Merge branch 'master' of https://gitlab.navinfo.com/CollectVehicle/OneMapQS
This commit is contained in:
@@ -184,8 +184,39 @@ class MainActivity : BaseActivity() {
|
||||
}
|
||||
//捕捉列表变化回调
|
||||
viewModel.liveDataQsRecordIdList.observe(this) {
|
||||
//处理页面跳转
|
||||
viewModel.navigationRightFragment(this, it)
|
||||
//跳转到质检数据页面
|
||||
//获取右侧fragment容器
|
||||
val naviController = findNavController(R.id.main_activity_right_fragment)
|
||||
|
||||
naviController.currentDestination?.let { navDestination ->
|
||||
when (navDestination.id) {
|
||||
R.id.RightEmptyFragment -> {
|
||||
if (it.size == 1) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString("QsId", it[0])
|
||||
naviController.navigate(R.id.EvaluationResultFragment, bundle)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//捕捉列表变化回调
|
||||
viewModel.liveDataNoteIdList.observe(this) {
|
||||
//跳转到质检数据页面
|
||||
//获取右侧fragment容器
|
||||
val naviController = findNavController(R.id.main_activity_right_fragment)
|
||||
|
||||
naviController.currentDestination?.let { navDestination ->
|
||||
when (navDestination.id) {
|
||||
R.id.RightEmptyFragment -> {
|
||||
if (it.size == 1) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString("NoteId", it[0])
|
||||
naviController.navigate(R.id.NoteFragment, bundle)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//右上角菜单是否被点击
|
||||
viewModel.liveDataMenuState.observe(this) {
|
||||
@@ -253,7 +284,7 @@ class MainActivity : BaseActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.liveDataSignMoreInfo.observe(this){
|
||||
viewModel.liveDataSignMoreInfo.observe(this) {
|
||||
val fragment =
|
||||
supportFragmentManager.findFragmentById(R.id.main_activity_sign_more_info_fragment)
|
||||
if (fragment == null) {
|
||||
@@ -432,10 +463,17 @@ class MainActivity : BaseActivity() {
|
||||
/**
|
||||
* 隐藏或显示右侧展开按钮
|
||||
*/
|
||||
fun setRightSwitchButton(visibility: Int) {
|
||||
fun setRightSwitchButtonVisibility(visibility: Int) {
|
||||
binding.mainActivityFragmentSwitch.visibility = visibility
|
||||
}
|
||||
|
||||
/**
|
||||
* 顶部菜单按钮
|
||||
*/
|
||||
fun setTopMenuButtonVisibility(visibility: Int) {
|
||||
binding.mainActivityMenu.visibility = visibility
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击录音按钮
|
||||
*/
|
||||
@@ -557,4 +595,20 @@ class MainActivity : BaseActivity() {
|
||||
viewModel.showSignMoreInfo(viewModel.liveDataRoadName.value!!)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增便签,打开便签fragment
|
||||
*/
|
||||
fun onClickNewNote() {
|
||||
rightController.navigate(R.id.NoteFragment)
|
||||
binding.mainActivityMenu.isSelected = false
|
||||
binding.mainActivityMenuGroup.visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
/**
|
||||
* 右侧按钮+经纬度按钮
|
||||
*/
|
||||
fun setRightButtonsVisible(visible: Int) {
|
||||
binding.mainActivityRightVisibilityButtonsGroup2.visibility = visible
|
||||
}
|
||||
}
|
||||
@@ -71,6 +71,9 @@ class MainViewModel @Inject constructor(
|
||||
//地图点击捕捉到的质检数据ID列表
|
||||
val liveDataQsRecordIdList = MutableLiveData<List<String>>()
|
||||
|
||||
//地图点击捕捉到的标签ID列表
|
||||
val liveDataNoteIdList = MutableLiveData<List<String>>()
|
||||
|
||||
//左侧看板数据
|
||||
val liveDataSignList = MutableLiveData<List<SignBean>>()
|
||||
|
||||
@@ -128,6 +131,10 @@ class MainViewModel @Inject constructor(
|
||||
override fun onQsRecordList(list: MutableList<String>) {
|
||||
liveDataQsRecordIdList.value = list
|
||||
}
|
||||
|
||||
override fun onNoteList(list: MutableList<String>) {
|
||||
liveDataNoteIdList.value = list
|
||||
}
|
||||
})
|
||||
initLocation()
|
||||
//处理地图点击操作
|
||||
@@ -295,7 +302,8 @@ class MainViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
liveDataTopSignList.postValue(topSignList.distinctBy { it.name }.sortedBy { it.index })
|
||||
liveDataTopSignList.postValue(topSignList.distinctBy { it.name }
|
||||
.sortedBy { it.index })
|
||||
|
||||
liveDataSignList.postValue(signList.sortedBy { it.distance })
|
||||
val speechText = SignUtil.getRoadSpeechText(topSignList)
|
||||
@@ -470,25 +478,6 @@ class MainViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理页面调转
|
||||
*/
|
||||
fun navigationRightFragment(activity: MainActivity, list: List<String>) {
|
||||
//获取右侧fragment容器
|
||||
val naviController = activity.findNavController(R.id.main_activity_right_fragment)
|
||||
|
||||
naviController.currentDestination?.let { navDestination ->
|
||||
when (navDestination.id) {
|
||||
R.id.RightEmptyFragment -> {
|
||||
if (list.size == 1) {
|
||||
val bundle = Bundle()
|
||||
bundle.putString("QsId", list[0])
|
||||
naviController.navigate(R.id.EvaluationResultFragment, bundle)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启线选择
|
||||
|
||||
@@ -32,18 +32,27 @@ class EmptyFragment : Fragment() {
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
val currentDestination = findNavController().currentDestination
|
||||
//有右侧面板的时候
|
||||
if (currentDestination?.label == "右侧空页面") {
|
||||
currentDestinationLabel = "右侧空页面"
|
||||
(activity as MainActivity).setRightSwitchButton(View.GONE)
|
||||
currentDestination?.let {
|
||||
//有右侧面板的时候
|
||||
currentDestinationLabel = it.label.toString()
|
||||
if (it.label == "右侧空页面") {
|
||||
(activity as MainActivity).setRightSwitchButtonVisibility(View.GONE)
|
||||
(activity as MainActivity).setTopMenuButtonVisibility(View.VISIBLE)
|
||||
} else if (it.label == "中间空页面") {
|
||||
(activity as MainActivity).setRightButtonsVisible(View.VISIBLE)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
//没有有右侧面板的时候
|
||||
if (currentDestinationLabel == "右侧空页面") {
|
||||
(activity as MainActivity).setRightSwitchButton(View.VISIBLE)
|
||||
(activity as MainActivity).setRightSwitchButtonVisibility(View.VISIBLE)
|
||||
(activity as MainActivity).setTopMenuButtonVisibility(View.GONE)
|
||||
} else if (currentDestinationLabel == "中间空页面") {
|
||||
(activity as MainActivity).setRightButtonsVisible(View.GONE)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.*
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.findNavController
|
||||
@@ -21,12 +25,12 @@ import com.navinfo.omqs.ui.dialog.FirstDialog
|
||||
import com.navinfo.omqs.ui.fragment.BaseFragment
|
||||
import com.navinfo.omqs.ui.other.shareViewModels
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.videolan.vlc.Util
|
||||
|
||||
|
||||
@AndroidEntryPoint
|
||||
class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
|
||||
private lateinit var binding: FragmentEvaluationResultBinding
|
||||
private var mCameraLauncher: ActivityResultLauncher<Intent>? = null
|
||||
|
||||
/**
|
||||
* 和[PhenomenonFragment],[ProblemLinkFragment],[EvaluationResultFragment]共用同一个viewModel
|
||||
@@ -37,6 +41,23 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
|
||||
PictureAdapter()
|
||||
}
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
mCameraLauncher = registerForActivityResult<Intent, ActivityResult>(
|
||||
ActivityResultContracts.StartActivityForResult()
|
||||
) { result: ActivityResult ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
// 处理相机返回的结果
|
||||
val extras = result.data!!.extras
|
||||
val imageBitmap: Bitmap? = extras!!["data"] as Bitmap?
|
||||
// 在这里处理图片数据
|
||||
if (imageBitmap != null)
|
||||
viewModel.savePhoto(imageBitmap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private val args:EmptyFragmentArgs by navArgs()
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
@@ -62,7 +83,7 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
|
||||
adapter.refreshData(it)
|
||||
}
|
||||
|
||||
binding.evaluationPictureViewpager
|
||||
|
||||
|
||||
return binding.root
|
||||
}
|
||||
@@ -106,15 +127,26 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
|
||||
val list = mutableListOf("1", "2", "3")
|
||||
pictureAdapter.refreshData(list)
|
||||
|
||||
//照片左右选择键点击监听
|
||||
binding.evaluationPictureLeft.setOnClickListener(this)
|
||||
binding.evaluationPictureRight.setOnClickListener(this)
|
||||
binding.evaluationCamera.setOnClickListener(this)
|
||||
//设置照片偏移量
|
||||
val viewPager = binding.evaluationPictureViewpager
|
||||
val vto = viewPager.viewTreeObserver
|
||||
vto.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
|
||||
override fun onGlobalLayout() {
|
||||
val width = viewPager.width
|
||||
// 处理View宽度
|
||||
// 在回调完成后,需要将监听器从View树中移除,以避免重复调用
|
||||
viewPager.viewTreeObserver.removeOnGlobalLayoutListener(this)
|
||||
|
||||
val recyclerView = viewPager.getChildAt(0) as RecyclerView
|
||||
|
||||
val recyclerView = binding.evaluationPictureViewpager.getChildAt(0) as RecyclerView
|
||||
|
||||
recyclerView.setPadding(0, 0, Util.convertDpToPx(requireContext(), 50), 0)
|
||||
recyclerView.clipToPadding = false
|
||||
|
||||
recyclerView.setPadding(0, 0, width / 2 - 30, 0)
|
||||
recyclerView.clipToPadding = false
|
||||
}
|
||||
})
|
||||
|
||||
binding.evaluationVoice.setOnTouchListener { _, event ->
|
||||
Log.e("qj", event?.action.toString())
|
||||
@@ -123,11 +155,7 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
|
||||
voiceOnTouchStart()//Do Something
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_UP -> {
|
||||
voiceOnTouchStop()//Do Something
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_CANCEL -> {
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL, MotionEvent.ACTION_OUTSIDE -> {
|
||||
voiceOnTouchStop()//Do Something
|
||||
}
|
||||
}
|
||||
@@ -338,7 +366,9 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
R.id.evaluation_camera -> {
|
||||
takePhoto()
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@@ -362,4 +392,16 @@ class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
|
||||
return true
|
||||
}
|
||||
|
||||
private fun takePhoto() {
|
||||
try {
|
||||
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
|
||||
if (takePictureIntent.resolveActivity(requireActivity().packageManager) != null) {
|
||||
mCameraLauncher!!.launch(takePictureIntent)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d("TTTT", e.toString())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
import android.app.Activity
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.AnimationDrawable
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.os.Build
|
||||
@@ -35,17 +36,13 @@ import com.navinfo.omqs.util.DateTimeUtil
|
||||
import com.navinfo.omqs.util.SoundMeter
|
||||
import com.navinfo.omqs.util.SpeakMode
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import io.realm.OrderedCollectionChangeSet
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmList
|
||||
import io.realm.RealmModel
|
||||
import io.realm.RealmResults
|
||||
import io.realm.kotlin.addChangeListener
|
||||
import io.realm.kotlin.where
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.oscim.core.GeoPoint
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -78,9 +75,20 @@ class EvaluationResultViewModel @Inject constructor(
|
||||
*/
|
||||
val liveDataRightTypeList = MutableLiveData<List<RightBean>>()
|
||||
|
||||
var liveDataQsRecordBean = MutableLiveData<QsRecordBean>()
|
||||
/**
|
||||
*
|
||||
*/
|
||||
val liveDataQsRecordBean = MutableLiveData<QsRecordBean>()
|
||||
|
||||
var listDataChatMsgEntityList = MutableLiveData<MutableList<ChatMsgEntity>>()
|
||||
/**
|
||||
* 语音列表
|
||||
*/
|
||||
val listDataChatMsgEntityList = MutableLiveData<MutableList<ChatMsgEntity>>()
|
||||
|
||||
/**
|
||||
* 照片列表
|
||||
*/
|
||||
val liveDataPictureList = MutableLiveData<MutableList<String>>()
|
||||
|
||||
var oldBean: QsRecordBean? = null
|
||||
|
||||
@@ -201,7 +209,8 @@ class EvaluationResultViewModel @Inject constructor(
|
||||
var classCode = list[0].elementCode
|
||||
liveDataLeftTypeList.postValue(it)
|
||||
if (bean != null) {
|
||||
val classType2 = roomAppDatabase.getScProblemTypeDao().findClassTypeByCode(bean.renderEntity.code)
|
||||
val classType2 = roomAppDatabase.getScProblemTypeDao()
|
||||
.findClassTypeByCode(bean.renderEntity.code)
|
||||
if (classType2 != null) {
|
||||
classType = classType2
|
||||
}
|
||||
@@ -364,13 +373,19 @@ class EvaluationResultViewModel @Inject constructor(
|
||||
Realm.getDefaultInstance().use { realm ->
|
||||
realm.executeTransactionAsync { bgRealm ->
|
||||
// find the item
|
||||
val objects = bgRealm.where(QsRecordBean::class.java).equalTo("id", id).findFirst()
|
||||
val objects =
|
||||
bgRealm.where(QsRecordBean::class.java).equalTo("id", id).findFirst()
|
||||
if (objects != null) {
|
||||
oldBean = bgRealm.copyFromRealm(objects)
|
||||
oldBean?.let {
|
||||
liveDataQsRecordBean.postValue(it.copy())
|
||||
val p = GeometryTools.createGeoPoint(it.geometry)
|
||||
mapController.markerHandle.addMarker(GeoPoint(p.latitude, p.longitude), markerTitle)
|
||||
mapController.markerHandle.addMarker(
|
||||
GeoPoint(
|
||||
p.latitude,
|
||||
p.longitude
|
||||
), markerTitle
|
||||
)
|
||||
|
||||
//获取linkid
|
||||
if (it.linkId.isNotEmpty()) {
|
||||
@@ -381,7 +396,8 @@ class EvaluationResultViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
liveDataQsRecordBean.value?.attachmentBeanList = it.attachmentBeanList
|
||||
liveDataQsRecordBean.value?.attachmentBeanList =
|
||||
it.attachmentBeanList
|
||||
// 显示语音数据到界面
|
||||
getChatMsgEntityList()
|
||||
}
|
||||
@@ -508,9 +524,42 @@ class EvaluationResultViewModel @Inject constructor(
|
||||
fun stopSoundMeter() {
|
||||
//先重置标识,防止按钮抬起时触发语音结束
|
||||
Constant.IS_VIDEO_SPEED = false
|
||||
if (mSoundMeter != null && mSoundMeter!!.isStartSound()) {
|
||||
if (mSoundMeter != null && mSoundMeter!!.isStartSound) {
|
||||
mSoundMeter!!.stop()
|
||||
}
|
||||
if (pop != null && pop!!.isShowing) pop!!.dismiss()
|
||||
pop?.let {
|
||||
if (it.isShowing) {
|
||||
it.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun savePhoto(bitmap: Bitmap) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
// 创建一个名为 "MyApp" 的文件夹
|
||||
val myAppDir = File(Constant.USER_DATA_ATTACHEMNT_PATH)
|
||||
if (!myAppDir.exists())
|
||||
myAppDir.mkdirs() // 确保文件夹已创建
|
||||
|
||||
// 创建一个名为 fileName 的文件
|
||||
val file = File(myAppDir, "${UUID.randomUUID()}.png")
|
||||
file.createNewFile() // 创建文件
|
||||
|
||||
// 将 Bitmap 压缩为 JPEG 格式,并将其写入文件中
|
||||
val out = FileOutputStream(file)
|
||||
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)
|
||||
out.flush()
|
||||
out.close()
|
||||
var picList = mutableListOf<String>()
|
||||
if (liveDataPictureList.value == null) {
|
||||
picList.add(file.absolutePath)
|
||||
} else {
|
||||
picList.addAll(liveDataPictureList.value!!)
|
||||
picList.add(file.absolutePath)
|
||||
}
|
||||
liveDataPictureList.postValue(picList)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package com.navinfo.omqs.ui.fragment.note
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.FragmentCanvasBinding
|
||||
import com.navinfo.omqs.databinding.FragmentNoteBinding
|
||||
import com.navinfo.omqs.databinding.FragmentProblemLinkBinding
|
||||
import com.navinfo.omqs.ui.fragment.BaseFragment
|
||||
import com.navinfo.omqs.ui.fragment.note.CanvasView.CanvasStyle
|
||||
import com.navinfo.omqs.ui.fragment.note.CanvasView.OnCanvasChangeListener
|
||||
import com.navinfo.omqs.ui.other.shareViewModels
|
||||
|
||||
/**
|
||||
* @author zhjch
|
||||
* @version V1.0
|
||||
* @ClassName: CanvasFragment
|
||||
* @Date 2016/5/10
|
||||
* @Description: ${TODO}(绘制画布)
|
||||
*/
|
||||
class CanvasFragment : BaseFragment() {
|
||||
/**
|
||||
* 获取画布
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/**
|
||||
* 画布
|
||||
*/
|
||||
private val canvasView by lazy { binding.canvasView }
|
||||
|
||||
/**
|
||||
* 画笔线型
|
||||
*/
|
||||
private var mStyle = CanvasStyle.FREE_LINE
|
||||
|
||||
/**
|
||||
* 画笔颜色
|
||||
*/
|
||||
private var mColor = -1
|
||||
|
||||
/**
|
||||
* 画笔粗细
|
||||
*/
|
||||
private var width = 5
|
||||
|
||||
|
||||
/**
|
||||
* 画布回调接口
|
||||
*/
|
||||
private var listener: OnCanvasChangeListener? = null
|
||||
|
||||
|
||||
private var _binding: FragmentCanvasBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val viewModel by shareViewModels<NoteViewModel>("note")
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentCanvasBinding.inflate(inflater, container, false)
|
||||
viewModel.initCanvasView(canvasView)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
canvasView.setStyle(mStyle)
|
||||
if (mColor == -1) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
mColor = resources.getColor(R.color.black, null)
|
||||
}
|
||||
}
|
||||
canvasView.setPaintColor(mColor)
|
||||
canvasView.setPaintWidth(width)
|
||||
if (listener != null) {
|
||||
canvasView.setOnCanvasChangeListener(listener)
|
||||
}
|
||||
|
||||
// * 开关橡皮擦
|
||||
// */
|
||||
// viewModel.liveEraserData.observe(viewLifecycleOwner) {
|
||||
// canvasView.setEraser(it)
|
||||
// }
|
||||
// /**
|
||||
// * 清除
|
||||
// */
|
||||
// viewModel.liveClearData.observe(viewLifecycleOwner) {
|
||||
// canvasView.removeAllPaint()
|
||||
// }
|
||||
// /**
|
||||
// * 回退上一笔
|
||||
// */
|
||||
// viewModel.liveBackData.observe(viewLifecycleOwner) {
|
||||
// canvasView.back()
|
||||
// }
|
||||
// /**
|
||||
// * 撤销回退
|
||||
// */
|
||||
// viewModel.liveForward.observe(viewLifecycleOwner) {
|
||||
// canvasView.forward()
|
||||
// }
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将数据转化并绘制在画板上
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
fun setDrawPathList(value: MutableList<CanvasView.DrawPath>) {
|
||||
if (value != null && value.isNotEmpty()) {
|
||||
canvasView.setDrawPathList(value)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置草图画笔线型
|
||||
*/
|
||||
fun setStyle(style: CanvasStyle) {
|
||||
mStyle = style
|
||||
canvasView.setStyle(style)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置画笔颜色
|
||||
*/
|
||||
fun setPaintColor(color: Int) {
|
||||
mColor = color
|
||||
canvasView.setPaintColor(mColor)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置画笔粗细
|
||||
*/
|
||||
fun setPaintWidth(width: Int) {
|
||||
this.width = width
|
||||
canvasView.setPaintWidth(width)
|
||||
}
|
||||
}
|
||||
1801
app/src/main/java/com/navinfo/omqs/ui/fragment/note/CanvasView.kt
Normal file
1801
app/src/main/java/com/navinfo/omqs/ui/fragment/note/CanvasView.kt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,424 @@
|
||||
package com.navinfo.omqs.ui.fragment.note
|
||||
|
||||
import android.graphics.Path
|
||||
import android.graphics.Point
|
||||
import android.graphics.Rect
|
||||
import android.graphics.RectF
|
||||
import android.text.TextUtils
|
||||
import com.navinfo.collect.library.data.entity.NoteBean
|
||||
import com.navinfo.collect.library.data.entity.SketchAttachContent
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.collect.library.utils.GeometryTools
|
||||
import com.navinfo.omqs.ui.fragment.note.CanvasView.CanvasStyle
|
||||
import io.realm.RealmList
|
||||
import org.locationtech.jts.geom.Coordinate
|
||||
import org.oscim.backend.canvas.Color
|
||||
import org.oscim.core.GeoPoint
|
||||
import java.util.UUID
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
/**
|
||||
* @author zhjch
|
||||
* @version V1.0
|
||||
* @ClassName: CanvasViewHelper
|
||||
* @Date 2016/5/16
|
||||
* @Description: ${TODO}(用一句话描述该文件做什么)
|
||||
*/
|
||||
object CanvasViewHelper {
|
||||
private const val mD2I = 3600000
|
||||
fun createNoteBean(
|
||||
controller: NIMapController,
|
||||
mCurrentPaths: List<CanvasView.DrawPath>,
|
||||
): NoteBean {
|
||||
val noteBean = NoteBean(UUID.randomUUID().toString())
|
||||
if (mCurrentPaths.isNotEmpty()) {
|
||||
val list: RealmList<SketchAttachContent> = RealmList<SketchAttachContent>()
|
||||
noteBean.list = list
|
||||
for (index in mCurrentPaths.indices) {
|
||||
val dp: CanvasView.DrawPath = mCurrentPaths[index]
|
||||
val geo = SketchAttachContent(UUID.randomUUID().toString())
|
||||
val pointList = dp.pointList ?: continue
|
||||
if (dp.style === CanvasStyle.GREENLAND_LINE || dp.style === CanvasStyle.WATER_LINE || dp.style === CanvasStyle.PARKING_LINE) {
|
||||
val geoPointList = mutableListOf<GeoPoint>()
|
||||
for (i in pointList.indices) {
|
||||
val point = pointList[i]
|
||||
val geoPoint: GeoPoint = controller.viewportHandler.fromScreenPoint(
|
||||
point
|
||||
)
|
||||
geoPointList.add(geoPoint)
|
||||
if (index == 0 && i == 0) {
|
||||
noteBean.guideGeometry =
|
||||
GeometryTools.createGeometry(geoPoint).toText()
|
||||
}
|
||||
}
|
||||
geo.style = createLineStyle(dp.style, dp.width, dp.color)
|
||||
geo.geometry = GeometryTools.createPolygon(geoPointList).toText()
|
||||
} else if (dp.style === CanvasStyle.CIRCULAR_POINT) {
|
||||
val point = pointList[0]
|
||||
val geoPoint: GeoPoint = controller.viewportHandler.fromScreenPoint(point)
|
||||
geo.style = createLineStyle(dp.style, dp.width, dp.color)
|
||||
geo.geometry = GeometryTools.createGeometry(geoPoint).toText()
|
||||
noteBean.guideGeometry = geo.geometry
|
||||
} else if (dp.style === CanvasStyle.ELLIPSE_LINE) {
|
||||
dp.rect?.let {
|
||||
val pointLT = Point(it.left, it.top)
|
||||
val pointRB = Point(it.right, it.bottom)
|
||||
val geoPointLT: GeoPoint =
|
||||
controller.viewportHandler.fromScreenPoint(pointLT)
|
||||
val geoPointRB: GeoPoint =
|
||||
controller.viewportHandler.fromScreenPoint(pointRB)
|
||||
val minX: Double
|
||||
val maxX: Double
|
||||
val minY: Double
|
||||
val maxY: Double
|
||||
if (geoPointLT.longitude < geoPointRB.longitude) {
|
||||
minX = (geoPointLT.longitude * mD2I)
|
||||
maxX = (geoPointRB.longitude * mD2I)
|
||||
} else {
|
||||
minX = (geoPointRB.longitude * mD2I)
|
||||
maxX = (geoPointLT.longitude * mD2I)
|
||||
}
|
||||
if (geoPointLT.latitude < geoPointRB.latitude) {
|
||||
minY = (geoPointLT.latitude * mD2I)
|
||||
maxY = (geoPointRB.latitude * mD2I)
|
||||
} else {
|
||||
minY = (geoPointRB.latitude * mD2I)
|
||||
maxY = (geoPointLT.latitude * mD2I)
|
||||
}
|
||||
val xR = (maxX - minX) / 2
|
||||
val yR = (maxY - minY) / 2
|
||||
var a = 0.0
|
||||
var tempX = xR * cos(a) + xR + minX
|
||||
val tempY = yR * sin(a) + yR + minY
|
||||
val firstX = tempX
|
||||
val geoPointList = mutableListOf<GeoPoint>()
|
||||
geoPointList.add(GeoPoint(tempX / mD2I, tempY / mD2I))
|
||||
var bLeft = false
|
||||
var bRight = false
|
||||
var zeng = 0.1
|
||||
if (controller.mMapView.mapLevel >= 20) {
|
||||
zeng = 0.2
|
||||
}
|
||||
while (!bLeft || !bRight) {
|
||||
a += zeng
|
||||
val x1 = (xR * cos(a) + xR + minX).toInt().toDouble()
|
||||
val y1 = (yR * sin(a) + yR + minY).toInt().toDouble()
|
||||
if (!bLeft && x1 > tempX) {
|
||||
bLeft = true
|
||||
}
|
||||
if (!bRight && bLeft && x1 <= tempX) {
|
||||
bRight = true
|
||||
geoPointList.add(
|
||||
GeoPoint(
|
||||
firstX / mD2I,
|
||||
tempY / mD2I
|
||||
)
|
||||
)
|
||||
} else {
|
||||
tempX = x1
|
||||
geoPointList.add(GeoPoint(x1 / mD2I, y1 / mD2I))
|
||||
}
|
||||
}
|
||||
if (index == 0) {
|
||||
noteBean.guideGeometry =
|
||||
GeometryTools.createGeometry(geoPointList[0]).toText()
|
||||
}
|
||||
geo.style = createLineStyle(dp.style, dp.width, dp.color)
|
||||
geo.geometry = GeometryTools.createLineString(geoPointList).toText()
|
||||
}
|
||||
} else {
|
||||
val geoPointList = mutableListOf<GeoPoint>()
|
||||
for (i in pointList.indices) {
|
||||
val point = pointList[i]
|
||||
val geoPoint: GeoPoint =
|
||||
controller.viewportHandler.fromScreenPoint(point)
|
||||
geoPointList.add(geoPoint)
|
||||
if (index == 0 && i == 0) {
|
||||
noteBean.guideGeometry =
|
||||
GeometryTools.createGeometry(geoPoint).toText()
|
||||
}
|
||||
}
|
||||
geo.style = createLineStyle(dp.style, dp.width, dp.color)
|
||||
geo.geometry = GeometryTools.createLineString(geoPointList).toText()
|
||||
}
|
||||
list.add(geo)
|
||||
}
|
||||
}
|
||||
return noteBean
|
||||
}
|
||||
|
||||
fun createDrawPaths(
|
||||
controller: NIMapController,
|
||||
att: NoteBean
|
||||
): MutableList<CanvasView.DrawPath> {
|
||||
val contents: List<SketchAttachContent> = att.list
|
||||
val drawPaths: MutableList<CanvasView.DrawPath> = mutableListOf()
|
||||
var width = 5
|
||||
var canvasStyle = CanvasStyle.FREE_LINE
|
||||
var color = Color.BLACK
|
||||
for (geo in contents) {
|
||||
var max_x = 0
|
||||
var max_y = 0
|
||||
var min_x = 0
|
||||
var min_y = 0
|
||||
val style = geo.style
|
||||
if (!TextUtils.isEmpty(style) && style.length > 3) {
|
||||
try {
|
||||
if (style.startsWith("4")) {
|
||||
canvasStyle = CanvasStyle.RAILWAY_LINE
|
||||
} else if (style.startsWith("5")) {
|
||||
if (style.contains("cde3ac")) {
|
||||
canvasStyle = CanvasStyle.GREENLAND_LINE
|
||||
} else if (style.contains("abcaff")) {
|
||||
canvasStyle = CanvasStyle.WATER_LINE
|
||||
} else if (style.contains("fffe98")) {
|
||||
canvasStyle = CanvasStyle.PARKING_LINE
|
||||
}
|
||||
} else {
|
||||
val s = style.substring(0, 1)
|
||||
if (TextUtils.equals(s, "2")) {
|
||||
canvasStyle = CanvasStyle.STRAIGHT_LINE
|
||||
} else if (TextUtils.equals(s, "3")) {
|
||||
canvasStyle = CanvasStyle.RECT_LINE
|
||||
} else if (TextUtils.equals(s, "6")) {
|
||||
canvasStyle = CanvasStyle.POLY_LINE
|
||||
} else if (TextUtils.equals(s, "7")) {
|
||||
canvasStyle = CanvasStyle.ELLIPSE_LINE
|
||||
} else if (TextUtils.equals(s, "9")) {
|
||||
canvasStyle = CanvasStyle.CIRCULAR_POINT
|
||||
} else if (TextUtils.equals(s, "1")) {
|
||||
canvasStyle = CanvasStyle.FREE_LINE
|
||||
}
|
||||
width = style.substring(1, 3).toInt()
|
||||
var colorStr = style.substring(3, style.length)
|
||||
if (colorStr.length == 6) {
|
||||
colorStr = "ff$colorStr"
|
||||
} else if (colorStr.length == 8) {
|
||||
} else {
|
||||
colorStr = "ff000000"
|
||||
}
|
||||
color = colorStr.toLong(16).toInt()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
val path = Path()
|
||||
val pointList: MutableList<Point> = ArrayList()
|
||||
if (canvasStyle === CanvasStyle.GREENLAND_LINE || canvasStyle === CanvasStyle.WATER_LINE || canvasStyle === CanvasStyle.PARKING_LINE) {
|
||||
// val polygonGeometry: PolygonGeometry = geo.geo as PolygonGeometry
|
||||
// if (polygonGeometry != null) {
|
||||
// val xyz: Array<Array<DoubleArray>> = polygonGeometry.getCoordinates()
|
||||
// if (xyz != null && xyz.isNotEmpty() && xyz[0].size > 1) {
|
||||
// var geoPoint: GeoPoint? = GeoPoint(xyz[0][0][0], xyz[0][0][1])
|
||||
// val movePoint: Point = .geoToScreen(geoPoint)
|
||||
// max_x = movePoint.x
|
||||
// max_y = movePoint.y
|
||||
// min_x = movePoint.x
|
||||
// min_y = movePoint.y
|
||||
// path.reset()
|
||||
// path.moveTo(movePoint.x.toFloat(), movePoint.y.toFloat())
|
||||
// pointList.add(Point(movePoint.x, movePoint.y))
|
||||
// for (i in 1 until xyz[0].size) {
|
||||
// val x_y = xyz[0][i]
|
||||
// if (x_y != null) {
|
||||
// geoPoint = GeoPoint(x_y[0], x_y[1])
|
||||
// val point: Point = projection.geoToScreen(geoPoint)
|
||||
// if (point.x > max_x) {
|
||||
// max_x = point.x
|
||||
// }
|
||||
// if (point.x < min_x) {
|
||||
// min_x = point.x
|
||||
// }
|
||||
// if (point.y > max_y) {
|
||||
// max_y = point.y
|
||||
// }
|
||||
// if (point.y < min_y) {
|
||||
// min_y = point.y
|
||||
// }
|
||||
// path.lineTo(point.x.toFloat(), point.y.toFloat())
|
||||
// pointList.add(point)
|
||||
// }
|
||||
// }
|
||||
// path.close()
|
||||
// }
|
||||
// }
|
||||
// val drawPath =
|
||||
// CanvasView.DrawPath(pointList[0], path, width, color, canvasStyle)
|
||||
// val rect = Rect(min_x, min_y, max_x, max_y)
|
||||
// drawPath.rect = rect
|
||||
// drawPath.pointList = pointList
|
||||
// drawPaths.add(drawPath)
|
||||
} else if (canvasStyle === CanvasStyle.CIRCULAR_POINT) {
|
||||
// val pointGeometry: PointGeometry = geo.geo as PointGeometry
|
||||
// if (pointGeometry != null && pointGeometry.getCoordinates() != null) {
|
||||
// val geoPoint: GeoPoint = GeoPoint(
|
||||
// pointGeometry.getCoordinates().get(0),
|
||||
// pointGeometry.getCoordinates().get(1)
|
||||
// )
|
||||
// val movePoint: Point = projection.geoToScreen(geoPoint)
|
||||
// pointList.add(movePoint)
|
||||
// val drawPath = DrawPath(movePoint, path, width, color, canvasStyle)
|
||||
// val rect = Rect(
|
||||
// movePoint.x - width - 20,
|
||||
// movePoint.y - width - 20,
|
||||
// movePoint.x + width + 20,
|
||||
// movePoint.y + width + 20
|
||||
// )
|
||||
// drawPath.rect = rect
|
||||
// drawPath.pointList = pointList
|
||||
// drawPaths.add(drawPath)
|
||||
// }
|
||||
} else if (canvasStyle === CanvasStyle.ELLIPSE_LINE) {
|
||||
// val lineGeometry = GeometryTools.createGeometry(geo.geometry)
|
||||
// if (lineGeometry != null) {
|
||||
// val xys: Array<out Coordinate> = lineGeometry.coordinates
|
||||
// if (xys != null && xys.size > 1) {
|
||||
// var geoPoint: GeoPoint? = GeoPoint(xys[0].y, xys[0].x)
|
||||
// val movePoint: Point = projection.geoToScreen(geoPoint)
|
||||
// max_x = movePoint.x
|
||||
// max_y = movePoint.y
|
||||
// min_x = movePoint.x
|
||||
// min_y = movePoint.y
|
||||
// path.reset()
|
||||
// path.moveTo(movePoint.x.toFloat(), movePoint.y.toFloat())
|
||||
// pointList.add(Point(movePoint.x, movePoint.y))
|
||||
// for (i in 1 until xys.size) {
|
||||
// val x_y = xys[i]
|
||||
// geoPoint = GeoPoint(x_y[0], x_y[1])
|
||||
// val point: Point = projection.geoToScreen(geoPoint)
|
||||
// if (point.x > max_x) {
|
||||
// max_x = point.x
|
||||
// }
|
||||
// if (point.x < min_x) {
|
||||
// min_x = point.x
|
||||
// }
|
||||
// if (point.y > max_y) {
|
||||
// max_y = point.y
|
||||
// }
|
||||
// if (point.y < min_y) {
|
||||
// min_y = point.y
|
||||
// }
|
||||
// pointList.add(point)
|
||||
// }
|
||||
// path.addOval(
|
||||
// RectF(
|
||||
// min_x.toFloat(),
|
||||
// min_y.toFloat(),
|
||||
// max_x.toFloat(),
|
||||
// max_y.toFloat()
|
||||
// ), Path.Direction.CW
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// val drawPath =
|
||||
// CanvasView.DrawPath(pointList[0], path, width, color, canvasStyle)
|
||||
// val rect = Rect(min_x, min_y, max_x, max_y)
|
||||
// drawPath.rect = rect
|
||||
// drawPath.pointList = pointList
|
||||
// drawPaths.add(drawPath)
|
||||
} else {
|
||||
val lineGeometry = GeometryTools.createGeometry(geo.geometry)
|
||||
if (lineGeometry != null) {
|
||||
val xys: Array<out Coordinate> = lineGeometry.coordinates
|
||||
if (xys.size > 1) {
|
||||
var geoPoint = GeoPoint(xys[0].y, xys[0].x)
|
||||
val movePoint: Point =
|
||||
controller.viewportHandler.toScreenPoint(geoPoint)
|
||||
max_x = movePoint.x
|
||||
max_y = movePoint.y
|
||||
min_x = movePoint.x
|
||||
min_y = movePoint.y
|
||||
path.reset()
|
||||
path.moveTo(movePoint.x.toFloat(), movePoint.y.toFloat())
|
||||
pointList.add(Point(movePoint.x, movePoint.y))
|
||||
for (i in 1 until xys.size) {
|
||||
val x_y = xys[i]
|
||||
geoPoint = GeoPoint(x_y.y, x_y.x)
|
||||
val point: Point =
|
||||
controller.viewportHandler.toScreenPoint(geoPoint)
|
||||
if (point.x > max_x) {
|
||||
max_x = point.x
|
||||
}
|
||||
if (point.x < min_x) {
|
||||
min_x = point.x
|
||||
}
|
||||
if (point.y > max_y) {
|
||||
max_y = point.y
|
||||
}
|
||||
if (point.y < min_y) {
|
||||
min_y = point.y
|
||||
}
|
||||
if (canvasStyle === CanvasStyle.FREE_LINE) {
|
||||
val dx = abs(point.x - movePoint.x).toFloat()
|
||||
val dy = abs(point.y - movePoint.y).toFloat()
|
||||
if (dx >= 4 || dy >= 4) {
|
||||
path.quadTo(
|
||||
movePoint.x.toFloat(),
|
||||
movePoint.y.toFloat(),
|
||||
((point.x + movePoint.x) / 2).toFloat(),
|
||||
((point.y + movePoint.y) / 2).toFloat()
|
||||
) //源代码是这样写的,可是我没有弄明白,为什么要这样?
|
||||
movePoint.x = point.x
|
||||
movePoint.y = point.y
|
||||
}
|
||||
} else {
|
||||
path.lineTo(point.x.toFloat(), point.y.toFloat())
|
||||
}
|
||||
pointList.add(point)
|
||||
}
|
||||
}
|
||||
}
|
||||
val drawPath =
|
||||
CanvasView.DrawPath(pointList[0], path, width, color, canvasStyle)
|
||||
val rect = Rect(min_x, min_y, max_x, max_y)
|
||||
drawPath.rect = rect
|
||||
drawPath.pointList = pointList
|
||||
drawPaths.add(drawPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
return drawPaths
|
||||
}
|
||||
|
||||
private fun createLineStyle(canvasStyle: CanvasStyle, width: Int, color: Int): String {
|
||||
val style = StringBuilder()
|
||||
if (canvasStyle === CanvasStyle.RAILWAY_LINE) {
|
||||
return "4060070c004ffffff16"
|
||||
} else if (canvasStyle === CanvasStyle.GREENLAND_LINE) {
|
||||
return "50200b050cde3ac"
|
||||
} else if (canvasStyle === CanvasStyle.WATER_LINE) {
|
||||
return "50200b050abcaff"
|
||||
} else if (canvasStyle === CanvasStyle.PARKING_LINE) {
|
||||
return "502a6a6a6fffe98"
|
||||
}
|
||||
if (canvasStyle === CanvasStyle.STRAIGHT_LINE) {
|
||||
style.append("2")
|
||||
} else if (canvasStyle === CanvasStyle.RECT_LINE) {
|
||||
style.append("3")
|
||||
} else if (canvasStyle === CanvasStyle.POLY_LINE) {
|
||||
style.append("6")
|
||||
} else if (canvasStyle === CanvasStyle.ELLIPSE_LINE) {
|
||||
style.append("7")
|
||||
} else if (canvasStyle === CanvasStyle.CIRCULAR_POINT) {
|
||||
style.append("9")
|
||||
} else {
|
||||
style.append("1")
|
||||
}
|
||||
if (width < 10) {
|
||||
style.append("0")
|
||||
}
|
||||
style.append(width.toString())
|
||||
try {
|
||||
var colorString = Integer.toHexString(color).toString()
|
||||
if (colorString.length == 8) {
|
||||
colorString = TextUtils.substring(colorString, 2, 8)
|
||||
}
|
||||
style.append(colorString)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return style.toString()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
package com.navinfo.omqs.ui.fragment.note
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.FragmentNoteBinding
|
||||
import com.navinfo.omqs.ui.dialog.FirstDialog
|
||||
import com.navinfo.omqs.ui.fragment.BaseFragment
|
||||
import com.navinfo.omqs.ui.other.shareViewModels
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class NoteFragment : BaseFragment(), View.OnClickListener {
|
||||
private var _binding: FragmentNoteBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val viewModel by shareViewModels<NoteViewModel>("note")
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentNoteBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
binding.sketchEraser.setOnClickListener(this)
|
||||
binding.sketchClear.setOnClickListener(this)
|
||||
binding.sketchForward.setOnClickListener(this)
|
||||
binding.sketchBack.setOnClickListener(this)
|
||||
binding.noteBarSave.setOnClickListener(this)
|
||||
binding.noteBarCancel.setOnClickListener(this)
|
||||
binding.noteBarDelete.setOnClickListener(this)
|
||||
binding.noteDescription.addTextChangedListener(object : TextWatcher {
|
||||
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
|
||||
}
|
||||
|
||||
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
|
||||
}
|
||||
|
||||
override fun afterTextChanged(s: Editable?) {
|
||||
viewModel.noteBeanDescription = s.toString()
|
||||
}
|
||||
})
|
||||
/**
|
||||
* 数据操作结束
|
||||
*/
|
||||
viewModel.liveDataFinish.observe(viewLifecycleOwner) {
|
||||
if (it)
|
||||
onBackPressed()
|
||||
}
|
||||
|
||||
/**
|
||||
* 画布初始化完成
|
||||
*/
|
||||
|
||||
viewModel.liveDataCanvasViewInitFinished.observe(viewLifecycleOwner) {
|
||||
if (it)
|
||||
arguments?.let { b ->
|
||||
val id = b.getString("NoteId", "")
|
||||
if (id.isNotEmpty()) {
|
||||
viewModel.initData(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
activity?.run {
|
||||
findNavController(
|
||||
R.id.main_activity_middle_fragment
|
||||
).navigate(R.id.CanvasFragment)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
activity?.run {
|
||||
findNavController(
|
||||
R.id.main_activity_middle_fragment
|
||||
).navigateUp()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
when (v) {
|
||||
binding.sketchEraser -> {
|
||||
viewModel.onEraser()
|
||||
binding.sketchEraser.isSelected = viewModel.isEraser
|
||||
}
|
||||
binding.sketchBack -> {
|
||||
viewModel.onBack()
|
||||
}
|
||||
binding.sketchForward -> {
|
||||
viewModel.onForward()
|
||||
}
|
||||
binding.sketchClear -> {
|
||||
viewModel.onClear()
|
||||
}
|
||||
binding.noteBarSave -> {
|
||||
viewModel.onSaveData()
|
||||
}
|
||||
binding.noteBarDelete -> {
|
||||
viewModel.deleteData(requireContext())
|
||||
}
|
||||
binding.noteBarCancel -> {
|
||||
//返回按钮点击
|
||||
val mDialog = FirstDialog(context)
|
||||
mDialog.setTitle("提示?")
|
||||
mDialog.setMessage("是否退出,请确认!")
|
||||
mDialog.setPositiveButton(
|
||||
"确定"
|
||||
) { _, _ ->
|
||||
mDialog.dismiss()
|
||||
onBackPressed()
|
||||
}
|
||||
mDialog.setNegativeButton("取消", null)
|
||||
mDialog.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBackPressed(): Boolean {
|
||||
findNavController().navigateUp()
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
package com.navinfo.omqs.ui.fragment.note
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.navinfo.collect.library.data.entity.NoteBean
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.omqs.ui.dialog.FirstDialog
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import io.realm.Realm
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class NoteViewModel @Inject constructor(
|
||||
val mapController: NIMapController
|
||||
) : ViewModel() {
|
||||
|
||||
lateinit var canvasView: CanvasView
|
||||
|
||||
|
||||
var mNoteBean: NoteBean? = null
|
||||
|
||||
|
||||
var isEraser = false
|
||||
|
||||
var noteBeanDescription = ""
|
||||
// /**
|
||||
// * 橡皮擦开关
|
||||
// */
|
||||
// val liveEraserData = MutableLiveData(false)
|
||||
//
|
||||
// /**
|
||||
// * 清除按钮
|
||||
// */
|
||||
// val liveClearData = MutableLiveData(false)
|
||||
//
|
||||
// /**
|
||||
// * 回退按钮
|
||||
// */
|
||||
// val liveBackData = MutableLiveData(false)
|
||||
//
|
||||
// /**
|
||||
// * 撤销按钮
|
||||
// */
|
||||
// val liveForward = MutableLiveData(false)
|
||||
|
||||
/**
|
||||
* 处理结束关闭fragment
|
||||
*/
|
||||
val liveDataFinish = MutableLiveData(false)
|
||||
|
||||
/**
|
||||
* 通知页面画布初始化完成
|
||||
*/
|
||||
val liveDataCanvasViewInitFinished = MutableLiveData(false)
|
||||
|
||||
fun initCanvasView(canvasView: CanvasView) {
|
||||
this.canvasView = canvasView
|
||||
liveDataCanvasViewInitFinished.value = true
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通知橡皮擦开关
|
||||
*/
|
||||
fun onEraser() {
|
||||
isEraser = !isEraser
|
||||
canvasView.setEraser(isEraser)
|
||||
// liveEraserData.value = !liveEraserData.value!!
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知清除
|
||||
*/
|
||||
fun onClear() {
|
||||
canvasView.removeAllPaint()
|
||||
// liveClearData.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知回退
|
||||
*/
|
||||
fun onBack() {
|
||||
canvasView.back()
|
||||
// liveBackData.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知撤销回退
|
||||
*/
|
||||
fun onForward() {
|
||||
canvasView.forward()
|
||||
// liveForward.value = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存数据
|
||||
*/
|
||||
fun onSaveData() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
if (canvasView.paths != null && canvasView.paths!!.isNotEmpty()) {
|
||||
var noteBean =
|
||||
CanvasViewHelper.createNoteBean(mapController, canvasView.paths!!)
|
||||
if (mNoteBean != null) {
|
||||
noteBean.id = mNoteBean!!.id
|
||||
noteBean.description = noteBeanDescription
|
||||
}
|
||||
mNoteBean = noteBean
|
||||
val realm = Realm.getDefaultInstance()
|
||||
realm.executeTransaction {
|
||||
it.copyToRealmOrUpdate(noteBean)
|
||||
}
|
||||
mapController.markerHandle.addOrUpdateNoteMark(mNoteBean!!)
|
||||
liveDataFinish.postValue(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除数据
|
||||
*/
|
||||
fun deleteData(context: Context) {
|
||||
if (mNoteBean == null) {
|
||||
liveDataFinish.postValue(true)
|
||||
return
|
||||
} else {
|
||||
val mDialog = FirstDialog(context)
|
||||
mDialog.setTitle("提示?")
|
||||
mDialog.setMessage("是否删除标签,请确认!")
|
||||
mDialog.setPositiveButton(
|
||||
"确定"
|
||||
) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val realm = Realm.getDefaultInstance()
|
||||
realm.executeTransaction {
|
||||
val objects = it.where(NoteBean::class.java)
|
||||
.equalTo("id", mNoteBean!!.id).findFirst()
|
||||
objects?.deleteFromRealm()
|
||||
}
|
||||
mapController.markerHandle.removeNoteMark(mNoteBean!!)
|
||||
liveDataFinish.postValue(true)
|
||||
}
|
||||
}
|
||||
mDialog.setNegativeButton("取消", null)
|
||||
mDialog.show()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
fun initData(id: String) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val realm = Realm.getDefaultInstance()
|
||||
realm.executeTransaction { it ->
|
||||
val objects = it.where(NoteBean::class.java)
|
||||
.equalTo("id", id).findFirst()
|
||||
mNoteBean = realm.copyFromRealm(objects)
|
||||
mNoteBean?.let { bean ->
|
||||
noteBeanDescription = bean.description
|
||||
val list = CanvasViewHelper.createDrawPaths(mapController, bean)
|
||||
canvasView.setDrawPathList(list)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
app/src/main/res/drawable-xxhdpi/home_map_center.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/home_map_center.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/src/main/res/drawable-xxhdpi/sketch_back.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/sketch_back.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/drawable-xxhdpi/sketch_eraser.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/sketch_eraser.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
BIN
app/src/main/res/drawable-xxhdpi/sketch_forward.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/sketch_forward.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
16
app/src/main/res/drawable/selector_sketch_eraser_bg.xml
Normal file
16
app/src/main/res/drawable/selector_sketch_eraser_bg.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_selected="true">
|
||||
<shape>
|
||||
<padding android:bottom="2dp" android:left="@dimen/default_widget_padding" android:right="@dimen/default_widget_padding" android:top="2dp"></padding>
|
||||
<stroke android:width="1.1dp" android:color="#1ABBFE" />
|
||||
</shape>
|
||||
</item>
|
||||
<item>
|
||||
<shape>
|
||||
<padding android:bottom="@dimen/default_widget_padding" android:left="@dimen/default_widget_padding" android:right="@dimen/default_widget_padding" android:top="@dimen/default_widget_padding"></padding>
|
||||
<solid android:color="@color/transp" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</selector>
|
||||
@@ -4,7 +4,7 @@
|
||||
android:left="-300dp"
|
||||
android:right="-300dp">
|
||||
<rotate
|
||||
android:drawable="@drawable/laneinfo_1_2"
|
||||
android:drawable="@drawable/shape_dashed_line"
|
||||
android:fromDegrees="90" />
|
||||
</item>
|
||||
</layer-list>
|
||||
@@ -79,7 +79,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginRight="@dimen/top_right_drawer_btns_mr"
|
||||
app:constraint_referenced_ids="main_activity_serach,main_activity_2d_3d,main_activity_camera,main_activity_trace,main_activity_calc_disance,main_activity_menu"
|
||||
app:constraint_referenced_ids="main_activity_serach,main_activity_2d_3d,main_activity_camera,main_activity_trace,main_activity_calc_disance,main_activity_note,main_activity_menu"
|
||||
app:flow_horizontalGap="6dp"
|
||||
app:flow_wrapMode="aligned"
|
||||
app:layout_constraintRight_toLeftOf="@id/main_activity_right_fragment"
|
||||
@@ -90,7 +90,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible"
|
||||
app:constraint_referenced_ids="main_activity_serach,main_activity_2d_3d,main_activity_camera,main_activity_trace,main_activity_calc_disance" />
|
||||
app:constraint_referenced_ids="main_activity_serach,main_activity_2d_3d,main_activity_camera,main_activity_trace,main_activity_note,main_activity_calc_disance" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/main_activity_serach"
|
||||
@@ -122,6 +122,12 @@
|
||||
android:onClick="@{()->mainActivity.onClickCalcDisance()}"
|
||||
android:src="@drawable/icon_calc_disance" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/main_activity_note"
|
||||
style="@style/top_right_drawer_btns_style"
|
||||
android:onClick="@{()->mainActivity.onClickNewNote()}"
|
||||
android:src="@drawable/icon_calc_disance" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/main_activity_menu"
|
||||
android:layout_width="@dimen/top_right_drawer_wh"
|
||||
@@ -224,16 +230,6 @@
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/main_activity_sign_recyclerview" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/main_activity_right_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:elevation="3dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navGraph="@navigation/right_fragment_nav_graph" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/main_activity_geometry"
|
||||
@@ -250,7 +246,18 @@
|
||||
android:text="经纬度:116.99388424,38.8403844"
|
||||
android:textSize="10sp"
|
||||
app:layout_constraintBottom_toTopOf="@id/main_activity_bottom_sheet_bg"
|
||||
app:layout_constraintRight_toLeftOf="@id/main_activity_middle_fragment" />
|
||||
app:layout_constraintRight_toLeftOf="@id/main_activity_right_fragment" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/main_activity_right_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:elevation="4dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navGraph="@navigation/right_fragment_nav_graph" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/main_activity_road_name"
|
||||
@@ -336,16 +343,21 @@
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="main_activity_select_line,main_activity_voice,main_activity_add_new" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/main_activity_right_visibility_buttons_group2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:constraint_referenced_ids="main_activity_select_line,main_activity_voice,main_activity_add_new,main_activity_zoom_in,main_activity_zoom_out,main_activity_geometry,main_activity_location" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/main_activity_middle_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginRight="-1dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@id/main_activity_right_fragment"
|
||||
app:layout_constraintTop_toBottomOf="@id/main_activity_flow"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navGraph="@navigation/middle_fragment_nav_graph" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
|
||||
9
app/src/main/res/layout/fragment_canvas.xml
Normal file
9
app/src/main/res/layout/fragment_canvas.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.navinfo.omqs.ui.fragment.note.CanvasView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/canvas_view"
|
||||
android:elevation="4dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#94fcfbfb"
|
||||
android:clickable="true" />
|
||||
235
app/src/main/res/layout/fragment_note.xml
Normal file
235
app/src/main/res/layout/fragment_note.xml
Normal file
@@ -0,0 +1,235 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="@dimen/right_fragment_w"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/shape_right_fragment_bg"
|
||||
tools:context=".ui.fragment.note.NoteFragment">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/note_bar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:layout_marginTop="14dp"
|
||||
android:drawableLeft="@drawable/selector_btn_back_xml"
|
||||
android:text="Mark"
|
||||
android:textColor="@color/default_blue_text_color"
|
||||
android:textSize="16sp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/note_bar_save"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginTop="9dp"
|
||||
android:layout_marginRight="14dp"
|
||||
android:background="@drawable/ripple_fragment_save_botton_bg"
|
||||
android:src="@drawable/icon_save"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/note_bar_cancel"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:background="@color/transparent"
|
||||
android:src="@drawable/icon_fragment_close"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintRight_toLeftOf="@id/note_bar_save"
|
||||
app:layout_constraintTop_toTopOf="@id/note_bar_save" />
|
||||
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/note_bar_delete"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_marginRight="5dp"
|
||||
android:background="@color/transparent"
|
||||
android:src="@drawable/icon_delete"
|
||||
app:layout_constraintRight_toLeftOf="@id/note_bar_cancel"
|
||||
app:layout_constraintTop_toTopOf="@id/note_bar_save" />
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:paddingLeft="11dp"
|
||||
android:paddingTop="6dp"
|
||||
android:paddingRight="9dp"
|
||||
android:paddingBottom="6dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/note_camera"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/note_bar_save">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginBottom="7dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="5dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="橡皮擦 " />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/sketch_eraser"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/selector_sketch_eraser_bg"
|
||||
android:src="@drawable/sketch_eraser" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/sketch_back"
|
||||
style="@style/sketch_operation_style"
|
||||
android:src="@drawable/sketch_back" />
|
||||
|
||||
<View
|
||||
style="@style/link_gray_style"
|
||||
android:layout_margin="2dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/sketch_forward"
|
||||
style="@style/sketch_operation_style"
|
||||
android:src="@drawable/sketch_forward" />
|
||||
|
||||
<View
|
||||
style="@style/link_gray_style"
|
||||
android:layout_margin="2dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sketch_clear"
|
||||
style="@style/sketch_operation_style"
|
||||
android:text="重绘" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
style="@style/evaluation_fragment_title_text_style"
|
||||
android:layout_gravity="top"
|
||||
android:layout_marginTop="3dp"
|
||||
android:text="备注" />
|
||||
|
||||
<com.navinfo.omqs.ui.widget.MyEditeText
|
||||
android:id="@+id/note_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/shape_rect_white_2dp_bg"
|
||||
android:elevation="2dp"
|
||||
android:gravity="start"
|
||||
android:hint="请输入备注信息"
|
||||
android:inputType="textMultiLine"
|
||||
android:lines="3"
|
||||
android:maxLines="3"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingTop="2dp"
|
||||
android:paddingBottom="2dp"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="多媒体"
|
||||
android:textColor="@color/default_blue_text_color"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<!--
|
||||
这种效果也好实现,主要的关键点是 Android:clipChildren=”false” 这个属性。
|
||||
1.配置ViewPager 和其父布局的 android:clipChildren属性为”false”.
|
||||
(android:clipChildren表示是否限制子View在其范围内,默认为true. 代码设置setClipChildren(false))
|
||||
因为如果clipChildren属性设置为true,就表明我们要将children给clip掉,就是说对于子元素来说,超出当前view的部分都会被切掉,那我们在这里把它设置成false,就表明超出view的部分,不要切掉,依然显示。
|
||||
注意:setClipChildren(false)在3.0以上版本中,开启了硬件加速后将不能正常工作,所以需要将其设置为软件加速。设置软硬件加速使用 setLayerType(View.LAYER_TYPE_SOFTWARE, null); 也可以在布局文件中添加 android:layerType=”software”
|
||||
|
||||
-->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/note_picture_left"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:background="@drawable/icon_picture_left"
|
||||
android:padding="5dp" />
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/note_picture_viewpager"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="50dp"
|
||||
android:layout_weight="1"
|
||||
android:clipChildren="false" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/note_picture_right"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:background="@drawable/icon_picture_right"
|
||||
android:padding="5dp" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/note_voice_recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="120dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/note_camera"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:src="@drawable/baseline_camera_alt_24"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHorizontal_weight="1"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@id/note_voice" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/note_voice"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:src="@drawable/baseline_keyboard_voice_24"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHorizontal_weight="1"
|
||||
app:layout_constraintLeft_toRightOf="@id/note_camera"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -1,26 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="@dimen/fragment_phenomenon_width"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/shape_middle_fragment_bg"
|
||||
android:gravity="right"
|
||||
tools:context="com.navinfo.omqs.ui.fragment.evaluationresult.PhenomenonFragment">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/phenomenon_left_recyclerview"
|
||||
android:layout_width="148dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
<LinearLayout
|
||||
android:layout_width="@dimen/fragment_phenomenon_width"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="55dp"
|
||||
android:background="@drawable/shape_middle_fragment_bg"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/phenomenon_right_recyclerview"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toRightOf="@id/phenomenon_left_recyclerview"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/phenomenon_left_recyclerview"
|
||||
android:layout_width="148dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toLeftOf="@id/phenomenon_right_recyclerview" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/phenomenon_right_recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentRight="true" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
@@ -2,13 +2,15 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="@dimen/fragment_problem_link_width"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/shape_middle_fragment_bg"
|
||||
tools:context="com.navinfo.omqs.ui.fragment.evaluationresult.ProblemLinkFragment">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:layout_marginTop="55dp"
|
||||
android:id="@+id/link_right_recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
android:layout_width="@dimen/fragment_problem_link_width"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/shape_middle_fragment_bg"
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -20,4 +20,10 @@
|
||||
android:name="com.navinfo.omqs.ui.fragment.evaluationresult.ProblemLinkFragment"
|
||||
android:label="评测页面"
|
||||
tools:layout="@layout/fragment_problem_link"></fragment>
|
||||
<fragment
|
||||
android:id="@+id/CanvasFragment"
|
||||
android:name="com.navinfo.omqs.ui.fragment.note.CanvasFragment"
|
||||
android:label="绘图页面"
|
||||
tools:layout="@layout/fragment_canvas"></fragment>
|
||||
|
||||
</navigation>
|
||||
@@ -30,4 +30,11 @@
|
||||
tools:layout="@layout/fragment_evaluation_result">
|
||||
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/NoteFragment"
|
||||
android:name="com.navinfo.omqs.ui.fragment.note.NoteFragment"
|
||||
android:label="便签页面"
|
||||
tools:layout="@layout/fragment_note">
|
||||
|
||||
</fragment>
|
||||
</navigation>
|
||||
7
app/src/main/res/values/styleable.xml
Normal file
7
app/src/main/res/values/styleable.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<declare-styleable name="CanvasView">
|
||||
<attr name="isSavePoint" format="boolean" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
@@ -1,5 +1,20 @@
|
||||
<resources>
|
||||
|
||||
<style name="sketch_operation_style">
|
||||
<item name="android:layout_width">0dp</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:layout_weight">1</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:paddingTop">5dp</item>
|
||||
<item name="android:paddingBottom">5dp</item>
|
||||
</style>
|
||||
|
||||
<style name="link_gray_style" comment="竖着的灰色分隔线">
|
||||
<item name="android:layout_width">1dp</item>
|
||||
<item name="android:layout_height">match_parent</item>
|
||||
<item name="android:background">#C3C3C3</item>
|
||||
</style>
|
||||
|
||||
<style name="main_activity_bottom_sheet_icon" comment="主控页面下方按钮样式">
|
||||
<item name="android:layout_width">36dp</item>
|
||||
<item name="android:layout_height">36dp</item>
|
||||
|
||||
Reference in New Issue
Block a user