feat: 任务切换加滑动动画 + 严格手势防误触
1. 手势判断从 dx>dy 改为 dx>dy*2 且 dx>80px,斜滑不再误触 2. 切换任务时内容滑出+滑入动画(120ms出+150ms入),有明确感知 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -92,19 +92,17 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
|
|||||||
findNavController().popBackStack()
|
findNavController().popBackStack()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 左右滑手势(切换任务),上下滑留给内容滚动
|
// 左右滑手势(切换任务),严格区分水平/垂直防误触
|
||||||
gestureDetector = GestureDetector(requireContext(), object : GestureDetector.SimpleOnGestureListener() {
|
gestureDetector = GestureDetector(requireContext(), object : GestureDetector.SimpleOnGestureListener() {
|
||||||
override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
|
override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
|
||||||
if (e1 == null) return false
|
if (e1 == null) return false
|
||||||
val dy = e2.y - e1.y
|
val dy = e2.y - e1.y
|
||||||
val dx = e2.x - e1.x
|
val dx = e2.x - e1.x
|
||||||
// 水平滑动且幅度 > 垂直
|
// 水平幅度必须 > 垂直的 2 倍,且 > 80px,防止斜滑误触
|
||||||
if (abs(dx) > abs(dy) && abs(dx) > 50) {
|
if (abs(dx) > abs(dy) * 2 && abs(dx) > 80) {
|
||||||
if (dx < 0) {
|
if (dx < 0) {
|
||||||
// 左滑 → 下一个任务
|
|
||||||
nextTask()
|
nextTask()
|
||||||
} else {
|
} else {
|
||||||
// 右滑 → 上一个任务
|
|
||||||
prevTask()
|
prevTask()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -212,22 +210,46 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
|
|||||||
|
|
||||||
// ===== 左右滑切换 =====
|
// ===== 左右滑切换 =====
|
||||||
|
|
||||||
/** 下一个任务(左滑) */
|
/** 下一个任务(左滑,内容从右滑入) */
|
||||||
private fun nextTask() {
|
private fun nextTask() {
|
||||||
if (taskIndex < taskList.size - 1) {
|
if (taskIndex < taskList.size - 1) {
|
||||||
taskIndex++
|
taskIndex++
|
||||||
fetchCurrentDetail()
|
animateSwitch(fromRight = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 上一个任务(右滑) */
|
/** 上一个任务(右滑,内容从左滑入) */
|
||||||
private fun prevTask() {
|
private fun prevTask() {
|
||||||
if (taskIndex > 0) {
|
if (taskIndex > 0) {
|
||||||
taskIndex--
|
taskIndex--
|
||||||
fetchCurrentDetail()
|
animateSwitch(fromRight = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 切换任务时的滑入动画 */
|
||||||
|
private fun animateSwitch(fromRight: Boolean) {
|
||||||
|
val content = binding.scrollView
|
||||||
|
val screenWidth = content.width.toFloat()
|
||||||
|
// 旧内容滑出
|
||||||
|
val slideOut = if (fromRight) -screenWidth else screenWidth
|
||||||
|
content.animate()
|
||||||
|
.translationX(slideOut)
|
||||||
|
.alpha(0f)
|
||||||
|
.setDuration(120)
|
||||||
|
.withEndAction {
|
||||||
|
// 加载新数据
|
||||||
|
fetchCurrentDetail()
|
||||||
|
// 新内容从另一边滑入
|
||||||
|
content.translationX = if (fromRight) screenWidth else -screenWidth
|
||||||
|
content.animate()
|
||||||
|
.translationX(0f)
|
||||||
|
.alpha(1f)
|
||||||
|
.setDuration(150)
|
||||||
|
.start()
|
||||||
|
}
|
||||||
|
.start()
|
||||||
|
}
|
||||||
|
|
||||||
// ===== UI 显示 =====
|
// ===== UI 显示 =====
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user