feat: 大图查看支持左右滑动切换图片
- 传入所有图片 URL 列表和起始索引 - 左滑下一张,右滑上一张 - 底部显示页码指示 1/3 - 单击关闭 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -437,18 +437,20 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
|
||||
isFocusable = true
|
||||
}
|
||||
loadImage(imageView, pic.url)
|
||||
// 点击放大全屏查看
|
||||
val picUrl = pic.url
|
||||
imageView.setOnClickListener { showFullImage(picUrl) }
|
||||
// 点击放大全屏查看(传入所有图片和当前索引)
|
||||
val idx = index
|
||||
val allUrls = pics.map { it.url }
|
||||
imageView.setOnClickListener { showFullImage(allUrls, idx) }
|
||||
binding.picContainer.addView(imageView)
|
||||
}
|
||||
}
|
||||
|
||||
/** 全屏显示大图(覆盖在 Activity 窗口顶层,点击关闭) */
|
||||
private fun showFullImage(url: String) {
|
||||
Timber.d("查看大图: $url")
|
||||
// 使用 Activity 的 decorView 确保在最顶层
|
||||
/** 全屏查看大图(左右滑切换,点击关闭) */
|
||||
private fun showFullImage(urls: List<String>, startIndex: Int) {
|
||||
Timber.d("查看大图: index=$startIndex, total=${urls.size}")
|
||||
val rootView = requireActivity().window.decorView as ViewGroup
|
||||
var currentIndex = startIndex
|
||||
|
||||
val overlay = FrameLayout(requireContext()).apply {
|
||||
layoutParams = ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
@@ -458,6 +460,7 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
|
||||
isClickable = true
|
||||
isFocusable = true
|
||||
}
|
||||
|
||||
val imageView = android.widget.ImageView(requireContext()).apply {
|
||||
layoutParams = FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.MATCH_PARENT,
|
||||
@@ -465,13 +468,54 @@ class TaskListFragment : BaseFragment<FragmentTaskListBinding>() {
|
||||
)
|
||||
scaleType = android.widget.ImageView.ScaleType.FIT_CENTER
|
||||
}
|
||||
|
||||
// 页码指示(多张图片时显示)
|
||||
val tvIndicator = android.widget.TextView(requireContext()).apply {
|
||||
layoutParams = FrameLayout.LayoutParams(
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||
FrameLayout.LayoutParams.WRAP_CONTENT
|
||||
).apply {
|
||||
gravity = android.view.Gravity.BOTTOM or android.view.Gravity.CENTER_HORIZONTAL
|
||||
bottomMargin = (20 * resources.displayMetrics.density).toInt()
|
||||
}
|
||||
setTextColor(0xCCFFFFFF.toInt())
|
||||
textSize = 18f
|
||||
visibility = if (urls.size > 1) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
overlay.addView(imageView)
|
||||
overlay.addView(tvIndicator)
|
||||
rootView.addView(overlay)
|
||||
// 点击任意位置关闭
|
||||
overlay.setOnClickListener { rootView.removeView(overlay) }
|
||||
imageView.setOnClickListener { rootView.removeView(overlay) }
|
||||
// 加载大图
|
||||
loadImage(imageView, url)
|
||||
|
||||
// 显示当前图片
|
||||
fun showAt(index: Int) {
|
||||
currentIndex = index
|
||||
tvIndicator.text = "${index + 1}/${urls.size}"
|
||||
loadImage(imageView, urls[index])
|
||||
}
|
||||
showAt(startIndex)
|
||||
|
||||
// 手势:左右滑切换,点击关闭
|
||||
val detector = GestureDetector(requireContext(), object : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
|
||||
rootView.removeView(overlay)
|
||||
return true
|
||||
}
|
||||
override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
|
||||
if (e1 == null) return false
|
||||
val dx = e2.x - e1.x
|
||||
if (kotlin.math.abs(dx) > 50) {
|
||||
if (dx < 0 && currentIndex < urls.size - 1) {
|
||||
showAt(currentIndex + 1) // 左滑下一张
|
||||
} else if (dx > 0 && currentIndex > 0) {
|
||||
showAt(currentIndex - 1) // 右滑上一张
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
overlay.setOnTouchListener { _, event -> detector.onTouchEvent(event); true }
|
||||
}
|
||||
|
||||
/** 异步加载图片到 ImageView(使用系统 HttpURLConnection) */
|
||||
|
||||
Reference in New Issue
Block a user