Merge branch 'master' of gitlab.navinfo.com:CollectVehicle/OneMapQS

This commit is contained in:
squallzhjch 2023-07-07 13:55:31 +08:00
commit ae44b848e2
17 changed files with 721 additions and 163 deletions

View File

@ -9,6 +9,7 @@ import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.db.ImportOMDBHelper
import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.tools.FileManager.Companion.FileDownloadStatus
import com.navinfo.omqs.util.DateTimeUtil
import io.realm.Realm
import kotlinx.coroutines.*
import java.io.File
@ -94,6 +95,8 @@ class TaskDownloadScope(
if (taskBean.status != status || status == FileDownloadStatus.LOADING || status == FileDownloadStatus.IMPORTING) {
taskBean.status = status
taskBean.message = message
//赋值时间,用于查询过滤
taskBean.operationTime = DateTimeUtil.getNowDate().time
downloadData.postValue(taskBean)
if (status != FileDownloadStatus.LOADING && status != FileDownloadStatus.IMPORTING) {
val realm = Realm.getDefaultInstance()

View File

@ -13,6 +13,7 @@ import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.bean.SysUserBean
import com.navinfo.omqs.http.DefaultResponse
import com.navinfo.omqs.tools.FileManager.Companion.FileUploadStatus
import com.navinfo.omqs.util.DateTimeUtil
import io.realm.Realm
import kotlinx.coroutines.*
import java.util.*
@ -72,6 +73,8 @@ class TaskUploadScope(
if (taskBean.syncStatus != status) {
taskBean.syncStatus = status
taskBean.errMsg = message
//赋值时间,用于查询过滤
taskBean.operationTime = DateTimeUtil.getNowDate().time
uploadData.postValue(taskBean)
//同步中不进行状态记录,只做界面变更显示
if(status!=FileUploadStatus.UPLOADING){
@ -134,11 +137,6 @@ class TaskUploadScope(
problemType = 2
}
var evaluationWay = 2
/* if(it.evaluationWay=="生产测评"){
evaluationWay = "1"
}else if(it.evaluationWay=="现场测评"){
evaluationWay = "2"
}*/
val evaluationInfo = EvaluationInfo(
evaluationTaskId = taskBean.id.toString(),
linkPid = hadLinkDvoBean.linkPid,//"84207223282277331"

View File

@ -28,6 +28,7 @@ class FileManager {
const val ERROR = 2 //错误
const val WAITING = 3 //等待中
const val UPLOADING = 4 //同步中
const val NOUPLOAD = 5 //无能上传
}
//初始化数据文件夹

View File

@ -2,9 +2,13 @@ package com.navinfo.omqs.ui.fragment
import android.os.Bundle
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import com.google.android.material.R
import com.google.android.material.dialog.MaterialAlertDialogBuilder
abstract class BaseFragment : Fragment() {
private var loadingDialog: AlertDialog? = null
// override fun onCreateView(
// inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
// ): View {
@ -49,4 +53,21 @@ abstract class BaseFragment : Fragment() {
return true
}
/**
* 显示loading dialog
*/
fun showLoadingDialog(message: String) {
loadingDialog?.dismiss()
loadingDialog = MaterialAlertDialogBuilder(
this.requireContext(), R.style.MaterialAlertDialog_Material3_Animation).setMessage(message).setCancelable(false).show()
}
/**
* 隐藏loading dialog
* */
fun hideLoadingDialog() {
loadingDialog?.dismiss()
loadingDialog = null
}
}

View File

@ -143,7 +143,6 @@ class PersonalCenterFragment(private var backListener: (() -> Unit?)? = null) :
viewModel.liveDataMessage.observe(viewLifecycleOwner) {
ToastUtils.showShort(it)
}
fileChooser.setCallbacks(this@PersonalCenterFragment)
}

View File

@ -1,5 +1,7 @@
package com.navinfo.omqs.ui.fragment.tasklist
import android.annotation.SuppressLint
import android.app.Dialog
import android.graphics.Color
import android.util.Log
import android.view.LayoutInflater
@ -7,15 +9,25 @@ import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView
import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.R
import com.navinfo.omqs.databinding.AdapterTaskListBinding
import com.navinfo.omqs.http.taskdownload.TaskDownloadManager
import com.navinfo.omqs.http.taskupload.TaskUploadManager
import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.tools.FileManager.Companion.FileDownloadStatus
import com.navinfo.omqs.tools.FileManager.Companion.FileUploadStatus
import com.navinfo.omqs.ui.dialog.FirstDialog
import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter
import com.navinfo.omqs.ui.other.BaseViewHolder
import com.navinfo.omqs.ui.widget.LeftDeleteView
import io.realm.Realm
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
/**
* 离线地图城市列表 RecyclerView 适配器
@ -28,10 +40,17 @@ import com.navinfo.omqs.ui.other.BaseViewHolder
class TaskListAdapter(
private val downloadManager: TaskDownloadManager,
private val uploadManager: TaskUploadManager,
private var itemListener: ((Int, TaskBean) -> Unit?)? = null
private val recyclerView: RecyclerView,
private var itemListener: ((Int, Int, TaskBean) -> Unit?)? = null,
) : BaseRecyclerViewAdapter<TaskBean>() {
private var selectPosition = -1
private var leftDeleteView: LeftDeleteView? = null
private val mRecyclerView = recyclerView
private var isShowDeleteView = false
private
val downloadBtnClick = View.OnClickListener() {
if (it.tag != null) {
@ -50,29 +69,55 @@ class TaskListAdapter(
}
}
} else {
Toast.makeText(downloadManager.context, "数据错误无Link信息无法执行下载", Toast.LENGTH_LONG).show()
Toast.makeText(
downloadManager.context,
"数据错误无Link信息无法执行下载",
Toast.LENGTH_LONG
).show()
}
}
}
private val uploadBtnClick = View.OnClickListener() {
if (it.tag != null) {
val taskBean = data[it.tag as Int]
if (taskBean.hadLinkDvoList.isNotEmpty()) {
when (taskBean.syncStatus) {
FileUploadStatus.NONE, FileUploadStatus.UPLOADING, FileUploadStatus.ERROR, FileUploadStatus.WAITING -> {
uploadManager.start(taskBean.id)
}
}
}else{
Toast.makeText(uploadManager.context, "数据错误无Link信息无法执行同步", Toast.LENGTH_LONG).show()
itemListener?.invoke(it.tag as Int, ItemClickStatus.UPLOAD_LAYOUT_CLICK, taskBean)
} else {
Toast.makeText(
uploadManager.context,
"数据错误无Link信息无法执行同步",
Toast.LENGTH_LONG
).show()
}
}
}
/**
* 重置item状态
* @param point
*/
fun uploadTask(taskBean: TaskBean) {
when (taskBean.syncStatus) {
FileManager.Companion.FileUploadStatus.NONE, FileManager.Companion.FileUploadStatus.UPLOADING, FileManager.Companion.FileUploadStatus.ERROR, FileManager.Companion.FileUploadStatus.WAITING -> {
uploadManager.start(taskBean.id)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder {
val viewBinding =
AdapterTaskListBinding.inflate(LayoutInflater.from(parent.context), parent, false)
val deleteView = viewBinding.root
deleteView.setRecyclerView(mRecyclerView)
return BaseViewHolder(viewBinding)
}
@ -82,10 +127,25 @@ class TaskListAdapter(
downloadManager.removeObserver(holder.tag.toInt())
}
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
override fun onBindViewHolder(
holder: BaseViewHolder,
@SuppressLint("RecyclerView") position: Int
) {
val binding: AdapterTaskListBinding =
holder.viewBinding as AdapterTaskListBinding
val taskBean = data[position]
binding.root.mStatusChangeLister = {
isShowDeleteView = it
if (it) {
//重置以后滑动布局
restoreItemView()
// 如果编辑菜单在显示
leftDeleteView = binding.root
selectPosition = position
} else {
selectPosition = -1
}
}
//tag 方便onclick里拿到数据
holder.tag = taskBean.id.toString()
changeViews(binding, taskBean)
@ -122,18 +182,40 @@ class TaskListAdapter(
binding.taskCityName.text = taskBean.cityName
binding.taskDataVersion.text = "版本号:${taskBean.dataVersion}"
binding.root.isSelected = selectPosition == position
binding.root.setOnClickListener {
val pos = holder.adapterPosition
if (selectPosition != pos) {
val lastPos = selectPosition
selectPosition = pos
if (lastPos > -1) {
notifyItemChanged(lastPos)
}
binding.root.isSelected = true
itemListener?.invoke(position, taskBean)
}
binding.taskItemLayout.setOnClickListener {
if (isShowDeleteView) {
leftDeleteView?.resetDeleteStatus()
} else {
val pos = holder.adapterPosition
if (selectPosition != pos) {
val lastPos = selectPosition
selectPosition = pos
if (lastPos > -1) {
notifyItemChanged(lastPos)
}
binding.root.isSelected = true
itemListener?.invoke(position, ItemClickStatus.ITEM_LAYOUT_CLICK, taskBean)
}
}
}
binding.taskDeleteLayout.setOnClickListener {
//重置状态
leftDeleteView?.resetDeleteStatus()
itemListener?.invoke(position, ItemClickStatus.DELETE_LAYOUT_CLICK, taskBean)
}
}
/**
* 重置item状态
* @param point
*/
fun restoreItemView() {
leftDeleteView?.let {
if (isShowDeleteView)
it.resetDeleteStatus()
}
}
@ -271,7 +353,8 @@ class TaskListAdapter(
}
val errMsg = taskBean.errMsg
if (errMsg != null && errMsg.isNotEmpty()) {
Toast.makeText(binding.taskProgressText.context, errMsg, Toast.LENGTH_LONG).show()
Toast.makeText(binding.taskProgressText.context, errMsg, Toast.LENGTH_LONG)
.show()
}
}
@ -282,6 +365,14 @@ class TaskListAdapter(
}
}
}
companion object {
object ItemClickStatus {
const val ITEM_LAYOUT_CLICK = 0 //条目点击
const val DELETE_LAYOUT_CLICK = 1 //删除点击
const val UPLOAD_LAYOUT_CLICK = 2 //上传点击
}
}
}

View File

@ -1,5 +1,7 @@
package com.navinfo.omqs.ui.fragment.tasklist
import android.app.Dialog
import android.os.Build
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
@ -7,15 +9,26 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.recyclerview.widget.LinearLayoutManager
import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.omqs.databinding.FragmentTaskListBinding
import com.navinfo.omqs.http.taskdownload.TaskDownloadManager
import com.navinfo.omqs.http.taskupload.TaskUploadManager
import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.ui.dialog.FirstDialog
import com.navinfo.omqs.ui.fragment.BaseFragment
import com.navinfo.omqs.ui.other.shareViewModels
import dagger.hilt.android.AndroidEntryPoint
import io.realm.Realm
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import javax.inject.Inject
@RequiresApi(Build.VERSION_CODES.M)
@AndroidEntryPoint
class TaskListFragment : BaseFragment() {
@ -31,14 +44,25 @@ class TaskListFragment : BaseFragment() {
*/
private val viewModel by shareViewModels<TaskViewModel>("Task")
private val binding get() = _binding!!
private val adapter: TaskListAdapter by lazy {
TaskListAdapter(
downloadManager, uploadManager
) { _, taskBean ->
downloadManager, uploadManager,binding.taskListRecyclerview
) { _, status, taskBean ->
if(taskBean.hadLinkDvoList.isEmpty()){
Toast.makeText(context, "数据错误无Link数据", Toast.LENGTH_SHORT).show()
}
viewModel.setSelectTaskBean(taskBean)
if(status==TaskListAdapter.Companion.ItemClickStatus.ITEM_LAYOUT_CLICK){
viewModel.setSelectTaskBean(taskBean as TaskBean)
}else if(status==TaskListAdapter.Companion.ItemClickStatus.DELETE_LAYOUT_CLICK){
context?.let { viewModel.removeTask(it, taskBean as TaskBean) }
}else if(status==TaskListAdapter.Companion.ItemClickStatus.UPLOAD_LAYOUT_CLICK){
showLoadingDialog("正在校验")
Toast.makeText(context, "正在校验", Toast.LENGTH_SHORT).show()
viewModel.checkUploadTask(binding.root.context,taskBean)
} else {
}
}
}
@ -64,6 +88,16 @@ class TaskListFragment : BaseFragment() {
adapter.refreshData(it)
}
//监听并调用上传
viewModel.liveDataTaskUpload.observe(viewLifecycleOwner){
for ((key, value) in it) {
if(value){
adapter.uploadTask(key)
}
}
hideLoadingDialog()
}
binding.taskListSearch.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}

View File

@ -1,5 +1,6 @@
package com.navinfo.omqs.ui.fragment.tasklist
import android.app.Dialog
import android.content.Context
import android.graphics.Color
import android.os.Build
@ -9,6 +10,7 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.navinfo.collect.library.data.entity.HadLinkDvoBean
import com.navinfo.collect.library.data.entity.QsRecordBean
import com.navinfo.collect.library.data.entity.TaskBean
import com.navinfo.collect.library.map.NIMapController
import com.navinfo.collect.library.utils.GeometryTools
@ -16,11 +18,12 @@ import com.navinfo.omqs.Constant
import com.navinfo.omqs.http.NetResult
import com.navinfo.omqs.http.NetworkService
import com.navinfo.omqs.tools.FileManager
import com.navinfo.omqs.ui.dialog.FirstDialog
import com.navinfo.omqs.util.DateTimeUtil
import dagger.hilt.android.lifecycle.HiltViewModel
import io.realm.Realm
import kotlinx.coroutines.*
import javax.inject.Inject
import kotlin.math.max
@HiltViewModel
@ -37,6 +40,12 @@ class TaskViewModel @Inject constructor(
* 用来更新当前任务
*/
val liveDataTaskLinks = MutableLiveData<List<HadLinkDvoBean>>()
/**
* 用来更新数据是否可以上传
*/
val liveDataTaskUpload = MutableLiveData<Map<TaskBean, Boolean>>()
private val colors =
arrayOf(Color.RED, Color.YELLOW, Color.BLUE, Color.MAGENTA, Color.GREEN, Color.CYAN)
@ -74,21 +83,15 @@ class TaskViewModel @Inject constructor(
task.fileSize = item.fileSize
task.status = item.status
task.currentSize = item.currentSize
// task.color = item.color
//已上传后不在更新操作时间
if (task.syncStatus != FileManager.Companion.FileUploadStatus.DONE) {
//赋值时间,用于查询过滤
task.operationTime = DateTimeUtil.getNowDate().time
}
} else {
//赋值时间,用于查询过滤
task.operationTime = DateTimeUtil.getNowDate().time
}
// else {
// if (index < 6)
// task.color = colors[index]
// else {
// val random = Random()
// task.color = Color.argb(
// 255,
// random.nextInt(256),
// random.nextInt(256),
// random.nextInt(256)
// )
// }
// }
realm.copyToRealmOrUpdate(task)
}
}
@ -114,29 +117,19 @@ class TaskViewModel @Inject constructor(
is NetResult.Loading -> {}
}
val realm = Realm.getDefaultInstance()
val objects = realm.where(TaskBean::class.java).findAll()
//过滤掉已上传的超过90天的数据
var nowTime: Long = DateTimeUtil.getNowDate().time
var beginNowTime: Long = nowTime - 90 * 3600 * 24 * 1000L
var syncUpload: Int = FileManager.Companion.FileUploadStatus.DONE
val objects =
realm.where(TaskBean::class.java).notEqualTo("syncStatus", syncUpload).or()
.between("operationTime", beginNowTime, nowTime)
.equalTo("syncStatus", syncUpload).findAll()
taskList = realm.copyFromRealm(objects)
for (item in taskList) {
FileManager.checkOMDBFileInfo(item)
}
// niMapController.lineHandler.omdbTaskLinkLayer.setLineColor(
// Color.rgb(0, 255, 0).toColor()
// )
// taskList.forEach {
// niMapController.lineHandler.omdbTaskLinkLayer.addLineList(it.hadLinkDvoList)
// }
// niMapController.lineHandler.omdbTaskLinkLayer.update()
liveDataTaskList.postValue(taskList)
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// mapController.lineHandler.omdbTaskLinkLayer.removeAll()
// if(taskList.isNotEmpty()){
// mapController.lineHandler.omdbTaskLinkLayer.addLineList(item.hadLinkDvoList)
// }
// for (item in taskList) {
// mapController.lineHandler.omdbTaskLinkLayer.setLineColor(Color.valueOf(item.color))
//
// }
// }
}
}
@ -262,4 +255,90 @@ class TaskViewModel @Inject constructor(
liveDataTaskLinks.postValue(list)
}
}
fun removeTask(context: Context, taskBean: TaskBean) {
if (taskBean != null) {
val mDialog = FirstDialog(context)
mDialog.setTitle("提示?")
mDialog.setMessage("是否关闭,请确认!")
mDialog.setPositiveButton("确定", object : FirstDialog.OnClickListener {
override fun onClick(dialog: Dialog?, which: Int) {
mDialog.dismiss()
viewModelScope.launch(Dispatchers.IO) {
val realm = Realm.getDefaultInstance()
realm.executeTransaction {
val objects = it.where(TaskBean::class.java)
.equalTo("id", taskBean.id).findFirst()
objects?.deleteFromRealm()
}
//遍历删除对应的数据
taskBean.hadLinkDvoList.forEach { hadLinkDvoBean ->
val qsRecordList = realm.where(QsRecordBean::class.java)
.equalTo("linkId", hadLinkDvoBean.linkPid).findAll()
if (qsRecordList != null && qsRecordList.size > 0) {
val copyList = realm.copyFromRealm(qsRecordList)
copyList.forEach {
it.deleteFromRealm()
mapController.markerHandle.removeQsRecordMark(it)
mapController.mMapView.vtmMap.updateMap(true)
}
}
}
//过滤掉已上传的超过90天的数据
var nowTime: Long = DateTimeUtil.getNowDate().time
var beginNowTime: Long = nowTime - 90 * 3600 * 24 * 1000L
var syncUpload: Int = FileManager.Companion.FileUploadStatus.DONE
val objects = realm.where(TaskBean::class.java)
.notEqualTo("syncStatus", syncUpload).or()
.between("operationTime", beginNowTime, nowTime)
.equalTo("syncStatus", syncUpload).findAll()
val taskList = realm.copyFromRealm(objects)
for (item in taskList) {
FileManager.checkOMDBFileInfo(item)
}
liveDataTaskList.postValue(taskList)
}
}
})
mDialog.setNegativeButton("取消", null)
mDialog.show()
}
}
fun checkUploadTask(context: Context, taskBean: TaskBean) {
viewModelScope.launch(Dispatchers.IO) {
val realm = Realm.getDefaultInstance()
taskBean.hadLinkDvoList.forEach { hadLinkDvoBean ->
val objects = realm.where(QsRecordBean::class.java)
.equalTo("linkId", hadLinkDvoBean.linkPid).findAll()
val map: MutableMap<TaskBean, Boolean> = HashMap<TaskBean, Boolean>()
if (objects.isEmpty() && hadLinkDvoBean.reason.isEmpty()) {
withContext(Dispatchers.Main) {
liveDataTaskUpload.postValue(map)
val mDialog = FirstDialog(context)
mDialog.setTitle("提示?")
mDialog.setMessage("此任务中存在未测评link请确认")
mDialog.setPositiveButton(
"确定",
object : FirstDialog.OnClickListener {
override fun onClick(dialog: Dialog?, which: Int) {
mDialog.dismiss()
map[taskBean] = true
liveDataTaskUpload.postValue(map)
}
})
mDialog.setNegativeButton("取消", object : FirstDialog.OnClickListener {
override fun onClick(dialog: Dialog?, which: Int) {
mDialog.dismiss()
}
})
mDialog.show()
}
return@launch
}
map[taskBean] = true
liveDataTaskUpload.postValue(map)
}
}
}
}

View File

@ -0,0 +1,291 @@
package com.navinfo.omqs.ui.widget
import android.animation.ValueAnimator
import android.animation.ValueAnimator.AnimatorUpdateListener
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.*
import android.widget.LinearLayout
import androidx.recyclerview.widget.RecyclerView
import com.navinfo.omqs.R
import kotlin.math.abs
/**
* Description:左滑删除按钮
*
* Time:2021/7/1-20:37
* Author:我叫PlusPlus
*/
class LeftDeleteView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : LinearLayout(context, attrs, defStyleAttr) {
/**
* 上下文
*/
private val mContext = context
/**
* 最小触摸距离
*/
private var mMinTouchDistance : Int = 0
/**
* 右边可滑动距离
*/
private var mRightCanDistance :Int = 0
/**
* 按下时 x
*/
private var mInitX : Float = 0f
/**
* 按下y
*/
private var mInitY : Float = 0f
/**
* 属性动画
*/
private var mValueAnimator: ValueAnimator? = null
/**
* 动画时长
*/
private var mAnimDuring = 300
/**
* RecyclerView
*/
private var mRecyclerView: RecyclerView? = null
/**
* 是否重新计算
*/
private var needResetCompute = true
/**
* 状态监听
*/
var mStatusChangeLister : ((Boolean)-> Unit) ? = null
init {
//通过自定义属性获取删除按钮的宽度
val array = mContext.obtainStyledAttributes(attrs, R.styleable.LeftDeleteView)
val delWidth = array.getFloat(R.styleable.LeftDeleteView_deleteBtnWidth, 0f)
array.recycle()
mMinTouchDistance = ViewConfiguration.get(mContext).scaledTouchSlop
//将dp转成PX
val var2: Float = mContext.resources.displayMetrics.density
//计算向右可以滑动的距离单位PX
mRightCanDistance = (delWidth * var2 + 0.5f).toInt()
setBackgroundColor(Color.TRANSPARENT)
orientation = HORIZONTAL
}
/**
* 设置RecyclerView
*/
fun setRecyclerView(recyclerView: RecyclerView) {
mRecyclerView = recyclerView
}
/**
* 处理触摸事件
*/
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
val actionMasked = ev.actionMasked
when (actionMasked) {
MotionEvent.ACTION_DOWN -> {
mInitX = ev.rawX + scrollX
mInitY = ev.rawY
clearAnim()
}
MotionEvent.ACTION_MOVE -> {
if (mInitX - ev.rawX < 0) {
// mRecyclerView拦截
mRecyclerView?.let {
if (needResetCompute) {
it.requestDisallowInterceptTouchEvent(false)
needResetCompute = false
}
}
return false
}
// y轴方向上达到滑动最小距离, x 轴未达到
if (abs(ev.rawY - mInitY) >= mMinTouchDistance
&& abs(ev.rawY - mInitY) > abs(mInitX - ev.rawX - scrollX)) {
// mRecyclerView拦截
mRecyclerView?.let {
if (needResetCompute) {
it.requestDisallowInterceptTouchEvent(false)
needResetCompute = false
}
}
return false
}
// x轴方向达到了最小滑动距离y轴未达到
if (abs(mInitX - ev.rawX - scrollX) >= mMinTouchDistance
&& abs(ev.rawY - mInitY) <= abs(mInitX - ev.rawX - scrollX)) {
// mRecyclerView拦截
mRecyclerView?.let {
if (needResetCompute) {
it.requestDisallowInterceptTouchEvent(false)
needResetCompute = false
}
}
return true
}
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
mRecyclerView?.let {
it.requestDisallowInterceptTouchEvent(false)
needResetCompute = true
}
}
else -> {
}
}
return super.onInterceptTouchEvent(ev)
}
/**
* 处理触摸事件
* 需要注意:何时处理左滑何时不处理
*/
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(ev: MotionEvent): Boolean {
when (ev.actionMasked) {
MotionEvent.ACTION_DOWN -> {
mInitX = ev.rawX + scrollX
mInitY = ev.rawY
clearAnim()
}
MotionEvent.ACTION_MOVE -> {
if (mInitX - ev.rawX < 0) {
// 让父级容器拦截
mRecyclerView?.let {
if (needResetCompute) {
it.requestDisallowInterceptTouchEvent(false)
needResetCompute = false
}
}
}
// y轴方向上达到滑动最小距离, x 轴未达到
if (abs(ev.rawY - mInitY) >= mMinTouchDistance
&& abs(ev.rawY - mInitY) > abs(mInitX - ev.rawX - scrollX)) {
// mRecyclerView拦截
mRecyclerView?.let {
if (needResetCompute) {
it.requestDisallowInterceptTouchEvent(false)
needResetCompute = false
}
}
}
// x轴方向达到了最小滑动距离y轴未达到
if (abs(mInitX - ev.rawX - scrollX) >= mMinTouchDistance
&& abs(ev.rawY - mInitY) <= abs(mInitX - ev.rawX - scrollX)) {
// mRecyclerView拦截
mRecyclerView?.let {
if (needResetCompute) {
it.requestDisallowInterceptTouchEvent(false)
needResetCompute = false
}
}
}
//手指移动距离超过最小距离
var translationX = mInitX - ev.rawX
//滑动距离已经大于右边可伸缩的距离后, 重新设置
if (translationX > mRightCanDistance) {
mInitX = ev.rawX + mRightCanDistance
}
//互动距离小于0那么重新设置初始位置
if (translationX < 0) {
mInitX = ev.rawX
}
translationX = if (translationX > mRightCanDistance) mRightCanDistance.toFloat() else translationX
translationX = if (translationX < 0) 0f else translationX
// 向左滑动
if (translationX <= mRightCanDistance && translationX >= 0) {
scrollTo(translationX.toInt(), 0)
return true
}
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
mRecyclerView?.let {
it.requestDisallowInterceptTouchEvent(false)
needResetCompute = true
}
upFingerAnim()
return true
}
else -> {
}
}
return true
}
/**
* 清理动画
*/
private fun clearAnim() {
mValueAnimator?.let {
it.end()
it.cancel()
mValueAnimator = null
}
}
/**
* 手指抬起开始执行动画
*/
private fun upFingerAnim() {
val scrollX = scrollX
if (scrollX == mRightCanDistance || scrollX == 0) {
//回调显示状态
mStatusChangeLister?.invoke(scrollX == mRightCanDistance)
return
}
clearAnim()
// 如果显出一半松开手指,那么自动完全显示。否则完全隐藏
if (scrollX >= mRightCanDistance / 2) {
mValueAnimator = ValueAnimator.ofInt(scrollX, mRightCanDistance)
//进行滑动
mValueAnimator?.addUpdateListener { animation ->
val value = animation.animatedValue as Int
scrollTo(value, 0)
}
mValueAnimator?.duration = mAnimDuring.toLong()
mValueAnimator?.start()
//回调显示的状态
mStatusChangeLister?.invoke(true)
} else {
mValueAnimator = ValueAnimator.ofInt(scrollX, 0)
//进行滑动
mValueAnimator?.addUpdateListener { animation ->
val value = animation.animatedValue as Int
scrollTo(value, 0)
}
mValueAnimator?.duration = mAnimDuring.toLong()
mValueAnimator?.start()
//回调关闭的状态
mStatusChangeLister?.invoke(false)
}
}
/**
* 重置按钮删除状态
*/
fun resetDeleteStatus() {
val scrollX = scrollX
if (scrollX == 0) {
return
}
clearAnim()
mValueAnimator = ValueAnimator.ofInt(scrollX, 0)
//进行滑动
mValueAnimator?.addUpdateListener(AnimatorUpdateListener { animation ->
val value = animation.animatedValue as Int
scrollTo(value, 0)
})
mValueAnimator?.duration = mAnimDuring.toLong()
mValueAnimator?.start()
//回调关闭的状态
mStatusChangeLister?.invoke(false)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

View File

@ -1,107 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<com.navinfo.omqs.ui.widget.LeftDeleteView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/selector_adapter_item_select_bg"
android:paddingLeft="8dp"
android:paddingTop="6dp"
android:paddingRight="8dp"
android:paddingBottom="8dp"
tools:context="com.navinfo.omqs.ui.fragment.tasklist.TaskListAdapter">
tools:context="com.navinfo.omqs.ui.fragment.tasklist.TaskListAdapter"
app:deleteBtnWidth="64"
android:layout_height="wrap_content"
android:layout_width="match_parent">
<ImageView
android:id="@+id/task_list_head"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_alignTop="@id/task_name"
android:layout_marginLeft="6dp"
android:layout_marginTop="2dp"
android:layout_marginRight="6dp"
android:background="@drawable/selector_task_head" />
<TextView
android:id="@+id/task_name"
<RelativeLayout
android:id="@+id/task_item_layout"
android:paddingLeft="8dp"
android:paddingTop="6dp"
android:paddingRight="8dp"
android:paddingBottom="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/task_list_head"
android:text="任务名称"
android:textColor="#15141F"
android:textSize="14sp" />
android:layout_height="match_parent">
<ImageView
android:id="@+id/task_list_head"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_alignTop="@id/task_name"
android:layout_marginLeft="6dp"
android:layout_marginTop="2dp"
android:layout_marginRight="6dp"
android:background="@drawable/selector_task_head" />
<TextView
android:id="@+id/task_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/task_list_head"
android:text="任务名称"
android:textColor="#15141F"
android:textSize="14sp" />
<TextView
android:id="@+id/task_data_version"
style="@style/map_size_font_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/task_name"
android:layout_alignLeft="@id/task_name"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:text="版本号"
android:textColor="@color/gray_121"
android:textSize="13sp" />
<TextView
android:id="@+id/task_data_version"
style="@style/map_size_font_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/task_name"
android:layout_alignLeft="@id/task_name"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:text="版本号"
android:textColor="@color/gray_121"
android:textSize="13sp" />
<TextView
android:id="@+id/task_city_name"
style="@style/map_size_font_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/task_data_version"
android:layout_alignLeft="@id/task_name"
android:text="省市名称"
android:textColor="@color/gray_121"
android:textSize="13sp" />
<TextView
android:id="@+id/task_city_name"
style="@style/map_size_font_style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/task_data_version"
android:layout_alignLeft="@id/task_name"
android:text="省市名称"
android:textColor="@color/gray_121"
android:textSize="13sp" />
<com.navinfo.omqs.ui.widget.TextProgressButtonBar
android:id="@+id/task_download_btn"
android:layout_width="75dp"
android:layout_height="22dp"
android:layout_alignBottom="@id/task_city_name"
android:layout_alignParentRight="true"
android:layout_gravity="center"
android:layout_marginTop="5dp"
app:backgroundcolor="#888FB3"
app:text="下载"
app:textSize="@dimen/card_title_font_2size"
app:textcolor="@color/white" />
<com.navinfo.omqs.ui.widget.TextProgressButtonBar
android:id="@+id/task_download_btn"
android:layout_width="75dp"
android:layout_height="22dp"
android:layout_alignBottom="@id/task_city_name"
android:layout_alignParentRight="true"
android:layout_gravity="center"
android:layout_marginTop="5dp"
app:backgroundcolor="#888FB3"
app:text="下载"
app:textSize="@dimen/card_title_font_2size"
app:textcolor="@color/white" />
<com.navinfo.omqs.ui.widget.TextProgressButtonBar
android:id="@+id/task_upload_btn"
android:layout_width="75dp"
android:layout_height="22dp"
android:layout_alignBottom="@id/task_city_name"
android:layout_alignParentRight="true"
android:layout_gravity="center"
android:layout_marginTop="5dp"
android:visibility="gone"
app:backgroundcolor="#888FB3"
app:text="未上传"
app:textSize="@dimen/card_title_font_2size"
app:textcolor="@color/white" />
<com.navinfo.omqs.ui.widget.TextProgressButtonBar
android:id="@+id/task_upload_btn"
android:layout_width="75dp"
android:layout_height="22dp"
android:layout_alignBottom="@id/task_city_name"
android:layout_alignParentRight="true"
android:layout_gravity="center"
android:layout_marginTop="5dp"
android:visibility="gone"
app:backgroundcolor="#888FB3"
app:text="未上传"
app:textSize="@dimen/card_title_font_2size"
app:textcolor="@color/white" />
<TextView
android:id="@+id/task_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginBottom="10dp"
android:layout_toLeftOf="@id/task_download_btn"
android:clickable="true"
android:focusable="false"
android:shadowColor="@android:color/transparent"
android:textColor="@color/white"
android:textSize="@dimen/card_title_font_2size" />
<TextView
android:id="@+id/task_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginBottom="10dp"
android:layout_toLeftOf="@id/task_download_btn"
android:clickable="true"
android:focusable="false"
android:shadowColor="@android:color/transparent"
android:textColor="@color/white"
android:textSize="@dimen/card_title_font_2size" />
<TextView
android:id="@+id/task_progress_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/task_download_btn"
android:layout_alignBottom="@id/task_download_btn"
android:layout_toLeftOf="@id/task_download_btn"
android:gravity="center"
android:visibility="invisible" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/task_delete_layout"
android:background="@color/red"
android:layout_width="64dp"
android:layout_height="match_parent">
<TextView
android:layout_centerVertical="true"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusable="false"
android:enabled="false"
android:text="关闭"
android:textColor="#15141F"
android:textSize="@dimen/left_pannel_title_font" />
</RelativeLayout>
</com.navinfo.omqs.ui.widget.LeftDeleteView>
<TextView
android:id="@+id/task_progress_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@id/task_download_btn"
android:layout_alignBottom="@id/task_download_btn"
android:layout_toLeftOf="@id/task_download_btn"
android:gravity="center"
android:visibility="invisible" />
</RelativeLayout>

View File

@ -31,8 +31,7 @@
android:paddingRight="@dimen/eight"
android:paddingTop="@dimen/eight"
android:text="title"
android:textColor="@color/black"
android:textSize="@dimen/card_title_font_2size" />
android:textColor="@color/black" />
<View
android:id="@+id/title_divider"
@ -82,7 +81,7 @@
android:paddingTop="@dimen/twenty"
android:text="提示内容"
android:textColor="@color/black"
android:textSize="@dimen/card_title_font_3size" />
android:textSize="@dimen/card_title_font_2size" />
</RelativeLayout>

View File

@ -29,6 +29,10 @@
<item
android:icon="@drawable/ic_baseline_sim_card_download_24"
android:title="备份数据" />
<item
android:id="@+id/personal_center_menu_version"
android:icon="@drawable/ic_baseline_layers_24"
android:title="版本ONE_QE_V1.1.0_20230630_A" />
</group>
<group android:checkableBehavior="single">
<item android:title="小标题">

View File

@ -9,4 +9,10 @@
<attr name="textSize" format="dimension" />
<attr name="text" format="string" />
</declare-styleable>
//自定义删除按钮的宽度
<declare-styleable name="LeftDeleteView">
<attr name="deleteBtnWidth" format="float"/>
</declare-styleable>
</resources>

View File

@ -55,6 +55,11 @@ open class TaskBean @JvmOverloads constructor(
*/
var status: Int = 0,
/**
* 操作时间
*/
var operationTime: Long = 0L,
/**
* 上传状态
*/
@ -69,5 +74,4 @@ open class TaskBean @JvmOverloads constructor(
fun getDownLoadUrl(): String {
return "${Constant.SERVER_ADDRESS}devcp/downFile?fileStr=$id"
}
}

2
vtm

@ -1 +1 @@
Subproject commit 1ee201a41f78f169873848209a3f3bdac36f185a
Subproject commit dd13e533c38b5738ab404c2737d7ccadeff01323