164 lines
6.1 KiB
Kotlin
164 lines
6.1 KiB
Kotlin
package com.sw.inbound.activity
|
|
|
|
import android.app.Dialog
|
|
import android.content.Context
|
|
import android.graphics.Color
|
|
import android.os.Bundle
|
|
import android.view.LayoutInflater
|
|
import android.view.ViewGroup
|
|
import android.view.WindowManager
|
|
import androidx.core.graphics.drawable.toDrawable
|
|
import androidx.lifecycle.lifecycleScope
|
|
import com.sw.inbound.base.BaseActivity
|
|
import androidx.recyclerview.widget.GridLayoutManager
|
|
import coil.load
|
|
import com.chad.library.adapter4.BaseQuickAdapter
|
|
import com.chad.library.adapter4.viewholder.QuickViewHolder
|
|
import com.sw.inbound.databinding.ActivityLocalImagePreviewBinding
|
|
import com.sw.inbound.databinding.DialogImageFullPreviewBinding
|
|
import com.sw.inbound.databinding.ListItemImagePreviewBinding
|
|
import com.sw.inbound.dialog.Loading
|
|
import kotlinx.coroutines.Dispatchers
|
|
import kotlinx.coroutines.delay
|
|
import kotlinx.coroutines.launch
|
|
import kotlinx.coroutines.withContext
|
|
import java.io.File
|
|
|
|
class LocalImagePreviewActivity : BaseActivity() {
|
|
|
|
private lateinit var binding: ActivityLocalImagePreviewBinding
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
super.onCreate(savedInstanceState)
|
|
binding = ActivityLocalImagePreviewBinding.inflate(layoutInflater)
|
|
setContentView(binding.root)
|
|
|
|
binding.recyclerView.let {
|
|
it.layoutManager = GridLayoutManager(this, 6, GridLayoutManager.VERTICAL, false)
|
|
it.adapter = imageAdapter
|
|
}
|
|
binding.btnBack.setOnClickListener { finish() }
|
|
loadData()
|
|
}
|
|
|
|
/** 从缓存 crop 目录加载所有图片文件 */
|
|
fun loadData() {
|
|
lifecycleScope.launch {
|
|
// 主线程显示加载框
|
|
Loading.show(this@LocalImagePreviewActivity)
|
|
// 切换到 IO 线程执行文件读取
|
|
withContext(Dispatchers.IO) {
|
|
val cropFile = File(this@LocalImagePreviewActivity.cacheDir, "crop")
|
|
cropFile.listFiles()?.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
|
|
}
|
|
imageList.add(ImageBean(file = it, name = displayName))
|
|
}
|
|
// 按文件名升序排列
|
|
imageList.sortBy { it.name }
|
|
}
|
|
// 回到主线程刷新列表
|
|
imageAdapter.notifyDataSetChanged()
|
|
// 延迟 500ms 后关闭加载框
|
|
delay(500)
|
|
Loading.dismiss()
|
|
}
|
|
}
|
|
|
|
/** 弹出全屏大图预览 Dialog,支持左右切换 */
|
|
private fun showFullImagePreview(startPosition: Int) {
|
|
var currentIndex = startPosition
|
|
|
|
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
|
|
)
|
|
}
|
|
|
|
/** 根据 currentIndex 刷新图片、文件名、页码及按钮状态 */
|
|
fun updateContent() {
|
|
val item = imageList[currentIndex]
|
|
dialogBinding.ivFullImage.load(item.file)
|
|
dialogBinding.tvFileName.text = item.file.name
|
|
dialogBinding.tvPageIndicator.text = "${currentIndex + 1} / ${imageList.size}"
|
|
// 到达边界时隐藏对应方向的按钮
|
|
dialogBinding.btnPrev.alpha = if (currentIndex > 0) 1f else 0.2f
|
|
dialogBinding.btnNext.alpha = if (currentIndex < imageList.size - 1) 1f else 0.2f
|
|
}
|
|
|
|
// 点击图片本身关闭弹窗
|
|
dialogBinding.ivFullImage.setOnClickListener { dialog.dismiss() }
|
|
// 关闭按钮
|
|
dialogBinding.btnClose.setOnClickListener { dialog.dismiss() }
|
|
// 上一张
|
|
dialogBinding.btnPrev.setOnClickListener {
|
|
if (currentIndex > 0) {
|
|
currentIndex--
|
|
updateContent()
|
|
}
|
|
}
|
|
// 下一张
|
|
dialogBinding.btnNext.setOnClickListener {
|
|
if (currentIndex < imageList.size - 1) {
|
|
currentIndex++
|
|
updateContent()
|
|
}
|
|
}
|
|
|
|
updateContent()
|
|
dialog.show()
|
|
}
|
|
|
|
private val imageList = mutableListOf<ImageBean>()
|
|
private val imageAdapter: ImageAdapter by lazy {
|
|
ImageAdapter(imageList).apply {
|
|
setOnItemClickListener { _, _, position ->
|
|
// 点击缩略图,弹出大图预览,传入当前索引以支持左右切换
|
|
showFullImagePreview(position)
|
|
}
|
|
}
|
|
}
|
|
|
|
data class ImageBean(
|
|
var file: File,
|
|
var name: String
|
|
)
|
|
|
|
inner class ImageAdapter(var list: MutableList<ImageBean>) :
|
|
BaseQuickAdapter<ImageBean, ImageAdapter.VH>(list) {
|
|
|
|
inner class VH(var binding: ListItemImagePreviewBinding) : QuickViewHolder(binding.root)
|
|
|
|
override fun onBindViewHolder(holder: VH, position: Int, item: ImageBean?) {
|
|
holder.binding.let {
|
|
it.imageView.load(item!!.file)
|
|
it.textView.text = item.name
|
|
}
|
|
}
|
|
|
|
override fun onCreateViewHolder(context: Context, parent: ViewGroup, viewType: Int): VH {
|
|
val inflater = LayoutInflater.from(context)
|
|
val binding = ListItemImagePreviewBinding.inflate(inflater, parent, false)
|
|
return VH(binding)
|
|
}
|
|
|
|
}
|
|
|
|
}
|