feat(activity): 新增本地图片预览功能及大图查看入口

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 14:22:38 +08:00
co-authored by Claude Sonnet 4.6
parent 8a6a6dfa2d
commit 301b91581b
4 changed files with 119 additions and 14 deletions
@@ -210,6 +210,11 @@ class FoodCollectionActivity : BaseActivity() {
loadEmptyView() loadEmptyView()
// 点击"图片"按钮,跳转至本地图片预览页
binding.tvImagePreview.setOnClickListener {
startActivity<LocalImagePreviewActivity> { }
}
binding.tvTitle.setOnClickListener { binding.tvTitle.setOnClickListener {
// startActivity<LocalImagePreviewActivity> { } // startActivity<LocalImagePreviewActivity> { }
@@ -1,18 +1,22 @@
package com.sw.inbound.activity package com.sw.inbound.activity
import android.app.Dialog
import android.content.Context import android.content.Context
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import android.view.WindowManager
import androidx.core.graphics.drawable.toDrawable
import com.sw.inbound.base.BaseActivity import com.sw.inbound.base.BaseActivity
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import coil.load import coil.load
import com.chad.library.adapter4.BaseQuickAdapter import com.chad.library.adapter4.BaseQuickAdapter
import com.chad.library.adapter4.viewholder.QuickViewHolder import com.chad.library.adapter4.viewholder.QuickViewHolder
import com.sw.inbound.databinding.ActivityLocalImagePreviewBinding import com.sw.inbound.databinding.ActivityLocalImagePreviewBinding
import com.sw.inbound.databinding.DialogImageFullPreviewBinding
import com.sw.inbound.databinding.ListItemImagePreviewBinding import com.sw.inbound.databinding.ListItemImagePreviewBinding
import com.sw.inbound.dialog.Loading import com.sw.inbound.dialog.Loading
import com.sw.inbound.utils.ext.copyText
import java.io.File import java.io.File
class LocalImagePreviewActivity : BaseActivity() { class LocalImagePreviewActivity : BaseActivity() {
@@ -32,7 +36,7 @@ class LocalImagePreviewActivity : BaseActivity() {
loadData() loadData()
} }
/** 从缓存 crop 目录加载所有图片文件 */
fun loadData() { fun loadData() {
Thread { Thread {
runOnUiThread { runOnUiThread {
@@ -40,17 +44,21 @@ class LocalImagePreviewActivity : BaseActivity() {
} }
val cropFile = File(this.cacheDir, "crop") val cropFile = File(this.cacheDir, "crop")
cropFile.listFiles()?.forEach { cropFile.listFiles()?.forEach {
if (it.isDirectory) { // 跳过子目录,只处理文件
return@forEach if (it.isDirectory) return@forEach
// 跳过非 jpg 图片
if (!it.name.endsWith(".jpg", ignoreCase = true)) return@forEach
val nameWithoutExt = it.nameWithoutExtension
// 兼容 IMG_CROP_{时间戳} 和其他命名格式
val displayName = if (nameWithoutExt.startsWith("IMG_CROP_")) {
nameWithoutExt.removePrefix("IMG_CROP_")
} else {
nameWithoutExt
} }
val start = "IMG_CROP_".length imageList.add(ImageBean(file = it, name = displayName))
val end = it.name.indexOf(".jpg")
val time = it.name.substring(start, end).toLong()
if (time >= 1764086400L) {
imageList.add(ImageBean(file = it, name = "$time"))
} }
} // 按文件名升序排列
imageList.sortBy { it.name.toLong() } imageList.sortBy { it.name }
runOnUiThread { runOnUiThread {
imageAdapter.notifyDataSetChanged() imageAdapter.notifyDataSetChanged()
Loading.dismiss() Loading.dismiss()
@@ -58,13 +66,39 @@ class LocalImagePreviewActivity : BaseActivity() {
}.start() }.start()
} }
private var isCycle = true /** 弹出全屏大图预览 Dialog */
private fun showFullImagePreview(item: ImageBean) {
val dialogBinding = DialogImageFullPreviewBinding.inflate(layoutInflater)
val dialog = Dialog(this, android.R.style.Theme_Black_NoTitleBar_Fullscreen)
dialog.setContentView(dialogBinding.root)
dialog.setCancelable(true)
dialog.setCanceledOnTouchOutside(true)
dialog.window?.apply {
setBackgroundDrawable(Color.TRANSPARENT.toDrawable())
setLayout(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT
)
}
// 加载大图
dialogBinding.ivFullImage.load(item.file)
// 显示文件名
dialogBinding.tvFileName.text = item.file.name
// 点击关闭按钮关闭弹窗
dialogBinding.btnClose.setOnClickListener { dialog.dismiss() }
// 点击图片本身也关闭弹窗
dialogBinding.ivFullImage.setOnClickListener { dialog.dismiss() }
dialog.show()
}
private val imageList = mutableListOf<ImageBean>() private val imageList = mutableListOf<ImageBean>()
private val imageAdapter: ImageAdapter by lazy { private val imageAdapter: ImageAdapter by lazy {
ImageAdapter(imageList).apply { ImageAdapter(imageList).apply {
setOnItemClickListener { _, _, position -> setOnItemClickListener { _, _, position ->
imageList[position].name.copyText(this@LocalImagePreviewActivity) // 点击缩略图,弹出大图预览
showFullImagePreview(imageList[position])
} }
} }
} }
@@ -20,6 +20,19 @@
android:textColor="#141428" android:textColor="#141428"
android:textSize="36sp" android:textSize="36sp"
android:textStyle="bold" /> android:textStyle="bold" />
<TextView
android:id="@+id/tvImagePreview"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical|end"
android:layout_marginEnd="40dp"
android:gravity="center_vertical"
android:paddingHorizontal="20dp"
android:text="图片"
android:textColor="#141428"
android:textSize="32sp"
android:textStyle="bold" />
</FrameLayout> </FrameLayout>
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CC000000">
<ImageView
android:id="@+id/ivFullImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="120dp"
android:scaleType="fitCenter" />
<!-- 底部工具栏:显示文件名 + 关闭按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_gravity="bottom"
android:background="#99000000"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingHorizontal="30dp">
<TextView
android:id="@+id/tvFileName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="middle"
android:maxLines="1"
android:textColor="#FFFFFFFF"
android:textSize="26sp" />
<FrameLayout
android:id="@+id/btnClose"
android:layout_width="200dp"
android:layout_height="80dp"
android:background="@drawable/bg_blue_ripple">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="关闭"
android:textColor="@color/white"
android:textSize="30sp"
android:textStyle="bold" />
</FrameLayout>
</LinearLayout>
</FrameLayout>