fix: 合并代码
This commit is contained in:
commit
7ea778780c
@ -45,12 +45,8 @@ android {
|
||||
dependencies {
|
||||
|
||||
implementation project(':collect-library')
|
||||
implementation 'androidx.core:core-ktx:1.9.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.8.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.5.3'
|
||||
|
||||
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
|
@ -2,6 +2,7 @@ package com.navinfo.omqs
|
||||
|
||||
import android.app.Application
|
||||
import android.util.Log
|
||||
import com.navinfo.omqs.db.MyRealmModule
|
||||
import com.navinfo.omqs.tools.FileManager
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import io.realm.Realm
|
||||
@ -24,6 +25,8 @@ class OMQSApplication : Application() {
|
||||
.directory(File(Constant.DATA_PATH))
|
||||
.name("OMQS.realm")
|
||||
.encryptionKey(password)
|
||||
.modules(Realm.getDefaultModule(), MyRealmModule())
|
||||
.schemaVersion(1)
|
||||
.build()
|
||||
Realm.setDefaultConfiguration(config)
|
||||
}
|
||||
|
@ -1,6 +0,0 @@
|
||||
package com.navinfo.omqs.bean
|
||||
|
||||
import java.io.Serializable
|
||||
|
||||
open class BaseBean : Serializable, Cloneable {
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
package com.navinfo.omqs.bean
|
||||
|
||||
import io.realm.RealmObject
|
||||
import io.realm.annotations.PrimaryKey
|
||||
|
||||
|
||||
/**
|
||||
* @author zhjch
|
||||
* @version V1.0
|
||||
* @ClassName: Rd_qcRecord
|
||||
* @Date 2016/1/12
|
||||
* @Description: ${TODO}(质检对象)
|
||||
*/
|
||||
open class QsRecord @JvmOverloads constructor(
|
||||
/**
|
||||
* id 主键
|
||||
*
|
||||
*/
|
||||
@PrimaryKey var id: String = "",
|
||||
/**
|
||||
* linkPid 绑定的道路ID
|
||||
*/
|
||||
var linkPid: String = "",
|
||||
/**
|
||||
*问题分类
|
||||
*/
|
||||
var classType: String = "",
|
||||
/**
|
||||
* 问题类型
|
||||
*/
|
||||
var type: String = "",
|
||||
|
||||
/**
|
||||
* 问题现象
|
||||
*/
|
||||
var phenomenon: String = "",
|
||||
/**
|
||||
* 问题描述
|
||||
*/
|
||||
var description: String = "",
|
||||
/**
|
||||
* 设置initial_cause
|
||||
* @param initial_cause
|
||||
* initial_cause
|
||||
*/
|
||||
// var initial_cause: String? = StringEntity.STRING_DEFAULT
|
||||
// /**
|
||||
// * 获取root_cause
|
||||
// * @return root_cause
|
||||
// */
|
||||
// /**
|
||||
// * 设置root_cause
|
||||
// * @param root_cause
|
||||
// * root_cause
|
||||
// */
|
||||
////根本原因(RCA)
|
||||
// var root_cause: String? = StringEntity.STRING_DEFAULT
|
||||
// /**
|
||||
// * 获取check_userid
|
||||
// * @return check_userid
|
||||
// */
|
||||
// /**
|
||||
// * 设置check_userid
|
||||
// * @param check_userid
|
||||
// * check_userid
|
||||
// */
|
||||
////质检员
|
||||
// var check_userid: String? = StringEntity.STRING_DEFAULT
|
||||
// /**
|
||||
// * 获取check_time
|
||||
// * @return check_time
|
||||
// */
|
||||
// /**
|
||||
// * 设置check_time
|
||||
// * @param check_time
|
||||
// * check_time
|
||||
// */
|
||||
////质检日期
|
||||
// var check_time: String? = StringEntity.STRING_DEFAULT
|
||||
// /**
|
||||
// * 获取confirm_userid
|
||||
// * @return confirm_userid
|
||||
// */
|
||||
// /**
|
||||
// * 设置confirm_userid
|
||||
// * @param confirm_userid
|
||||
// * confirm_userid
|
||||
// */
|
||||
////确认人
|
||||
// var confirm_userid: String? = StringEntity.STRING_DEFAULT
|
||||
// /**
|
||||
// * 获取t_lifecycle
|
||||
// * @return t_lifecycle
|
||||
// */
|
||||
// /**
|
||||
// * 设置t_lifecycle
|
||||
// * @param t_lifecycle
|
||||
// * t_lifecycle
|
||||
// */
|
||||
////状态 0 无; 1 删除;2 更新;3 新增;
|
||||
// var t_lifecycle = 0
|
||||
// /**
|
||||
// * 获取t_status
|
||||
// * @return t_status
|
||||
// */
|
||||
// /**
|
||||
// * 设置t_status
|
||||
// * @param t_status
|
||||
// * t_status
|
||||
// */
|
||||
////问题记录提交状态 0 未提交;1 已提交;
|
||||
// var t_status = 0
|
||||
) : RealmObject(
|
||||
|
||||
)
|
7
app/src/main/java/com/navinfo/omqs/db/MyRealmModule.kt
Normal file
7
app/src/main/java/com/navinfo/omqs/db/MyRealmModule.kt
Normal file
@ -0,0 +1,7 @@
|
||||
package com.navinfo.omqs.db
|
||||
|
||||
import com.navinfo.collect.library.data.entity.QsRecordBean
|
||||
|
||||
@io.realm.annotations.RealmModule(classes = [QsRecordBean::class])
|
||||
class MyRealmModule {
|
||||
}
|
@ -1,8 +1,6 @@
|
||||
package com.navinfo.omqs.db.dao
|
||||
|
||||
import androidx.room.*
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.navinfo.collect.library.data.dao.impl.MapLifeDataBase.getDatabase
|
||||
import com.navinfo.omqs.bean.ScProblemTypeBean
|
||||
|
||||
|
||||
@ -38,13 +36,13 @@ interface ScProblemTypeDao {
|
||||
/**
|
||||
* 获取问题类型,并去重
|
||||
*/
|
||||
@Query("select DISTINCT TYPE from ScProblemType where CLASS_TYPE=:type order by TYPE")
|
||||
suspend fun findProblemTypeList(type: String): List<String>
|
||||
@Query("select * from ScProblemType where CLASS_TYPE=:type order by TYPE")
|
||||
suspend fun findProblemTypeList(type: String): List<ScProblemTypeBean>?
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Query("select PHENOMENON from ScProblemType where CLASS_TYPE=:classType and TYPE=:type order by PHENOMENON")
|
||||
suspend fun getPhenomenonList(classType: String, type: String): List<String>
|
||||
// /**
|
||||
// *
|
||||
// */
|
||||
// @Query("select PHENOMENON from ScProblemType where CLASS_TYPE=:classType and TYPE=:type order by PHENOMENON")
|
||||
// suspend fun getPhenomenonList(classType: String, type: String): List<String>
|
||||
|
||||
}
|
@ -22,4 +22,10 @@ interface ScRootCauseAnalysisDao {
|
||||
insertList(list)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取问题环节数据
|
||||
*/
|
||||
@Query("select * from ScRootCauseAnalysis order by PROBLEM_LINK")
|
||||
suspend fun findAllData(): List<ScRootCauseAnalysisBean>?
|
||||
|
||||
}
|
@ -35,6 +35,7 @@ class MainActivityModule {
|
||||
|
||||
/**
|
||||
* 实验失败,这样创建,viewmodel不会在activity销毁的时候同时销毁
|
||||
* 4-14:因为没有传入activity的 owner,无法检测生命周期,
|
||||
*/
|
||||
// @ActivityRetainedScoped
|
||||
// @Provides
|
||||
|
@ -58,11 +58,11 @@ class LoginActivity : PermissionsActivity() {
|
||||
loginDialog = null
|
||||
}
|
||||
LoginStatus.LOGIN_STATUS_SUCCESS -> {
|
||||
val intent = Intent(this@LoginActivity, MainActivity::class.java)
|
||||
startActivity(intent)
|
||||
// finish()
|
||||
loginDialog?.dismiss()
|
||||
loginDialog = null
|
||||
val intent = Intent(this@LoginActivity, MainActivity::class.java)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
}
|
||||
LoginStatus.LOGIN_STATUS_CANCEL -> {
|
||||
loginDialog?.dismiss()
|
||||
|
@ -141,7 +141,8 @@ class LoginViewModel @Inject constructor(
|
||||
.show()
|
||||
}
|
||||
}
|
||||
NetResult.Loading -> {}
|
||||
is NetResult.Loading -> {}
|
||||
else -> {}
|
||||
}
|
||||
loginStatus.postValue(LoginStatus.LOGIN_STATUS_SUCCESS)
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import android.util.Log
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import androidx.navigation.findNavController
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
@ -52,7 +53,7 @@ class MainActivity : BaseActivity() {
|
||||
//给xml传递viewModel对象
|
||||
binding.viewModel = viewModel
|
||||
// lifecycle.addObserver(viewModel)
|
||||
|
||||
lifecycleScope
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
@ -92,4 +93,8 @@ class MainActivity : BaseActivity() {
|
||||
val naviController = findNavController(R.id.main_activity_right_fragment)
|
||||
naviController.navigate(R.id.EvaluationResultFragment)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.navinfo.omqs.ui.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
|
||||
abstract class BaseFragment : Fragment() {
|
||||
// override fun onCreateView(
|
||||
// inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
// ): View {
|
||||
// val view = OnCreateView(inflater, container, savedInstanceState)
|
||||
//
|
||||
// view.isFocusableInTouchMode = true;
|
||||
// view.requestFocus();
|
||||
// view.setOnKeyListener { _, keyCode, event ->
|
||||
// if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_DOWN) {
|
||||
// onBackPressed()
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
//
|
||||
//
|
||||
// return view
|
||||
// }
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
// 获取OnBackPressedDispatcher
|
||||
val dispatcher = requireActivity().onBackPressedDispatcher
|
||||
val callback = object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
// 添加返回键事件处理逻辑
|
||||
dispatcher.addCallback(this, callback)
|
||||
}
|
||||
|
||||
// abstract fun OnCreateView(
|
||||
// inflater: LayoutInflater,
|
||||
// container: ViewGroup?,
|
||||
// savedInstanceState: Bundle?
|
||||
// ): View
|
||||
|
||||
fun onBackPressed(): Boolean{
|
||||
findNavController().navigateUp()
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
|
||||
class EvaluationResultAdapter(activity: FragmentActivity, val fragmentList: List<Fragment>) :
|
||||
FragmentStateAdapter(activity) {
|
||||
override fun getItemCount(): Int {
|
||||
return fragmentList.size
|
||||
}
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return fragmentList[position]
|
||||
}
|
||||
}
|
@ -4,128 +4,251 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.findNavController
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.FragmentEvaluationResultBinding
|
||||
import com.navinfo.omqs.ui.fragment.BaseFragment
|
||||
import com.navinfo.omqs.ui.other.shareViewModels
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class EvaluationResultFragment : Fragment() {
|
||||
class EvaluationResultFragment : BaseFragment(), View.OnClickListener {
|
||||
private var _binding: FragmentEvaluationResultBinding? = null
|
||||
|
||||
private val binding get() = _binding!!
|
||||
private val viewModel by lazy { viewModels<EvaluationResultViewModel>().value }
|
||||
private var phenomenonFragmentAdapter: EvaluationResultAdapter? = null
|
||||
private val viewModel by shareViewModels<EvaluationResultViewModel>("QsRecode")
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentEvaluationResultBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
//返回按钮
|
||||
binding.evaluationBar.setNavigationOnClickListener {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
//监听数据变化
|
||||
viewModel.classTypeListLiveData.observe(viewLifecycleOwner) {
|
||||
if (it == null || it.isEmpty()) {
|
||||
Toast.makeText(requireContext(), "还没有导入元数据!", Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
binding.evaluationClassType.adapter =
|
||||
ArrayAdapter(requireContext(), R.layout.text_item_select, it)
|
||||
}
|
||||
}
|
||||
//选择问题分类的回调
|
||||
binding.evaluationClassType.onItemSelectedListener =
|
||||
object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(
|
||||
parent: AdapterView<*>?, view: View?, position: Int, id: Long
|
||||
) {
|
||||
viewModel.getProblemTypeList(position)
|
||||
}
|
||||
liveDataObserve()
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||
}
|
||||
/**
|
||||
* 监听联动选择的内容
|
||||
* 点击监听
|
||||
*/
|
||||
viewModel.problemTypeListLiveData.observe(viewLifecycleOwner) {
|
||||
binding.evaluationClassTabLayout.let { tabLayout ->
|
||||
tabLayout.removeAllTabs()
|
||||
val fragmentList = mutableListOf<Fragment>()
|
||||
for (item in it) {
|
||||
val tab = tabLayout.newTab()
|
||||
tab.text = item
|
||||
tabLayout.addTab(tab)
|
||||
fragmentList.add(PhenomenonFragment(viewModel.currentClassType,item))
|
||||
}
|
||||
phenomenonFragmentAdapter =
|
||||
activity?.let { a -> EvaluationResultAdapter(a, fragmentList) }
|
||||
binding.evaluationViewpager.adapter = phenomenonFragmentAdapter
|
||||
|
||||
TabLayoutMediator(
|
||||
binding.evaluationClassTabLayout,
|
||||
binding.evaluationViewpager
|
||||
) { tab, position ->
|
||||
tab.text = it[position]
|
||||
}.attach()
|
||||
updateHeight(0)
|
||||
}
|
||||
binding.evaluationClassType.setOnClickListener(this)
|
||||
binding.evaluationProblemType.setOnClickListener(this)
|
||||
binding.evaluationPhenomenon.setOnClickListener(this)
|
||||
binding.evaluationLink.setOnClickListener(this)
|
||||
binding.evaluationCause.setOnClickListener(this)
|
||||
|
||||
//返回按钮点击
|
||||
binding.evaluationBar.setNavigationOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
//获取数据
|
||||
viewModel.getClassTypeList()
|
||||
binding.evaluationViewpager.registerOnPageChangeCallback(object :
|
||||
ViewPager2.OnPageChangeCallback() {
|
||||
override fun onPageSelected(position: Int) {
|
||||
super.onPageSelected(position)
|
||||
updateHeight(position)
|
||||
//标题栏按钮
|
||||
binding.evaluationBar.setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.save -> {
|
||||
viewModel.saveData()
|
||||
true
|
||||
}
|
||||
R.id.delete -> {
|
||||
viewModel.deleteData()
|
||||
true
|
||||
}
|
||||
else -> true
|
||||
}
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 读取元数据
|
||||
*/
|
||||
viewModel.loadMetadata()
|
||||
// //监听大分类数据变化
|
||||
// viewModel.liveDataClassTypeList.observe(viewLifecycleOwner) {
|
||||
// if (it == null || it.isEmpty()) {
|
||||
// Toast.makeText(requireContext(), "还没有导入元数据!", Toast.LENGTH_SHORT).show()
|
||||
// } else {
|
||||
// binding.evaluationClassType.adapter =
|
||||
// ArrayAdapter(requireContext(), R.layout.text_item_select, it)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// viewModel.liveDataProblemTypeList.observe(viewLifecycleOwner){
|
||||
// if (it == null || it.isEmpty()) {
|
||||
// Toast.makeText(requireContext(), "还没有导入元数据!", Toast.LENGTH_SHORT).show()
|
||||
// }else{
|
||||
// binding.evaluationProblemType.adapter =
|
||||
// ArrayAdapter(requireContext(), R.layout.text_item_select, it)
|
||||
// }
|
||||
// }
|
||||
|
||||
// //选择问题分类的回调
|
||||
// binding.evaluationClassType.onItemSelectedListener =
|
||||
// object : AdapterView.OnItemSelectedListener {
|
||||
// override fun onItemSelected(
|
||||
// parent: AdapterView<*>?, view: View?, position: Int, id: Long
|
||||
// ) {
|
||||
// viewModel.getProblemTypeList(position)
|
||||
// }
|
||||
//
|
||||
// override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||
// }
|
||||
// /**
|
||||
// * 监听联动选择的内容
|
||||
// */
|
||||
// viewModel.problemTypeListLiveData.observe(viewLifecycleOwner) {
|
||||
// binding.evaluationClassTabLayout.let { tabLayout ->
|
||||
// tabLayout.removeAllTabs()
|
||||
// val fragmentList = mutableListOf<Fragment>()
|
||||
// for (item in it) {
|
||||
// val tab = tabLayout.newTab()
|
||||
// tab.text = item
|
||||
// tabLayout.addTab(tab)
|
||||
// fragmentList.add(PhenomenonFragment(viewModel.currentClassType, item))
|
||||
// }
|
||||
// phenomenonFragmentAdapter =
|
||||
// activity?.let { a -> EvaluationResultAdapter(a, fragmentList) }
|
||||
// binding.evaluationViewpager.adapter = phenomenonFragmentAdapter
|
||||
//
|
||||
// TabLayoutMediator(
|
||||
// binding.evaluationClassTabLayout,
|
||||
// binding.evaluationViewpager
|
||||
// ) { tab, position ->
|
||||
// tab.text = it[position]
|
||||
// }.attach()
|
||||
// updateHeight(0)
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
// binding.evaluationViewpager.registerOnPageChangeCallback(object :
|
||||
// ViewPager2.OnPageChangeCallback() {
|
||||
// override fun onPageSelected(position: Int) {
|
||||
// super.onPageSelected(position)
|
||||
// updateHeight(position)
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
|
||||
private fun updateHeight(position: Int) {
|
||||
phenomenonFragmentAdapter?.let {
|
||||
if (it.fragmentList.size > position) {
|
||||
val fragment: Fragment = it.fragmentList[position]
|
||||
if (fragment.view != null) {
|
||||
val viewWidth = View.MeasureSpec.makeMeasureSpec(
|
||||
fragment.requireView().width, View.MeasureSpec.EXACTLY
|
||||
)
|
||||
val viewHeight =
|
||||
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
|
||||
fragment.requireView().measure(viewWidth, viewHeight)
|
||||
binding.evaluationViewpager.let { viewpager ->
|
||||
if (viewpager.layoutParams.height != fragment.requireView().measuredHeight) {
|
||||
//必须要用对象去接收,然后修改该对象再采用该对象,否则无法生效...
|
||||
val layoutParams: ViewGroup.LayoutParams =
|
||||
viewpager.layoutParams
|
||||
layoutParams.height = fragment.requireView().measuredHeight
|
||||
viewpager.layoutParams = layoutParams
|
||||
}
|
||||
}
|
||||
// private fun updateHeight(position: Int) {
|
||||
// phenomenonFragmentAdapter?.let {
|
||||
// if (it.fragmentList.size > position) {
|
||||
// val fragment: Fragment = it.fragmentList[position]
|
||||
// if (fragment.view != null) {
|
||||
// val viewWidth = View.MeasureSpec.makeMeasureSpec(
|
||||
// fragment.requireView().width, View.MeasureSpec.EXACTLY
|
||||
// )
|
||||
// val viewHeight =
|
||||
// View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
|
||||
// fragment.requireView().measure(viewWidth, viewHeight)
|
||||
// binding.evaluationViewpager.let { viewpager ->
|
||||
// if (viewpager.layoutParams.height != fragment.requireView().measuredHeight) {
|
||||
// //必须要用对象去接收,然后修改该对象再采用该对象,否则无法生效...
|
||||
// val layoutParams: ViewGroup.LayoutParams =
|
||||
// viewpager.layoutParams
|
||||
// layoutParams.height = fragment.requireView().measuredHeight
|
||||
// viewpager.layoutParams = layoutParams
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 监听liveData
|
||||
*/
|
||||
private fun liveDataObserve() {
|
||||
|
||||
//监听问题分类,更新UI
|
||||
viewModel.liveDataCurrentClassType.observe(viewLifecycleOwner) {
|
||||
binding.evaluationClassType.text = it
|
||||
}
|
||||
//监听问题类型,更新UI
|
||||
viewModel.liveDataCurrentProblemType.observe(viewLifecycleOwner) {
|
||||
binding.evaluationProblemType.text = it
|
||||
}
|
||||
//监听问题现象,更新UI
|
||||
viewModel.liveDataCurrentPhenomenon.observe(viewLifecycleOwner) {
|
||||
binding.evaluationPhenomenon.text = it
|
||||
}
|
||||
//监听问题环节,更新UI
|
||||
viewModel.liveDataCurrentProblemLink.observe(viewLifecycleOwner) {
|
||||
binding.evaluationLink.text = it
|
||||
}
|
||||
//监听问题初步原因,更新UI
|
||||
viewModel.liveDataCurrentCause.observe(viewLifecycleOwner) {
|
||||
binding.evaluationCause.text = it
|
||||
}
|
||||
//监听是否退出当前页面
|
||||
viewModel.liveDataFinish.observe(viewLifecycleOwner) {
|
||||
onBackPressed()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
override fun onDestroyView() {
|
||||
activity?.apply {
|
||||
findNavController(R.id.main_activity_middle_fragment).navigateUp()
|
||||
}
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理点击事件
|
||||
*/
|
||||
override fun onClick(v: View?) {
|
||||
v?.let {
|
||||
when (v.id) {
|
||||
//上三项,打开面板
|
||||
R.id.evaluation_class_type, R.id.evaluation_problem_type, R.id.evaluation_phenomenon -> {
|
||||
activity?.apply {
|
||||
val controller = findNavController(R.id.main_activity_middle_fragment)
|
||||
controller.currentDestination?.let {
|
||||
//如果之前页面是空fragment,直接打开面板
|
||||
if (it.id == R.id.EmptyFragment) {
|
||||
findNavController(
|
||||
R.id.main_activity_middle_fragment
|
||||
).navigate(R.id.PhenomenonFragment)
|
||||
} else if (it.id != R.id.PhenomenonFragment) {//不是空fragment,先弹出之前的fragment
|
||||
findNavController(
|
||||
R.id.main_activity_middle_fragment
|
||||
).navigate(
|
||||
R.id.PhenomenonFragment,
|
||||
null,
|
||||
NavOptions.Builder()
|
||||
.setPopUpTo(it.id, true).build()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//下两项,打开面板
|
||||
R.id.evaluation_link, R.id.evaluation_cause -> {
|
||||
activity?.apply {
|
||||
val controller = findNavController(R.id.main_activity_middle_fragment)
|
||||
controller.currentDestination?.let {
|
||||
//如果之前页面是空fragment,直接打开面板
|
||||
if (it.id == R.id.EmptyFragment) {
|
||||
findNavController(
|
||||
R.id.main_activity_middle_fragment
|
||||
).navigate(R.id.ProblemLinkFragment)
|
||||
} else if (it.id != R.id.ProblemLinkFragment) {//不是空fragment,先弹出之前的fragment
|
||||
findNavController(
|
||||
R.id.main_activity_middle_fragment
|
||||
).navigate(
|
||||
R.id.ProblemLinkFragment,
|
||||
null,
|
||||
NavOptions.Builder()
|
||||
.setPopUpTo(it.id, true).build()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,73 +1,242 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.navinfo.collect.library.map.GeoPoint
|
||||
import com.navinfo.collect.library.map.NIMapController
|
||||
import com.navinfo.collect.library.data.entity.QsRecordBean
|
||||
import com.navinfo.omqs.db.RoomAppDatabase
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import io.realm.Realm
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.Dispatcher
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class EvaluationResultViewModel @Inject constructor(
|
||||
private val roomAppDatabase: RoomAppDatabase,
|
||||
private val roomAppDatabase: RoomAppDatabase, private val mapController: NIMapController
|
||||
) : ViewModel() {
|
||||
|
||||
private val markerTitle = "点选marker"
|
||||
|
||||
/**
|
||||
* 操作结束,销毁页面
|
||||
*/
|
||||
val liveDataFinish = MutableLiveData<Boolean>()
|
||||
|
||||
/**
|
||||
* 问题分类 liveData,给[PhenomenonLeftAdapter]展示的数据
|
||||
*/
|
||||
val liveDataClassTypeList = MutableLiveData<List<String>>()
|
||||
|
||||
/**
|
||||
* 问题类型 liveData 给[PhenomenonMiddleAdapter]展示的数据
|
||||
*/
|
||||
val liveDataProblemTypeList = MutableLiveData<List<String>>()
|
||||
|
||||
/**
|
||||
* 问题现象 liveData 给[PhenomenonRightGroupHeaderAdapter]展示的数据
|
||||
*/
|
||||
val liveDataPhenomenonRightList = MutableLiveData<List<PhenomenonMiddleBean>>()
|
||||
|
||||
|
||||
/**
|
||||
* 当前选择问题分类 给[EvaluationResultFragment]中 【问题分类】展示数据
|
||||
*/
|
||||
var liveDataCurrentClassType = MutableLiveData<String>()
|
||||
|
||||
/**
|
||||
* 当前选择的问题类型 给[EvaluationResultFragment]中 【问题类型】展示数据
|
||||
*/
|
||||
var liveDataCurrentProblemType = MutableLiveData<String>()
|
||||
|
||||
/**
|
||||
* 当前选择的问题现象 给[EvaluationResultFragment]中 【问题现象】展示数据
|
||||
*/
|
||||
var liveDataCurrentPhenomenon = MutableLiveData<String>()
|
||||
|
||||
|
||||
/**
|
||||
* 当前选择的问题环节 给[EvaluationResultFragment]中 【问题环节】展示数据
|
||||
*/
|
||||
var liveDataCurrentProblemLink = MutableLiveData<String>()
|
||||
|
||||
/**
|
||||
* 当前选择的问初步原因 给[EvaluationResultFragment]中 【初步原因】展示数据
|
||||
*/
|
||||
var liveDataCurrentCause = MutableLiveData<String>()
|
||||
|
||||
var currentGeoPoint: GeoPoint? = null
|
||||
|
||||
|
||||
init {
|
||||
Log.e("jingo", "EvaluationResultViewModel 创建了 ${hashCode()}")
|
||||
mapController.markerHandle.apply {
|
||||
setOnMapClickListener {
|
||||
currentGeoPoint = it
|
||||
addMarker(it, markerTitle)
|
||||
}
|
||||
}
|
||||
val geoPoint = mapController.locationLayerHandler.getCurrentGeoPoint()
|
||||
geoPoint?.let {
|
||||
currentGeoPoint = it
|
||||
mapController.markerHandle.addMarker(geoPoint, markerTitle)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
Log.e("jingo", "EvaluationResultViewModel 销毁了 ${hashCode()}")
|
||||
mapController.markerHandle.removeMarker(markerTitle)
|
||||
mapController.markerHandle.removeOnMapClickListener()
|
||||
}
|
||||
|
||||
/**
|
||||
* 问题分类 liveData
|
||||
*/
|
||||
|
||||
val classTypeListLiveData = MutableLiveData<List<String>?>()
|
||||
|
||||
/**
|
||||
* 问题类型 liveData
|
||||
*/
|
||||
|
||||
val problemTypeListLiveData = MutableLiveData<List<String>>()
|
||||
|
||||
var currentClassType: String = ""
|
||||
|
||||
/**
|
||||
* 查询数据库,获取问题分类
|
||||
*/
|
||||
fun loadMetadata() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
getClassTypeList()
|
||||
getProblemLinkList()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* //获取问题分类列表
|
||||
*/
|
||||
fun getClassTypeList() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val list = roomAppDatabase.getScProblemTypeDao().findClassTypeList()
|
||||
classTypeListLiveData.postValue(list)
|
||||
list?.let {
|
||||
//通知页面更新
|
||||
liveDataClassTypeList.postValue(it)
|
||||
//如果右侧栏没数据,给个默认值
|
||||
if (liveDataCurrentClassType.value == null) {
|
||||
liveDataCurrentClassType.postValue(it[0])
|
||||
}
|
||||
getProblemList(it[0])
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取问题环节列表和初步问题
|
||||
*/
|
||||
fun getProblemLinkList() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val list = roomAppDatabase.getScRootCauseAnalysisDao().findAllData()
|
||||
list?.let { tl ->
|
||||
if (tl.isNotEmpty()) {
|
||||
val typeTitleList = mutableListOf<String>()
|
||||
val phenomenonRightList = mutableListOf<PhenomenonMiddleBean>()
|
||||
for (item in tl) {
|
||||
if (!typeTitleList.contains(item.problemLink)) {
|
||||
typeTitleList.add(item.problemLink)
|
||||
}
|
||||
phenomenonRightList.add(
|
||||
PhenomenonMiddleBean(
|
||||
title = item.problemLink, text = item.problemCause, isSelect = false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
if (liveDataCurrentProblemLink.value == null) {
|
||||
liveDataCurrentProblemLink.postValue(phenomenonRightList[0].text)
|
||||
}
|
||||
if (liveDataCurrentCause.value == null) {
|
||||
liveDataCurrentCause.postValue(typeTitleList[0])
|
||||
}
|
||||
liveDataProblemTypeList.postValue(typeTitleList)
|
||||
liveDataPhenomenonRightList.postValue(phenomenonRightList)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取问题类型列表和问题现象
|
||||
*/
|
||||
private suspend fun getProblemList(classType: String) {
|
||||
val typeList = roomAppDatabase.getScProblemTypeDao().findProblemTypeList(classType)
|
||||
typeList?.let { tl ->
|
||||
if (tl.isNotEmpty()) {
|
||||
val typeTitleList = mutableListOf<String>()
|
||||
val phenomenonRightList = mutableListOf<PhenomenonMiddleBean>()
|
||||
for (item in tl) {
|
||||
if (!typeTitleList.contains(item.problemType)) {
|
||||
typeTitleList.add(item.problemType)
|
||||
}
|
||||
phenomenonRightList.add(
|
||||
PhenomenonMiddleBean(
|
||||
title = item.problemType, text = item.phenomenon, isSelect = false
|
||||
)
|
||||
)
|
||||
}
|
||||
if (liveDataCurrentPhenomenon.value == null) {
|
||||
liveDataCurrentPhenomenon.postValue(phenomenonRightList[0].text)
|
||||
}
|
||||
if (liveDataCurrentProblemType.value == null) {
|
||||
liveDataCurrentProblemType.postValue(typeTitleList[0])
|
||||
}
|
||||
liveDataProblemTypeList.postValue(typeTitleList)
|
||||
liveDataPhenomenonRightList.postValue(phenomenonRightList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询问题类型
|
||||
*/
|
||||
fun getProblemTypeList(index: Int) {
|
||||
fun getProblemTypeList(classType: String) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
classTypeListLiveData.value?.let {
|
||||
if (index < it.size) {
|
||||
currentClassType = it[index]
|
||||
val list =
|
||||
roomAppDatabase.getScProblemTypeDao().findProblemTypeList(currentClassType)
|
||||
problemTypeListLiveData.postValue(list)
|
||||
}
|
||||
}
|
||||
liveDataCurrentClassType.postValue(classType)
|
||||
getProblemList(classType)
|
||||
}
|
||||
}
|
||||
|
||||
fun getPhenomenonList() {
|
||||
viewModelScope.launch (Dispatchers.IO){
|
||||
fun setPhenomenonMiddleBean(bean: PhenomenonMiddleBean) {
|
||||
if (liveDataCurrentPhenomenon.value != bean.text) liveDataCurrentPhenomenon.value =
|
||||
bean.text
|
||||
if (liveDataCurrentProblemType.value != bean.title) liveDataCurrentProblemType.value =
|
||||
bean.title
|
||||
|
||||
}
|
||||
|
||||
fun setProblemLinkMiddleBean(bean: PhenomenonMiddleBean) {
|
||||
if (liveDataCurrentProblemLink.value != bean.text) liveDataCurrentProblemLink.value =
|
||||
bean.text
|
||||
if (liveDataCurrentCause.value != bean.title) liveDataCurrentCause.value = bean.title
|
||||
|
||||
}
|
||||
|
||||
fun saveData() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val qsRecord = QsRecordBean(
|
||||
id = UUID.randomUUID().toString(),
|
||||
classType = liveDataCurrentClassType.value.toString(),
|
||||
type = liveDataCurrentProblemType.value.toString(),
|
||||
phenomenon = liveDataCurrentPhenomenon.value.toString(),
|
||||
problemLink = liveDataCurrentProblemLink.value.toString(),
|
||||
cause = liveDataCurrentCause.value.toString(),
|
||||
)
|
||||
qsRecord.geometry = currentGeoPoint!!.toGeometry()
|
||||
val realm = Realm.getDefaultInstance()
|
||||
realm.executeTransaction {
|
||||
it.copyToRealmOrUpdate(qsRecord)
|
||||
}
|
||||
realm.close()
|
||||
mapController.mMapView.updateMap()
|
||||
liveDataFinish.postValue(true)
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteData() {
|
||||
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.TextItemSelectBinding
|
||||
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
|
||||
import com.navinfo.omqs.ui.other.BaseViewHolder
|
||||
|
||||
class PhenomenonAdapter() : BaseRecyclerViewAdapter<String>() {
|
||||
override fun getItemViewRes(position: Int): Int {
|
||||
return R.layout.text_item_select
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
|
||||
val viewBinding =
|
||||
TextItemSelectBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return BaseViewHolder(viewBinding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
|
||||
(holder.viewBinding as TextItemSelectBinding).itemId.text = data[position]
|
||||
}
|
||||
}
|
@ -6,45 +6,111 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.OnScrollListener
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.FragmentPhenomenonBinding
|
||||
import com.navinfo.omqs.db.RoomAppDatabase
|
||||
import com.navinfo.omqs.ui.fragment.BaseFragment
|
||||
import com.navinfo.omqs.ui.other.shareViewModels
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class PhenomenonFragment(private val classType: String, private val title: String) :
|
||||
Fragment() {
|
||||
@Inject
|
||||
lateinit var roomAppDatabase: RoomAppDatabase
|
||||
class PhenomenonFragment :
|
||||
BaseFragment() {
|
||||
private var _binding: FragmentPhenomenonBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val viewModel: EvaluationResultViewModel by shareViewModels("QsRecode")
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentPhenomenonBinding.inflate(inflater, container, false)
|
||||
Log.e("jingo", "PhenomenonFragment onCreateView ${hashCode()}")
|
||||
return binding.root
|
||||
|
||||
}
|
||||
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding.phenomenonRecyclerview.setHasFixedSize(true)
|
||||
binding.phenomenonRecyclerview.layoutManager = LinearLayoutManager(context)
|
||||
val adapter = PhenomenonAdapter()
|
||||
binding.phenomenonRecyclerview.adapter = adapter
|
||||
lifecycleScope.launch {
|
||||
Log.e("jingo", "$classType $title ")
|
||||
val list = roomAppDatabase.getScProblemTypeDao().getPhenomenonList(classType, title)
|
||||
Log.e("jingo", "${list.toString()}")
|
||||
adapter.refreshData(list)
|
||||
|
||||
//左侧菜单
|
||||
binding.phenomenonLeftRecyclerview.setHasFixedSize(true)
|
||||
binding.phenomenonLeftRecyclerview.layoutManager = LinearLayoutManager(requireContext())
|
||||
val leftAdapter = PhenomenonLeftAdapter { _, text ->
|
||||
viewModel.getProblemTypeList(text)
|
||||
}
|
||||
binding.phenomenonLeftRecyclerview.adapter = leftAdapter
|
||||
//左侧菜单查询结果监听
|
||||
viewModel.liveDataClassTypeList.observe(viewLifecycleOwner) {
|
||||
leftAdapter.refreshData(it)
|
||||
}
|
||||
|
||||
//右侧菜单
|
||||
binding.phenomenonRightRecyclerview.setHasFixedSize(true)
|
||||
var rightLayoutManager = LinearLayoutManager(requireContext())
|
||||
|
||||
binding.phenomenonRightRecyclerview.layoutManager = rightLayoutManager
|
||||
val rightAdapter = PhenomenonRightGroupHeaderAdapter { _, bean ->
|
||||
viewModel.setPhenomenonMiddleBean(bean)
|
||||
}
|
||||
binding.phenomenonRightRecyclerview.adapter = rightAdapter
|
||||
//右侧菜单增加组标题
|
||||
binding.phenomenonRightRecyclerview.addItemDecoration(
|
||||
PhenomenonRightGroupHeaderDecoration(
|
||||
requireContext()
|
||||
)
|
||||
)
|
||||
//右侧菜单查询数据监听
|
||||
viewModel.liveDataPhenomenonRightList.observe(viewLifecycleOwner) {
|
||||
rightAdapter.refreshData(it)
|
||||
}
|
||||
|
||||
val middleAdapter = PhenomenonMiddleAdapter { _, title ->
|
||||
rightLayoutManager.scrollToPositionWithOffset(rightAdapter.getGroupTopIndex(title), 0)
|
||||
|
||||
}
|
||||
|
||||
binding.phenomenonRightRecyclerview.addOnScrollListener(object :
|
||||
OnScrollListener() {
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
super.onScrollStateChanged(recyclerView, newState)
|
||||
}
|
||||
|
||||
//findLastVisibleItemPosition() :最后一个可见位置
|
||||
// findFirstVisibleItemPosition() :第一个可见位置
|
||||
// findLastCompletelyVisibleItemPosition() :最后一个完全可见位置
|
||||
// findFirstCompletelyVisibleItemPosition() :第一个完全可见位置
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
val firstIndex = rightLayoutManager.findFirstVisibleItemPosition()
|
||||
middleAdapter.setRightTitle(rightAdapter.data[firstIndex].title)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
//中间菜单
|
||||
binding.phenomenonMiddleRecyclerview.setHasFixedSize(true)
|
||||
binding.phenomenonMiddleRecyclerview.layoutManager = LinearLayoutManager(requireContext())
|
||||
binding.phenomenonMiddleRecyclerview.adapter = middleAdapter
|
||||
//中间侧菜单查询结果监听
|
||||
viewModel.liveDataProblemTypeList.observe(viewLifecycleOwner) {
|
||||
middleAdapter.refreshData(it)
|
||||
}
|
||||
binding.phenomenonDrawer.setOnClickListener {
|
||||
when (binding.group.visibility) {
|
||||
View.INVISIBLE, View.GONE ->
|
||||
binding.group.visibility = View.VISIBLE
|
||||
else ->
|
||||
binding.group.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.getClassTypeList()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
@ -0,0 +1,54 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.TextItemSelectBinding
|
||||
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
|
||||
import com.navinfo.omqs.ui.other.BaseViewHolder
|
||||
|
||||
class PhenomenonLeftAdapter(private var itemListener: ((Int, String) -> Unit?)? = null) :
|
||||
BaseRecyclerViewAdapter<String>() {
|
||||
private var selectTitle = ""
|
||||
|
||||
override fun getItemViewRes(position: Int): Int {
|
||||
return R.layout.text_item_select
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
|
||||
val viewBinding =
|
||||
TextItemSelectBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return BaseViewHolder(viewBinding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
|
||||
val bd = holder.viewBinding as TextItemSelectBinding
|
||||
val title = data[position]
|
||||
bd.itemId.text = title
|
||||
if (selectTitle == title) {
|
||||
bd.itemId.setBackgroundColor(holder.viewBinding.root.context.getColor(R.color.cv_gray_153))
|
||||
} else {
|
||||
bd.itemId.setBackgroundColor(holder.viewBinding.root.context.getColor(R.color.white))
|
||||
}
|
||||
bd.root.setOnClickListener {
|
||||
if (selectTitle != title) {
|
||||
selectTitle = title
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
itemListener?.invoke(position, title)
|
||||
}
|
||||
}
|
||||
|
||||
override fun refreshData(newData: List<String>) {
|
||||
data = newData
|
||||
selectTitle = newData[0]
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun setRightTitle(title: String) {
|
||||
if (title != selectTitle) {
|
||||
selectTitle = title
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.TextItemSelectBinding
|
||||
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
|
||||
import com.navinfo.omqs.ui.other.BaseViewHolder
|
||||
|
||||
class PhenomenonMiddleAdapter(private var itemListener: ((Int, String) -> Unit?)? = null) :
|
||||
BaseRecyclerViewAdapter<String>() {
|
||||
private var selectTitle = ""
|
||||
|
||||
override fun getItemViewRes(position: Int): Int {
|
||||
return R.layout.text_item_select
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
|
||||
val viewBinding =
|
||||
TextItemSelectBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return BaseViewHolder(viewBinding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
|
||||
val bd = holder.viewBinding as TextItemSelectBinding
|
||||
val title = data[position]
|
||||
bd.itemId.text = title
|
||||
if (selectTitle == title) {
|
||||
bd.itemId.setBackgroundColor(holder.viewBinding.root.context.getColor(R.color.cv_gray_153))
|
||||
} else {
|
||||
bd.itemId.setBackgroundColor(holder.viewBinding.root.context.getColor(R.color.white))
|
||||
}
|
||||
bd.root.setOnClickListener {
|
||||
if (selectTitle != title) {
|
||||
selectTitle = title
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
itemListener?.invoke(position, title)
|
||||
}
|
||||
}
|
||||
|
||||
override fun refreshData(newData: List<String>) {
|
||||
data = newData
|
||||
selectTitle = newData[0]
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun setRightTitle(title: String) {
|
||||
if (title != selectTitle) {
|
||||
selectTitle = title
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
/**
|
||||
* 问题现象列表
|
||||
*/
|
||||
data class PhenomenonMiddleBean(val title: String, val text: String, var isSelect: Boolean = false)
|
@ -0,0 +1,103 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import com.navinfo.omqs.R
|
||||
import com.navinfo.omqs.databinding.TextItemSelectBinding
|
||||
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
|
||||
import com.navinfo.omqs.ui.other.BaseViewHolder
|
||||
|
||||
class PhenomenonRightGroupHeaderAdapter(private var itemListener: ((Int, PhenomenonMiddleBean) -> Unit?)? = null) :
|
||||
BaseRecyclerViewAdapter<PhenomenonMiddleBean>() {
|
||||
private var groupTitleList = mutableListOf<String>()
|
||||
override fun getItemViewRes(position: Int): Int {
|
||||
return R.layout.text_item_select
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
|
||||
val viewBinding =
|
||||
TextItemSelectBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return BaseViewHolder(viewBinding)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
|
||||
val bd = holder.viewBinding as TextItemSelectBinding
|
||||
bd.itemId.text = data[position].text
|
||||
bd.root.setOnClickListener {
|
||||
itemListener?.invoke(position, data[position])
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断position对应的Item是否是组的第一项
|
||||
*
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
fun isItemHeader(position: Int): Boolean {
|
||||
if (position >= data.size)
|
||||
return false
|
||||
return if (position == 0) {
|
||||
true
|
||||
} else {
|
||||
val lastGroupName = data[position - 1].title
|
||||
val currentGroupName = data[position].title
|
||||
//判断上一个数据的组别和下一个数据的组别是否一致,如果不一致则是不同组,也就是为第一项(头部)
|
||||
lastGroupName != currentGroupName
|
||||
}
|
||||
}
|
||||
|
||||
fun isLastGroupTitle(position: Int): Boolean {
|
||||
if (groupTitleList.isNotEmpty() && data[position].title == groupTitleList.last()) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取position对应的Item组名
|
||||
*
|
||||
* @param position
|
||||
* @return
|
||||
*/
|
||||
fun getGroupName(position: Int): String {
|
||||
return data[position].title
|
||||
}
|
||||
|
||||
fun getGroupTopIndex(position: Int): Int {
|
||||
var nowPosition = position
|
||||
val title = data[position].title
|
||||
for (i in data.size - 2 downTo 0) {
|
||||
if (data[i].title == title) {
|
||||
nowPosition = i
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return nowPosition
|
||||
}
|
||||
|
||||
fun getGroupTopIndex(title: String): Int {
|
||||
for (i in data.indices) {
|
||||
if (data[i].title == title)
|
||||
return i
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun refreshData(newData: List<PhenomenonMiddleBean>) {
|
||||
super.refreshData(newData)
|
||||
groupTitleList.clear()
|
||||
for (item in newData) {
|
||||
if (groupTitleList.size > 0) {
|
||||
if (groupTitleList.last() != item.title) {
|
||||
groupTitleList.add(item.title)
|
||||
}
|
||||
} else {
|
||||
groupTitleList.add(item.title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,205 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Color
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Rect
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.ItemDecoration
|
||||
|
||||
|
||||
/**
|
||||
* 自定义装饰器(实现分组+吸顶效果)
|
||||
*/
|
||||
class PhenomenonRightGroupHeaderDecoration(context: Context) : ItemDecoration() {
|
||||
//头部的高
|
||||
private val mItemHeaderHeight: Int
|
||||
private val mTextPaddingLeft: Int
|
||||
|
||||
//画笔,绘制头部和分割线
|
||||
private val mItemHeaderPaint: Paint
|
||||
private val mTextPaint: Paint
|
||||
private val mLinePaint: Paint
|
||||
private val mTextRect: Rect
|
||||
private var lastGroupView: View? = null
|
||||
|
||||
init {
|
||||
mItemHeaderHeight = dp2px(context, 40f)
|
||||
mTextPaddingLeft = dp2px(context, 6f)
|
||||
mTextRect = Rect()
|
||||
mItemHeaderPaint = Paint(Paint.ANTI_ALIAS_FLAG)
|
||||
mItemHeaderPaint.color = Color.GRAY
|
||||
mTextPaint = Paint(Paint.ANTI_ALIAS_FLAG)
|
||||
mTextPaint.textSize = 46f
|
||||
mTextPaint.color = Color.WHITE
|
||||
mLinePaint = Paint(Paint.ANTI_ALIAS_FLAG)
|
||||
mLinePaint.color = Color.GRAY
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制Item的分割线和组头
|
||||
*
|
||||
* @param c
|
||||
* @param parent
|
||||
* @param state
|
||||
*/
|
||||
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
|
||||
if (parent.adapter is PhenomenonRightGroupHeaderAdapter) {
|
||||
val adapter = parent.adapter as PhenomenonRightGroupHeaderAdapter
|
||||
val count = parent.childCount //获取可见范围内Item的总数
|
||||
for (i in 0 until count) {
|
||||
val view: View = parent.getChildAt(i)
|
||||
|
||||
val position = parent.getChildLayoutPosition(view)
|
||||
val isHeader: Boolean = adapter.isItemHeader(position)
|
||||
val left = parent.paddingLeft
|
||||
val right = parent.width - parent.paddingRight
|
||||
if (isHeader) {
|
||||
c.drawRect(
|
||||
left.toFloat(),
|
||||
(view.top - mItemHeaderHeight).toFloat(),
|
||||
right.toFloat(),
|
||||
view.top.toFloat(),
|
||||
mItemHeaderPaint
|
||||
)
|
||||
val text = adapter.getGroupName(position)
|
||||
mTextPaint.getTextBounds(
|
||||
text,
|
||||
0,
|
||||
text.length,
|
||||
mTextRect
|
||||
)
|
||||
c.drawText(
|
||||
adapter.getGroupName(position),
|
||||
(left + mTextPaddingLeft).toFloat(),
|
||||
(view.top - mItemHeaderHeight + mItemHeaderHeight / 2 + mTextRect.height() / 2).toFloat(),
|
||||
mTextPaint
|
||||
)
|
||||
} else {
|
||||
c.drawRect(
|
||||
left.toFloat(),
|
||||
(view.top - 1).toFloat(), right.toFloat(),
|
||||
view.top.toFloat(), mLinePaint
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制Item的顶部布局(吸顶效果)
|
||||
*
|
||||
* @param c
|
||||
* @param parent
|
||||
* @param state
|
||||
*/
|
||||
override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
|
||||
if (parent.adapter is PhenomenonRightGroupHeaderAdapter) {
|
||||
val adapter = parent.adapter as PhenomenonRightGroupHeaderAdapter
|
||||
val position =
|
||||
(parent.layoutManager as LinearLayoutManager?)!!.findFirstVisibleItemPosition()
|
||||
parent.findViewHolderForAdapterPosition(position)?.let {
|
||||
val view: View = it.itemView
|
||||
val isHeader: Boolean = adapter.isItemHeader(position + 1)
|
||||
val top = parent.paddingTop
|
||||
val left = parent.paddingLeft
|
||||
val right = parent.width - parent.paddingRight
|
||||
if (isHeader) {
|
||||
val bottom = mItemHeaderHeight.coerceAtMost(view.bottom)
|
||||
c.drawRect(
|
||||
left.toFloat(),
|
||||
(top + view.top - mItemHeaderHeight).toFloat(),
|
||||
right.toFloat(),
|
||||
(top + bottom).toFloat(),
|
||||
mItemHeaderPaint
|
||||
)
|
||||
val text = adapter.getGroupName(position)
|
||||
mTextPaint.getTextBounds(
|
||||
text,
|
||||
0,
|
||||
text.length,
|
||||
mTextRect
|
||||
)
|
||||
c.drawText(
|
||||
adapter.getGroupName(position),
|
||||
(left + mTextPaddingLeft).toFloat(),
|
||||
(top + mItemHeaderHeight / 2 + mTextRect.height() / 2 - (mItemHeaderHeight - bottom)).toFloat(),
|
||||
mTextPaint
|
||||
)
|
||||
} else {
|
||||
c.drawRect(
|
||||
left.toFloat(),
|
||||
top.toFloat(), right.toFloat(),
|
||||
(top + mItemHeaderHeight).toFloat(), mItemHeaderPaint
|
||||
)
|
||||
val text = adapter.getGroupName(position)
|
||||
mTextPaint.getTextBounds(
|
||||
text,
|
||||
0,
|
||||
text.length,
|
||||
mTextRect
|
||||
)
|
||||
c.drawText(
|
||||
adapter.getGroupName(position), (left + mTextPaddingLeft).toFloat(),
|
||||
(top + mItemHeaderHeight / 2 + mTextRect.height() / 2).toFloat(), mTextPaint
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
c.save()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Item的间距
|
||||
*
|
||||
* @param outRect
|
||||
* @param view
|
||||
* @param parent
|
||||
* @param state
|
||||
*/
|
||||
override fun getItemOffsets(
|
||||
outRect: Rect,
|
||||
view: View,
|
||||
parent: RecyclerView,
|
||||
state: RecyclerView.State
|
||||
) {
|
||||
if (parent.adapter is PhenomenonRightGroupHeaderAdapter) {
|
||||
val adapter = parent.adapter as PhenomenonRightGroupHeaderAdapter
|
||||
//获取当前view在整个列表中的位置
|
||||
val position = parent.getChildLayoutPosition(view)
|
||||
//是不是改组的第一个
|
||||
val isHeader: Boolean = adapter.isItemHeader(position)
|
||||
if (isHeader) {
|
||||
outRect.top = mItemHeaderHeight
|
||||
if (adapter.isLastGroupTitle(position)) {
|
||||
lastGroupView = view
|
||||
}
|
||||
} else if (position == (parent.adapter as PhenomenonRightGroupHeaderAdapter).itemCount - 1) {
|
||||
//判断这条是不是最后一条
|
||||
//如果是最后一个,找到他所在组的第一个
|
||||
lastGroupView?.let {
|
||||
if (it.top > 0) {
|
||||
outRect.bottom = it.top - it.height * 2
|
||||
}
|
||||
}
|
||||
outRect.top = 1
|
||||
} else {
|
||||
outRect.top = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dp转换成px
|
||||
*/
|
||||
private fun dp2px(context: Context, dpValue: Float): Int {
|
||||
val scale: Float = context.resources.displayMetrics.density
|
||||
return (dpValue * scale + 0.5f).toInt()
|
||||
}
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package com.navinfo.omqs.ui.fragment.evaluationresult
|
||||
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.navinfo.omqs.databinding.FragmentProblemLinkBinding
|
||||
import com.navinfo.omqs.ui.fragment.BaseFragment
|
||||
import com.navinfo.omqs.ui.other.shareViewModels
|
||||
|
||||
class ProblemLinkFragment : BaseFragment() {
|
||||
private var _binding: FragmentProblemLinkBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private val viewModel: EvaluationResultViewModel by shareViewModels("QsRecode")
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentProblemLinkBinding.inflate(inflater, container, false)
|
||||
Log.e("jingo", "linkFragment onCreateView ${hashCode()}")
|
||||
return binding.root
|
||||
}
|
||||
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
//右侧菜单
|
||||
binding.linkRightRecyclerview.setHasFixedSize(true)
|
||||
var rightLayoutManager = LinearLayoutManager(requireContext())
|
||||
|
||||
binding.linkRightRecyclerview.layoutManager = rightLayoutManager
|
||||
val rightAdapter = PhenomenonRightGroupHeaderAdapter { _, bean ->
|
||||
viewModel.setProblemLinkMiddleBean(bean)
|
||||
}
|
||||
binding.linkRightRecyclerview.adapter = rightAdapter
|
||||
//右侧菜单增加组标题
|
||||
binding.linkRightRecyclerview.addItemDecoration(
|
||||
PhenomenonRightGroupHeaderDecoration(
|
||||
requireContext()
|
||||
)
|
||||
)
|
||||
//右侧菜单查询数据监听
|
||||
viewModel.liveDataPhenomenonRightList.observe(viewLifecycleOwner) {
|
||||
rightAdapter.refreshData(it)
|
||||
}
|
||||
|
||||
val middleAdapter = PhenomenonMiddleAdapter { _, title ->
|
||||
rightLayoutManager.scrollToPositionWithOffset(rightAdapter.getGroupTopIndex(title), 0)
|
||||
}
|
||||
|
||||
binding.linkRightRecyclerview.addOnScrollListener(object :
|
||||
RecyclerView.OnScrollListener() {
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
super.onScrollStateChanged(recyclerView, newState)
|
||||
}
|
||||
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
val firstIndex = rightLayoutManager.findFirstVisibleItemPosition()
|
||||
middleAdapter.setRightTitle(rightAdapter.data[firstIndex].title)
|
||||
}
|
||||
})
|
||||
|
||||
//中间菜单
|
||||
binding.linkMiddleRecyclerview.setHasFixedSize(true)
|
||||
binding.linkMiddleRecyclerview.layoutManager = LinearLayoutManager(requireContext())
|
||||
binding.linkMiddleRecyclerview.adapter = middleAdapter
|
||||
//中间侧菜单查询结果监听
|
||||
viewModel.liveDataProblemTypeList.observe(viewLifecycleOwner) {
|
||||
middleAdapter.refreshData(it)
|
||||
}
|
||||
binding.linkDrawer.setOnClickListener {
|
||||
when (binding.group.visibility) {
|
||||
View.INVISIBLE, View.GONE ->
|
||||
binding.group.visibility = View.VISIBLE
|
||||
else ->
|
||||
binding.group.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.getProblemLinkList()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
Log.e("jingo", "linkFragment onDestroyView ${hashCode()}")
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.navinfo.omqs.ui.other
|
||||
|
||||
interface AdapterItemClickListener {
|
||||
fun onItemClick(position: Int)
|
||||
}
|
@ -37,27 +37,28 @@ abstract class BaseRecyclerViewAdapter<T>(var data: List<T> = listOf()) :
|
||||
return data.size
|
||||
}
|
||||
|
||||
fun refreshData(newData: List<T>) {
|
||||
this.data = newData
|
||||
this.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
|
||||
override fun onViewAttachedToWindow(holder: BaseViewHolder) {
|
||||
super.onViewAttachedToWindow(holder)
|
||||
holder.onStart()
|
||||
}
|
||||
|
||||
|
||||
override fun onViewDetachedFromWindow(holder: BaseViewHolder) {
|
||||
super.onViewDetachedFromWindow(holder)
|
||||
holder.apply {
|
||||
onStop()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
|
||||
|
||||
// this.recyclerView = recyclerView
|
||||
// super.onAttachedToRecyclerView(recyclerView)
|
||||
// this.recyclerView = recyclerView
|
||||
// override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
|
||||
open fun refreshData(newData: List<T>) {
|
||||
this.data = newData
|
||||
this.notifyDataSetChanged()
|
||||
}
|
||||
// }
|
||||
//
|
||||
// override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
|
||||
|
107
app/src/main/java/com/navinfo/omqs/ui/other/ShareViewModel.kt
Normal file
107
app/src/main/java/com/navinfo/omqs/ui/other/ShareViewModel.kt
Normal file
@ -0,0 +1,107 @@
|
||||
package com.navinfo.omqs.ui.other
|
||||
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.createViewModelLazy
|
||||
import androidx.lifecycle.*
|
||||
import androidx.lifecycle.viewmodel.CreationExtras
|
||||
|
||||
/**
|
||||
* 用来共享的viewModel
|
||||
*/
|
||||
val vMStores = HashMap<String, ViewModelStoreOwner>()
|
||||
|
||||
|
||||
@MainThread
|
||||
inline fun <reified VM : ViewModel> Fragment.shareViewModels(
|
||||
scopeName: String,
|
||||
noinline ownerProducer: () -> ViewModelStoreOwner = { this },
|
||||
noinline factoryProducer: (() -> ViewModelProvider.Factory)? = null
|
||||
): Lazy<VM> {
|
||||
val owner by lazy(LazyThreadSafetyMode.NONE) { ownerProducer() }
|
||||
|
||||
val store: ViewModelStoreOwner
|
||||
if (vMStores.keys.contains(scopeName)) {
|
||||
store = vMStores[scopeName]!!
|
||||
} else {
|
||||
vMStores[scopeName] = owner
|
||||
store = owner
|
||||
this.let { fragment ->
|
||||
fragment.lifecycle.addObserver(object : LifecycleEventObserver {
|
||||
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
|
||||
if (event == Lifecycle.Event.ON_DESTROY) {
|
||||
fragment.lifecycle.removeObserver(this)
|
||||
store.viewModelStore.clear()
|
||||
vMStores.remove(scopeName)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// store.register(this)
|
||||
|
||||
return createViewModelLazy(
|
||||
VM::class,
|
||||
{ store.viewModelStore },
|
||||
{
|
||||
(store as? HasDefaultViewModelProviderFactory)?.defaultViewModelCreationExtras
|
||||
?: CreationExtras.Empty
|
||||
},
|
||||
factoryProducer ?: {
|
||||
(store as? HasDefaultViewModelProviderFactory)?.defaultViewModelProviderFactory
|
||||
?: defaultViewModelProviderFactory
|
||||
})
|
||||
}
|
||||
|
||||
//
|
||||
//@MainThread
|
||||
//inline fun <reified VM : ViewModel> LifecycleOwner.shareViewModels(
|
||||
// scopeName: String,
|
||||
// factory: ViewModelProvider.Factory? = null
|
||||
//): Lazy<VM> {
|
||||
// val store: VMStore
|
||||
// if (vMStores.keys.contains(scopeName)) {
|
||||
// store = vMStores[scopeName]!!
|
||||
// } else {
|
||||
// store = VMStore()
|
||||
// vMStores[scopeName] = store
|
||||
// }
|
||||
// store.register(this)
|
||||
// return ViewModelLazy(VM::class,
|
||||
// { store.viewModelStore },
|
||||
// { factory ?: MyViewModelFactory() })
|
||||
//}
|
||||
|
||||
|
||||
class MyViewModelFactory(
|
||||
) : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return modelClass.getConstructor().newInstance()
|
||||
}
|
||||
}
|
||||
|
||||
class VMStore(val owner: ViewModelStoreOwner) {
|
||||
|
||||
// private val bindTargets = ArrayList<LifecycleOwner>()
|
||||
// fun register(host: LifecycleOwner) {
|
||||
// if (!bindTargets.contains(host)) {
|
||||
// bindTargets.add(host)
|
||||
// host.lifecycle.addObserver(object : LifecycleEventObserver {
|
||||
// override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
|
||||
// if (event == Lifecycle.Event.ON_DESTROY) {
|
||||
// host.lifecycle.removeObserver(this)
|
||||
// bindTargets.remove(host)
|
||||
// if (bindTargets.isEmpty()) {//如果当前商店没有关联对象,则释放资源
|
||||
// vMStores.entries.find { it.value == this@VMStore }?.also {
|
||||
// owner.viewModelStore.clear()
|
||||
// vMStores.remove(it.key)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
}
|
@ -35,13 +35,14 @@
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/login_fragment_user_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:scrollbarAlwaysDrawHorizontalTrack="true"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.4">
|
||||
|
||||
@ -54,10 +55,12 @@
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/login_fragment_user_layout">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
|
@ -5,6 +5,7 @@
|
||||
tools:context=".ui.activity.map.MainActivity">
|
||||
|
||||
<data>
|
||||
|
||||
<variable
|
||||
name="mainActivity"
|
||||
type="com.navinfo.omqs.ui.activity.map.MainActivity" />
|
||||
@ -27,8 +28,12 @@
|
||||
|
||||
<com.navinfo.collect.library.map.NIMapView
|
||||
android:id="@+id/main_activity_map"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/main_activity_person_center"
|
||||
@ -64,21 +69,40 @@
|
||||
app:layout_constraintRight_toRightOf="parent" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/main_activity_right_fragment"
|
||||
android:id="@+id/main_activity_middle_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintHorizontal_bias="0.3"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHorizontal_weight="6"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toLeftOf="@+id/main_activity_right_fragment"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navGraph="@navigation/middle_fragment_nav_graph" />
|
||||
|
||||
<fragment
|
||||
android:id="@id/main_activity_right_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintHorizontal_weight="4"
|
||||
app:layout_constraintLeft_toRightOf="@id/main_activity_middle_fragment"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navGraph="@navigation/right_fragment_nav_graph" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/main_activity_drawer_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="300dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="left"
|
||||
app:layout_constraintHorizontal_bias="0.3"
|
||||
app:navGraph="@navigation/left_drawer_nav_graph" />
|
||||
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
||||
</layout>
|
@ -45,24 +45,52 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="问题分类" />
|
||||
|
||||
<Spinner
|
||||
<TextView
|
||||
android:id="@+id/evaluation_class_type"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:background="@drawable/fm_card_map_down_status_bg" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/evaluation_class_tab_layout"
|
||||
<TextView
|
||||
android:id="@+id/evaluation_problem_type"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp" />
|
||||
android:layout_marginTop="5dp"
|
||||
android:background="@drawable/fm_card_map_down_status_bg" />
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/evaluation_viewpager"
|
||||
<TextView
|
||||
android:id="@+id/evaluation_phenomenon"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="5dp" />
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:background="@drawable/fm_card_map_down_status_bg" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/evaluation_link"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:background="@drawable/fm_card_map_down_status_bg" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/evaluation_cause"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="5dp"
|
||||
android:background="@drawable/fm_card_map_down_status_bg" />
|
||||
|
||||
<!-- <com.google.android.material.tabs.TabLayout-->
|
||||
<!-- android:id="@+id/evaluation_class_tab_layout"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="wrap_content"-->
|
||||
<!-- android:layout_marginTop="5dp" />-->
|
||||
|
||||
<!-- <androidx.viewpager2.widget.ViewPager2-->
|
||||
<!-- android:id="@+id/evaluation_viewpager"-->
|
||||
<!-- android:layout_width="match_parent"-->
|
||||
<!-- android:layout_height="match_parent"-->
|
||||
<!-- android:layout_marginTop="5dp" />-->
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
||||
|
@ -1,15 +1,67 @@
|
||||
<?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:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="right|center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="30dp"
|
||||
tools:context="com.navinfo.omqs.ui.fragment.evaluationresult.PhenomenonFragment">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/phenomenon_recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
<ImageView
|
||||
android:id="@+id/phenomenon_drawer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
android:background="@drawable/progress_bg"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingTop="30dp"
|
||||
android:paddingRight="10dp"
|
||||
android:paddingBottom="30dp"
|
||||
android:src="@drawable/btn_back_xml" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/group"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/phenomenon_title_bg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="65dp"
|
||||
android:background="@color/default_blue"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:text="问题列表"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/phenomenon_left_recyclerview"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2"
|
||||
android:background="@color/white" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/phenomenon_middle_recyclerview"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="@color/white" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/phenomenon_right_recyclerview"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="4"
|
||||
android:background="@color/white" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
60
app/src/main/res/layout/fragment_problem_link.xml
Normal file
60
app/src/main/res/layout/fragment_problem_link.xml
Normal file
@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="right|center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="100dp"
|
||||
tools:context="com.navinfo.omqs.ui.fragment.evaluationresult.ProblemLinkFragment">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/link_drawer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/progress_bg"
|
||||
android:paddingLeft="10dp"
|
||||
android:paddingTop="30dp"
|
||||
android:paddingRight="10dp"
|
||||
android:paddingBottom="30dp"
|
||||
android:src="@drawable/btn_back_xml" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/group"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/link_title_bg"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="65dp"
|
||||
android:background="@color/default_blue"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:text="问题列表"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/link_middle_recyclerview"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2"
|
||||
android:background="@color/white" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/link_right_recyclerview"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="4"
|
||||
android:background="@color/white" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
24
app/src/main/res/navigation/middle_fragment_nav_graph.xml
Normal file
24
app/src/main/res/navigation/middle_fragment_nav_graph.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation 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:id="@+id/middle_fragment_nav_graph"
|
||||
app:startDestination="@id/EmptyFragment">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/EmptyFragment"
|
||||
android:name="com.navinfo.omqs.ui.fragment.empty.EmptyFragment"
|
||||
android:label="空页面"
|
||||
tools:layout="@layout/fragment_empty"></fragment>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/PhenomenonFragment"
|
||||
android:name="com.navinfo.omqs.ui.fragment.evaluationresult.PhenomenonFragment"
|
||||
android:label="评测页面"
|
||||
tools:layout="@layout/fragment_phenomenon"></fragment>
|
||||
<fragment
|
||||
android:id="@+id/ProblemLinkFragment"
|
||||
android:name="com.navinfo.omqs.ui.fragment.evaluationresult.ProblemLinkFragment"
|
||||
android:label="评测页面"
|
||||
tools:layout="@layout/fragment_problem_link"></fragment>
|
||||
</navigation>
|
@ -63,10 +63,19 @@ android {
|
||||
dependencies {
|
||||
api fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
|
||||
api files('libs/BaiduLBS_Android.jar')
|
||||
|
||||
//
|
||||
api 'androidx.core:core-ktx:1.9.0'
|
||||
api 'androidx.appcompat:appcompat:1.6.1'
|
||||
api 'com.google.android.material:material:1.8.0'
|
||||
api 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
api 'androidx.navigation:navigation-fragment-ktx:2.5.3'
|
||||
api 'androidx.navigation:navigation-ui-ktx:2.5.3'
|
||||
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
implementation 'com.yanzhenjie:kalle:0.1.7'
|
||||
// implementation 'com.yanzhenjie:kalle:0.1.7'
|
||||
|
||||
// VTM依赖
|
||||
implementation "net.sf.kxml:kxml2:2.3.0"
|
||||
|
@ -0,0 +1,102 @@
|
||||
package com.navinfo.collect.library.data.entity
|
||||
|
||||
import com.navinfo.collect.library.utils.GeometryToolsKt
|
||||
import io.realm.RealmObject
|
||||
import io.realm.RealmSet
|
||||
import io.realm.annotations.PrimaryKey
|
||||
import io.realm.annotations.RealmClass
|
||||
|
||||
|
||||
/**
|
||||
* @author zhjch
|
||||
* @version V1.0
|
||||
* @ClassName: Rd_qcRecord
|
||||
* @Date 2016/1/12
|
||||
* @Description: ${TODO}(质检对象)
|
||||
*/
|
||||
@RealmClass
|
||||
open class QsRecordBean @JvmOverloads constructor(
|
||||
/**
|
||||
* id 主键
|
||||
*
|
||||
*/
|
||||
@PrimaryKey
|
||||
var id: String = "",
|
||||
/**
|
||||
* 关联要素id
|
||||
*/
|
||||
var elementId: String = "",
|
||||
/**
|
||||
* linkPid 绑定的道路ID
|
||||
*/
|
||||
var linkId: String = "",
|
||||
/**
|
||||
*问题分类
|
||||
*/
|
||||
var classType: String = "",
|
||||
/**
|
||||
* 问题类型
|
||||
*/
|
||||
var type: String = "",
|
||||
|
||||
/**
|
||||
* 问题现象
|
||||
*/
|
||||
var phenomenon: String = "",
|
||||
/**
|
||||
* 描述信息
|
||||
*/
|
||||
var description: String = "",
|
||||
/**
|
||||
* 问题环节
|
||||
*/
|
||||
var problemLink: String = "",
|
||||
/**
|
||||
* 问题原因
|
||||
* 根本原因(RCA)
|
||||
*/
|
||||
|
||||
var cause: String = "",
|
||||
/**
|
||||
* 质检员ID
|
||||
*/
|
||||
var checkUserId: String = "",
|
||||
/**
|
||||
* 质检日期
|
||||
*/
|
||||
var checkTime: String = "",
|
||||
/**
|
||||
* 确认人
|
||||
*/
|
||||
var confirmUserId: String = "",
|
||||
/**
|
||||
* 状态 0 无; 1 删除;2 更新;3 新增;
|
||||
*/
|
||||
|
||||
var t_lifecycle: Int = 3,
|
||||
/**
|
||||
* 问题记录提交状态 0 未提交;1 已提交;
|
||||
*/
|
||||
var t_status: Int = 0,
|
||||
/**
|
||||
* 显示坐标
|
||||
*/
|
||||
// var geometry: String = "",
|
||||
/**
|
||||
* 显示坐标
|
||||
*/
|
||||
var guideGeometry: String = "",
|
||||
|
||||
) : RealmObject() {
|
||||
|
||||
|
||||
private val tileX = RealmSet<Int>() // x方向的tile编码
|
||||
private val tileY = RealmSet<Int>() // y方向的tile编码
|
||||
var geometry: String = ""
|
||||
set(value) {
|
||||
field = value
|
||||
// 根据geometry自动计算当前要素的x-tile和y-tile
|
||||
GeometryToolsKt.getTileXByGeometry(value, tileX)
|
||||
GeometryToolsKt.getTileYByGeometry(value, tileY)
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.navinfo.collect.library.map
|
||||
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
@Parcelize
|
||||
data class GeoPoint(
|
||||
var latitude: Double = 0.0,
|
||||
var longitude: Double = 0.0
|
||||
) : Parcelable {
|
||||
fun toGeometry(): String {
|
||||
return "POINT($longitude $latitude)"
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package com.navinfo.collect.library.map
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.navinfo.collect.library.map.handler.*
|
||||
import com.navinfo.collect.library.map.maphandler.MeasureLayerHandler
|
||||
import com.navinfo.collect.library.map.handler.ViewportHandler
|
||||
@ -23,7 +24,7 @@ class NIMapController {
|
||||
lateinit var measureLayerHandler: MeasureLayerHandler
|
||||
|
||||
|
||||
fun init(context: Context, mapView: NIMapView, options: NIMapOptions? = null, mapPath: String) {
|
||||
fun init(context: AppCompatActivity, mapView: NIMapView, options: NIMapOptions? = null, mapPath: String) {
|
||||
Constant.MAP_PATH = mapPath
|
||||
layerManagerHandler = LayerManagerHandler(context, mapView)
|
||||
locationLayerHandler = LocationLayerHandler(context, mapView)
|
||||
@ -38,5 +39,6 @@ class NIMapController {
|
||||
mMapView.vtmMap.viewport().maxZoomLevel = Constant.MAX_ZOOM // 设置地图的最大级别
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ package com.navinfo.collect.library.map;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@ -15,37 +14,21 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import com.navinfo.collect.library.R;
|
||||
import com.navinfo.collect.library.map.layers.NaviMapScaleBar;
|
||||
import com.navinfo.collect.library.map.source.MapLifeDBTileSource;
|
||||
import com.navinfo.collect.library.map.source.MapLifeNiLocationTileDataSource;
|
||||
import com.navinfo.collect.library.map.source.MapLifeNiLocationTileSource;
|
||||
import com.navinfo.collect.library.system.Constant;
|
||||
|
||||
import org.oscim.android.MapPreferences;
|
||||
import org.oscim.android.MapView;
|
||||
import org.oscim.core.GeoPoint;
|
||||
import org.oscim.android.theme.AssetsRenderTheme;
|
||||
import org.oscim.core.MapPosition;
|
||||
import org.oscim.core.Tile;
|
||||
import org.oscim.event.Event;
|
||||
import org.oscim.event.Gesture;
|
||||
import org.oscim.event.GestureListener;
|
||||
import org.oscim.layers.GroupLayer;
|
||||
import org.oscim.layers.Layer;
|
||||
import org.oscim.layers.TileGridLayer;
|
||||
import org.oscim.layers.tile.buildings.BuildingLayer;
|
||||
import org.oscim.layers.tile.vector.OsmTileLayer;
|
||||
import org.oscim.layers.tile.vector.VectorTileLayer;
|
||||
import org.oscim.layers.tile.vector.labeling.LabelLayer;
|
||||
import org.oscim.layers.tile.vector.labeling.LabelTileLoaderHook;
|
||||
import org.oscim.map.Map;
|
||||
import org.oscim.renderer.GLViewport;
|
||||
import org.oscim.theme.IRenderTheme;
|
||||
import org.oscim.theme.ThemeLoader;
|
||||
import org.oscim.theme.VtmThemes;
|
||||
import org.oscim.tiling.source.mapfile.MapFileTileSource;
|
||||
import org.oscim.tiling.source.mapfile.MultiMapFileTileSource;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
/**
|
||||
@ -125,14 +108,14 @@ public final class NIMapView extends RelativeLayout {
|
||||
*
|
||||
* @param point
|
||||
*/
|
||||
void onMapClick(GeoPoint point);
|
||||
void onMapClick(com.navinfo.collect.library.map.GeoPoint point);
|
||||
|
||||
/**
|
||||
* 地图内 Poi 单击事件回调函数
|
||||
*
|
||||
* @param poi
|
||||
*/
|
||||
void onMapPoiClick(GeoPoint poi);
|
||||
// void onMapPoiClick(GeoPoint poi);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -218,10 +201,8 @@ public final class NIMapView extends RelativeLayout {
|
||||
this.mContext = context;
|
||||
|
||||
mapView = rootView.findViewById(R.id.base_map_view);
|
||||
// map = new NIMap(this);
|
||||
compassImage = rootView.findViewById(R.id.navinfo_map_compass);
|
||||
initMapGroup(); // 初始化图层组
|
||||
// mLayerManager = new NILayerManager(context, getVtmMap());
|
||||
|
||||
logoImage = rootView.findViewById(R.id.navinfo_map_logo);
|
||||
mRotateAnimation = new NIRotateAnimation(compassImage);
|
||||
@ -251,6 +232,7 @@ public final class NIMapView extends RelativeLayout {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 增加比例尺图层
|
||||
NaviMapScaleBar naviMapScaleBar = new NaviMapScaleBar(getVtmMap());
|
||||
naviMapScaleBar.initScaleBarLayer(GLViewport.Position.BOTTOM_LEFT, 25, 60);
|
||||
@ -302,6 +284,9 @@ public final class NIMapView extends RelativeLayout {
|
||||
|
||||
zoomLayout = rootView.findViewById(R.id.navinfo_map_zoom_layer);
|
||||
switchTileVectorLayerTheme(MAP_THEME.DEFAULT);
|
||||
|
||||
MapEventsReceiver mapEventReceiver = new MapEventsReceiver(mapView.map());
|
||||
getVtmMap().layers().add(mapEventReceiver);
|
||||
}
|
||||
|
||||
|
||||
@ -923,7 +908,7 @@ public final class NIMapView extends RelativeLayout {
|
||||
GeoPoint geoPoint = mMap.viewport().fromScreenPoint(e.getX(), e.getY());
|
||||
if (g instanceof Gesture.Tap) { // 单击事件
|
||||
if (mapClickListener != null) {
|
||||
mapClickListener.onMapClick(geoPoint);
|
||||
mapClickListener.onMapClick(new com.navinfo.collect.library.map.GeoPoint(geoPoint.getLatitude(), geoPoint.getLongitude()));
|
||||
}
|
||||
} else if (g instanceof Gesture.DoubleTap) { // 双击
|
||||
if (mapDoubleClickListener != null) {
|
||||
@ -934,17 +919,6 @@ public final class NIMapView extends RelativeLayout {
|
||||
mapLongClickListener.onMapLongClick(geoPoint);
|
||||
}
|
||||
}
|
||||
setOnMapClickListener(new OnMapClickListener() {
|
||||
@Override
|
||||
public void onMapClick(GeoPoint point) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapPoiClick(GeoPoint poi) {
|
||||
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -952,7 +926,7 @@ public final class NIMapView extends RelativeLayout {
|
||||
/**
|
||||
* 设置地图的点击事件
|
||||
*/
|
||||
public void setOnMapClickListener(@Nullable OnMapClickListener listener) {
|
||||
public void setOnMapClickListener(OnMapClickListener listener) {
|
||||
this.mapClickListener = listener;
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
package com.navinfo.collect.library.map.handler
|
||||
|
||||
import android.content.Context
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import org.oscim.layers.Layer
|
||||
|
||||
abstract class BaseHandler(context: Context, mapView: NIMapView) {
|
||||
protected val mContext: Context = context
|
||||
abstract class BaseHandler(context: AppCompatActivity, mapView: NIMapView) {
|
||||
protected val mContext: AppCompatActivity = context
|
||||
protected val mMapView: NIMapView = mapView
|
||||
|
||||
fun addLayer(layer: Layer, groupType: NIMapView.LAYER_GROUPS) {
|
||||
@ -19,4 +20,11 @@ abstract class BaseHandler(context: Context, mapView: NIMapView) {
|
||||
mMapView.vtmMap.layers().remove(layer)
|
||||
}
|
||||
|
||||
fun setOnMapClickListener(listener: NIMapView.OnMapClickListener) {
|
||||
mMapView.setOnMapClickListener(listener)
|
||||
}
|
||||
|
||||
fun removeOnMapClickListener() {
|
||||
mMapView.setOnMapClickListener(null)
|
||||
}
|
||||
}
|
@ -1,15 +1,21 @@
|
||||
package com.navinfo.collect.library.map.handler
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.navinfo.collect.library.data.entity.QsRecordBean
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.map.source.NavinfoMapRastorTileSource
|
||||
import com.navinfo.collect.library.map.source.NavinfoMultiMapFileTileSource
|
||||
import com.navinfo.collect.library.system.Constant
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.where
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import okhttp3.Cache
|
||||
import okhttp3.OkHttpClient
|
||||
import org.oscim.backend.CanvasAdapter
|
||||
import org.oscim.backend.canvas.Paint
|
||||
import org.oscim.layers.GroupLayer
|
||||
import org.oscim.layers.Layer
|
||||
import org.oscim.layers.tile.bitmap.BitmapTileLayer
|
||||
import org.oscim.layers.tile.buildings.BuildingLayer
|
||||
import org.oscim.layers.tile.vector.VectorTileLayer
|
||||
import org.oscim.layers.tile.vector.labeling.LabelLayer
|
||||
@ -20,11 +26,22 @@ import java.io.File
|
||||
/**
|
||||
* Layer 操作
|
||||
*/
|
||||
class LayerManagerHandler(context: Context, mapView: NIMapView) :
|
||||
class LayerManagerHandler(context: AppCompatActivity, mapView: NIMapView) :
|
||||
BaseHandler(context, mapView) {
|
||||
private var baseGroupLayer // 用于盛放所有基础底图的图层组,便于统一管理
|
||||
: GroupLayer? = null
|
||||
|
||||
/**
|
||||
* 默认文字颜色
|
||||
*/
|
||||
private val mDefaultTextColor = "#4E55AF"
|
||||
|
||||
/**
|
||||
* 文字画笔
|
||||
*/
|
||||
|
||||
private lateinit var paint: Paint
|
||||
|
||||
init {
|
||||
initMap()
|
||||
}
|
||||
@ -36,8 +53,9 @@ class LayerManagerHandler(context: Context, mapView: NIMapView) :
|
||||
|
||||
loadBaseMap()
|
||||
mMapView.switchTileVectorLayerTheme(NIMapView.MAP_THEME.DEFAULT)
|
||||
//初始化之间数据图层
|
||||
initQsRecordDataLayer()
|
||||
mMapView.vtmMap.updateMap()
|
||||
// initVectorTileLayer()
|
||||
// initMapLifeSource()
|
||||
}
|
||||
|
||||
@ -46,7 +64,7 @@ class LayerManagerHandler(context: Context, mapView: NIMapView) :
|
||||
* 切换基础底图样式
|
||||
*/
|
||||
fun loadBaseMap() {
|
||||
|
||||
//给地图layer分组
|
||||
if (baseGroupLayer == null) {
|
||||
baseGroupLayer = GroupLayer(mMapView.vtmMap)
|
||||
addLayer(baseGroupLayer!!, NIMapView.LAYER_GROUPS.BASE)
|
||||
@ -90,8 +108,11 @@ class LayerManagerHandler(context: Context, mapView: NIMapView) :
|
||||
}
|
||||
}
|
||||
baseLayer.tileSource = urlTileSource
|
||||
//增加基础路网图层
|
||||
it.layers.add(baseLayer)
|
||||
//增加建筑图层
|
||||
it.layers.add(BuildingLayer(mMapView.vtmMap, baseLayer))
|
||||
//增加文字图层
|
||||
it.layers.add(LabelLayer(mMapView.vtmMap, baseLayer))
|
||||
for (layer in it.layers) {
|
||||
addLayer(layer, NIMapView.LAYER_GROUPS.BASE)
|
||||
@ -101,26 +122,45 @@ class LayerManagerHandler(context: Context, mapView: NIMapView) :
|
||||
}
|
||||
}
|
||||
|
||||
private fun getRasterTileLayer(
|
||||
url: String?,
|
||||
tilePath: String?,
|
||||
useCache: Boolean
|
||||
): Layer {
|
||||
val builder = OkHttpClient.Builder()
|
||||
val mTileSource =
|
||||
NavinfoMapRastorTileSource.builder(url).tilePath(tilePath)
|
||||
.httpFactory(OkHttpFactory(builder)).build()
|
||||
// 如果使用缓存
|
||||
if (useCache) {
|
||||
val cacheDirectory =
|
||||
File(Constant.MAP_PATH, "cache")
|
||||
val cacheSize = 300 * 1024 * 1024 // 300 MB
|
||||
val cache = Cache(cacheDirectory, cacheSize.toLong())
|
||||
builder.cache(cache)
|
||||
}
|
||||
private fun initQsRecordDataLayer() {
|
||||
paint = CanvasAdapter.newPaint()
|
||||
paint.setTypeface(Paint.FontFamily.DEFAULT, Paint.FontStyle.NORMAL)
|
||||
paint.setTextSize(13 * CanvasAdapter.getScale())
|
||||
paint.strokeWidth = 2 * CanvasAdapter.getScale()
|
||||
paint.color = Color.parseColor(mDefaultTextColor)
|
||||
|
||||
return BitmapTileLayer(mMapView.vtmMap, mTileSource)
|
||||
mContext.lifecycleScope.launch(Dispatchers.IO) {
|
||||
|
||||
|
||||
val realm = Realm.getDefaultInstance()
|
||||
realm.executeTransaction {
|
||||
val list = realm.where<QsRecordBean>().findAll()
|
||||
paint.setColor(Color.parseColor(mDefaultTextColor))
|
||||
}
|
||||
realm.close()
|
||||
}
|
||||
}
|
||||
|
||||
// private fun getRasterTileLayer(
|
||||
// url: String?,
|
||||
// tilePath: String?,
|
||||
// useCache: Boolean
|
||||
// ): Layer {
|
||||
// val builder = OkHttpClient.Builder()
|
||||
// val mTileSource =
|
||||
// NavinfoMapRastorTileSource.builder(url).tilePath(tilePath)
|
||||
// .httpFactory(OkHttpFactory(builder)).build()
|
||||
// // 如果使用缓存
|
||||
// if (useCache) {
|
||||
// val cacheDirectory =
|
||||
// File(Constant.MAP_PATH, "cache")
|
||||
// val cacheSize = 300 * 1024 * 1024 // 300 MB
|
||||
// val cache = Cache(cacheDirectory, cacheSize.toLong())
|
||||
// builder.cache(cache)
|
||||
// }
|
||||
//
|
||||
// return BitmapTileLayer(mMapView.vtmMap, mTileSource)
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -8,6 +8,7 @@ import com.baidu.location.BDLocation
|
||||
import com.baidu.location.LocationClient
|
||||
import com.baidu.location.LocationClientOption
|
||||
import com.baidu.location.LocationClientOption.LocationMode
|
||||
import com.navinfo.collect.library.map.GeoPoint
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import org.oscim.layers.LocationLayer
|
||||
|
||||
@ -142,6 +143,13 @@ class LocationLayerHandler(context: Context, mapView: NIMapView) : BaseHandler(c
|
||||
mMapView.vtmMap.animator().animateTo(300, mapPosition)
|
||||
}
|
||||
}
|
||||
|
||||
fun getCurrentGeoPoint(): GeoPoint? {
|
||||
mCurrentLocation?.let {
|
||||
return GeoPoint(it.latitude, it.longitude)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,75 +1,101 @@
|
||||
package com.navinfo.collect.library.map.handler
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.BitmapFactory
|
||||
import com.navinfo.collect.library.R
|
||||
import com.navinfo.collect.library.map.GeoPoint
|
||||
import com.navinfo.collect.library.map.NIMapView
|
||||
import com.navinfo.collect.library.utils.StringUtil
|
||||
import org.oscim.core.GeoPoint
|
||||
import org.oscim.android.canvas.AndroidBitmap
|
||||
import org.oscim.layers.marker.ItemizedLayer
|
||||
import org.oscim.layers.marker.ItemizedLayer.OnItemGestureListener
|
||||
import org.oscim.layers.marker.MarkerInterface
|
||||
import org.oscim.layers.marker.MarkerItem
|
||||
import org.oscim.layers.marker.MarkerSymbol
|
||||
|
||||
/**
|
||||
* marker 操作
|
||||
*/
|
||||
open class MarkHandler(context: Context, mapView:NIMapView) :
|
||||
BaseHandler(context, mapView), OnItemGestureListener<MarkerInterface> {
|
||||
class MarkHandler(context: Context, mapView: NIMapView) :
|
||||
BaseHandler(context, mapView) {
|
||||
|
||||
// //增加marker
|
||||
// fun addMarker(
|
||||
// geoPoint: GeoPoint,
|
||||
// title: String?,
|
||||
// description: String? = ""
|
||||
// ): MarkerItem {
|
||||
// var marker: MarkerItem? = null
|
||||
// for (e in mMapView.layerManager.defaultMarkerLayer.itemList) {
|
||||
// if (e is MarkerItem && e.title == title) {
|
||||
// marker = e;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (marker == null) {
|
||||
// var tempTitle = title;
|
||||
// if (tempTitle.isNullOrBlank()) {
|
||||
// tempTitle = StringUtil.createUUID();
|
||||
// }
|
||||
// val marker = MarkerItem(
|
||||
// tempTitle,
|
||||
// description,
|
||||
// geoPoint
|
||||
// )
|
||||
// mMapView.layerManager.defaultMarkerLayer.addItem(marker);
|
||||
// mMapView.vtmMap.updateMap(true)
|
||||
// return marker
|
||||
// } else {
|
||||
// marker.description = description
|
||||
// marker.geoPoint = geoPoint
|
||||
// mMapView.layerManager.defaultMarkerLayer.removeItem(marker)
|
||||
// mMapView.layerManager.defaultMarkerLayer.addItem(marker)
|
||||
// mMapView.vtmMap.updateMap(true)
|
||||
// return marker
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fun removeMarker(title: String) {
|
||||
// var marker: MarkerItem? = null
|
||||
// for (e in mMapView.layerManager.defaultMarkerLayer.itemList) {
|
||||
// if (e is MarkerItem && e.title == title) {
|
||||
// marker = e;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (marker != null) {
|
||||
// mMapView.layerManager.defaultMarkerLayer.removeItem(marker)
|
||||
// mMapView.vtmMap.updateMap(true)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
override fun onItemSingleTapUp(index: Int, item: MarkerInterface): Boolean {
|
||||
return false
|
||||
// //默认marker图层
|
||||
private var mDefaultMarkerLayer: ItemizedLayer
|
||||
|
||||
init {
|
||||
//新增marker图标样式
|
||||
val mDefaultBitmap =
|
||||
AndroidBitmap(BitmapFactory.decodeResource(context.resources, R.mipmap.marker));
|
||||
|
||||
val markerSymbol = MarkerSymbol(
|
||||
mDefaultBitmap,
|
||||
MarkerSymbol.HotspotPlace.BOTTOM_CENTER
|
||||
);
|
||||
//新增marker图层
|
||||
mDefaultMarkerLayer = ItemizedLayer(
|
||||
mapView.vtmMap,
|
||||
ArrayList<MarkerInterface>(),
|
||||
markerSymbol,
|
||||
object : OnItemGestureListener<MarkerInterface> {
|
||||
override fun onItemSingleTapUp(index: Int, item: MarkerInterface?): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onItemLongPress(index: Int, item: MarkerInterface?): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
addLayer(mDefaultMarkerLayer, NIMapView.LAYER_GROUPS.OPERATE);
|
||||
}
|
||||
|
||||
override fun onItemLongPress(index: Int, item: MarkerInterface): Boolean {
|
||||
return false
|
||||
//增加marker
|
||||
fun addMarker(
|
||||
geoPoint: GeoPoint,
|
||||
title: String?,
|
||||
description: String? = ""
|
||||
) {
|
||||
var marker: MarkerItem? = null
|
||||
for (e in mDefaultMarkerLayer.itemList) {
|
||||
if (e is MarkerItem && e.title == title) {
|
||||
marker = e
|
||||
break
|
||||
}
|
||||
}
|
||||
if (marker == null) {
|
||||
var tempTitle = title;
|
||||
if (tempTitle.isNullOrBlank()) {
|
||||
tempTitle = StringUtil.createUUID();
|
||||
}
|
||||
val marker = MarkerItem(
|
||||
tempTitle,
|
||||
description,
|
||||
org.oscim.core.GeoPoint(geoPoint.latitude, geoPoint.longitude)
|
||||
)
|
||||
mDefaultMarkerLayer.addItem(marker);
|
||||
mMapView.vtmMap.updateMap(true)
|
||||
} else {
|
||||
marker.description = description
|
||||
marker.geoPoint = org.oscim.core.GeoPoint(geoPoint.latitude, geoPoint.longitude)
|
||||
mDefaultMarkerLayer.removeItem(marker)
|
||||
mDefaultMarkerLayer.addItem(marker)
|
||||
mMapView.vtmMap.updateMap(true)
|
||||
}
|
||||
}
|
||||
|
||||
fun removeMarker(title: String) {
|
||||
var marker: MarkerItem? = null
|
||||
for (e in mDefaultMarkerLayer.itemList) {
|
||||
if (e is MarkerItem && e.title == title) {
|
||||
marker = e
|
||||
break
|
||||
}
|
||||
}
|
||||
if (marker != null) {
|
||||
mDefaultMarkerLayer.removeItem(marker)
|
||||
mMapView.vtmMap.updateMap(true)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -7,7 +7,6 @@ import org.oscim.core.GeoPoint
|
||||
import org.oscim.core.Point
|
||||
|
||||
open class ViewportHandler(context: Context, mapView: NIMapView) : BaseHandler(context, mapView) {
|
||||
|
||||
/**
|
||||
* Set pivot horizontal / vertical relative to view center in [-1, 1].
|
||||
* e.g. pivotY 0.5 is usually preferred for navigation, moving center to 25% of view height.
|
||||
@ -73,7 +72,7 @@ open class ViewportHandler(context: Context, mapView: NIMapView) : BaseHandler(c
|
||||
px: Float, py: Float
|
||||
): Map<String, Any> {
|
||||
|
||||
val geo = mMapView.vtmMap.viewport().fromScreenPoint(px,py)
|
||||
val geo = mMapView.vtmMap.viewport().fromScreenPoint(px, py)
|
||||
|
||||
return mapOf(
|
||||
"latitude" to geo.latitude,
|
||||
|
Loading…
x
Reference in New Issue
Block a user