Commit aa4eb488 authored by wanglei's avatar wanglei

重复图片数据比对和UI展示

parent edd06204
......@@ -8,7 +8,6 @@ import android.net.Uri
* 重复图片数据
*/
data class DupImageData(
val name: String = "Image",
val path: String = "",
val Uri: Uri = android.net.Uri.EMPTY,
val dupList: List<MediaDataC>,
var select: Boolean = false,
)
\ No newline at end of file
package com.zxhy.hfilemanagermaster.duplicate
import android.annotation.SuppressLint
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.ItemDupImageSelectBinding
import com.example.hfilemanagermaster.databinding.ItemImageSelect2Binding
import com.zxhy.hfilemanagermaster.data.DupImageData
import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import com.zxhy.hfilemanagermaster.knife.inflate
class DupImageAdapter : RecyclerView.Adapter<DupImageAdapter.DupImageVideHolder>() {
class DupImageVideHolder(view: View) : RecyclerView.ViewHolder(view) {}
private val dupImageList = arrayListOf<DupImageData>()
class DupImageVideHolder(view: View) : RecyclerView.ViewHolder(view) {
val binding = ItemDupImageSelectBinding.bind(view)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DupImageVideHolder {
TODO("Not yet implemented")
val root = R.layout.item_dup_image_select.inflate(parent)
return DupImageVideHolder(root)
}
override fun getItemCount(): Int {
TODO("Not yet implemented")
return dupImageList.size
}
@SuppressLint("SetTextI18n")
override fun onBindViewHolder(holder: DupImageVideHolder, position: Int) {
TODO("Not yet implemented")
val context = holder.binding.root.context
val data = dupImageList[position]
holder.binding.apply {
ivSelector.isSelected = data.select
tvNum.text = "${data.dupList.size} items"
val adapter = DupImageItemAdapter()
rvDup.adapter = adapter
adapter.setData(data.dupList)
}
}
@SuppressLint("NotifyDataSetChanged")
fun setData(data: List<DupImageData>) {
dupImageList.clear()
dupImageList.addAll(data)
notifyDataSetChanged()
}
}
private class DupImageItemAdapter :
RecyclerView.Adapter<DupImageItemAdapter.DupImageItemViewHolder>() {
private val mediaList = arrayListOf<MediaDataC>()
class DupImageItemViewHolder(view: View) : ViewHolder(view) {
val binding = ItemImageSelect2Binding.bind(view)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DupImageItemViewHolder {
val root = R.layout.item_image_select_2.inflate(parent)
return DupImageItemViewHolder(root)
}
override fun getItemCount(): Int {
return mediaList.size
}
override fun onBindViewHolder(holder: DupImageItemViewHolder, position: Int) {
val context = holder.binding.root.context
val data = mediaList[position]
holder.binding.apply {
loadIntoImageView(context, data.uri, ivImage)
ivSelector.isSelected = data.select
}
}
@SuppressLint("NotifyDataSetChanged")
fun setData(data: List<MediaDataC>) {
mediaList.clear()
mediaList.addAll(data)
notifyDataSetChanged()
}
}
\ No newline at end of file
......@@ -9,12 +9,15 @@ import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.ActivityDupPictureBinding
import com.zxhy.hfilemanagermaster.data.DupImageData
import com.zxhy.hfilemanagermaster.knife.dupImage
import com.zxhy.hfilemanagermaster.knife.getDupImageList
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class DupPictureActivity : AppCompatActivity() {
private lateinit var binding: ActivityDupPictureBinding
private lateinit var adapter: DupImageAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
......@@ -30,12 +33,24 @@ class DupPictureActivity : AppCompatActivity() {
finish()
}
binding.tvDelete.setOnClickListener {
lifecycleScope.launch(Dispatchers.IO) {
val list = dupImage()
println(list)
lifecycleScope.launch(Dispatchers.Main) {
}
}
adapter = DupImageAdapter()
binding.rv.adapter = adapter
loadData()
}
private fun loadData() {
lifecycleScope.launch(Dispatchers.IO) {
val list = dupImage()
val dupDataList = arrayListOf<DupImageData>()
val dupList = getDupImageList(list)
dupList.forEach {
dupDataList.add(DupImageData(dupList = it))
}
lifecycleScope.launch(Dispatchers.Main) {
adapter.setData(dupDataList)
}
}
}
......
......@@ -8,6 +8,7 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.ItemImageBinding
import com.zxhy.hfilemanagermaster.knife.inflate
class ImageAdapter : RecyclerView.Adapter<ImageAdapter.ImageViewHolder>() {
......@@ -32,15 +33,7 @@ class ImageAdapter : RecyclerView.Adapter<ImageAdapter.ImageViewHolder>() {
holder.binding.iv.setImageURI(data)
}
/**
* 解析xml布局
*
* @param parent 父布局
* @param attachToRoot 是否依附到父布局
*/
fun Int.inflate(parent: ViewGroup, attachToRoot: Boolean = false): View {
return LayoutInflater.from(parent.context).inflate(this, parent, attachToRoot)
}
@SuppressLint("NotifyDataSetChanged")
fun setData(data: List<Uri>) {
......
......@@ -7,6 +7,8 @@ import android.database.Cursor
import android.provider.MediaStore
import com.zxhy.hfilemanagermaster.data.MediaDataC
import java.io.File
import java.text.SimpleDateFormat
import java.util.Locale
fun Context.dupImage(): ArrayList<MediaDataC> {
val list = arrayListOf<MediaDataC>()
......@@ -14,10 +16,13 @@ fun Context.dupImage(): ArrayList<MediaDataC> {
// 查询照片的Uri和字段
val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
val projection = arrayOf(MediaStore.Images.Media._ID, MediaStore.Images.Media.DISPLAY_NAME)
//DESC 降列
//ASC 升序
val sortOrder = MediaStore.Images.ImageColumns._ID + " DESC"
try {
// 执行查询
val contentResolver: ContentResolver = contentResolver
cursor = contentResolver.query(uri, projection, null, null, null)
cursor = contentResolver.query(uri, projection, null, null, sortOrder)
// 遍历结果
if (cursor != null && cursor.moveToFirst()) {
......@@ -31,11 +36,13 @@ fun Context.dupImage(): ArrayList<MediaDataC> {
val photoUri = ContentUris.withAppendedId(uri, id)
val filePath = getFilePathByUri(this, photoUri) ?: ""
val md5 = File(filePath).digestMd5().byteArrayToHexString()
val time = File(filePath).lastModified()
val timeE = SimpleDateFormat("MMM dd, yyyy", Locale.ENGLISH).format(time)
// println(photoUri)
list.add(MediaDataC(uri = photoUri, path = filePath, md5 = md5))
list.add(MediaDataC(uri = photoUri, path = filePath, time = timeE, md5 = md5))
// 在此处进行照片的操作,例如显示、复制、删除等
// ...
// if (list.size == 10) {
// if (list.size == 30) {
// break
// }
} while (cursor.moveToNext())
......@@ -48,4 +55,20 @@ fun Context.dupImage(): ArrayList<MediaDataC> {
cursor?.close()
}
return list
}
//获取重复图片
fun getDupImageList(list: List<MediaDataC>): List<List<MediaDataC>> {
val dupList = arrayListOf<List<MediaDataC>>()
val origList = list.toMutableList()
list.forEach { data ->
val dup = origList.filter { it.md5 == data.md5 }
if (dup.size > 1) {
dupList.add(dup)
origList.removeAll(dup)
}
}
return dupList
}
\ No newline at end of file
package com.zxhy.hfilemanagermaster.knife
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
/**
* 解析xml布局
*
* @param parent 父布局
* @param attachToRoot 是否依附到父布局
*/
fun Int.inflate(parent: ViewGroup, attachToRoot: Boolean = false): View {
return LayoutInflater.from(parent.context).inflate(this, parent, attachToRoot)
}
......@@ -9,6 +9,7 @@ import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.ItemMediaSelectBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import com.zxhy.hfilemanagermaster.knife.inflate
class LagerFileSelectorAdapter(
private val selectAction: ((flag: Boolean) -> Unit)? = null
......@@ -90,15 +91,6 @@ class LagerFileSelectorAdapter(
notifyDataSetChanged()
}
/**
* 解析xml布局
*
* @param parent 父布局
* @param attachToRoot 是否依附到父布局
*/
fun Int.inflate(parent: ViewGroup, attachToRoot: Boolean = false): View {
return LayoutInflater.from(parent.context).inflate(this, parent, attachToRoot)
}
@SuppressLint("NotifyDataSetChanged")
fun setToggleSelect(): Boolean {
......
......@@ -9,6 +9,7 @@ import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.ItemImageSelectBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import com.zxhy.hfilemanagermaster.knife.inflate
class LargeImageSelectorAdapter(
private val selectAction: ((flag: Boolean) -> Unit)? = null
......@@ -75,15 +76,6 @@ class LargeImageSelectorAdapter(
}
}
/**
* 解析xml布局
*
* @param parent 父布局
* @param attachToRoot 是否依附到父布局
*/
fun Int.inflate(parent: ViewGroup, attachToRoot: Boolean = false): View {
return LayoutInflater.from(parent.context).inflate(this, parent, attachToRoot)
}
@SuppressLint("NotifyDataSetChanged")
fun setData(data: List<MediaDataC>) {
......
......@@ -9,6 +9,7 @@ import com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.ItemVideoSelectBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.glide.loadIntoImageView
import com.zxhy.hfilemanagermaster.knife.inflate
class LargeVideoSelectorAdapter(
private val selectAction: ((flag: Boolean) -> Unit)? = null
......@@ -71,15 +72,6 @@ class LargeVideoSelectorAdapter(
}
/**
* 解析xml布局
*
* @param parent 父布局
* @param attachToRoot 是否依附到父布局
*/
fun Int.inflate(parent: ViewGroup, attachToRoot: Boolean = false): View {
return LayoutInflater.from(parent.context).inflate(this, parent, attachToRoot)
}
@SuppressLint("NotifyDataSetChanged")
fun setData(data: List<MediaDataC>) {
......
......@@ -24,7 +24,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="RtlHardcoded" />
tools:ignore="ContentDescription,RtlHardcoded" />
<TextView
android:layout_width="wrap_content"
......@@ -60,14 +60,16 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toLeftOf="@id/tv_all"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="RtlHardcoded" />
tools:ignore="ContentDescription,RtlHardcoded" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
tools:listitem="@layout/item_dup_image_select"
android:layout_width="0dp"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="16dp"
app:layout_constraintBottom_toTopOf="@id/tv_delete"
......
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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="115dp"
android:layout_marginHorizontal="16dp"
android:layout_marginVertical="12dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginTop="8dp"
android:text="2 items"
android:textColor="#333333"
android:textSize="15sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText,RtlHardcoded" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_dup"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="2dp"
android:orientation="horizontal"
android:paddingHorizontal="6dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_num"
tools:listitem="@layout/item_image_select_2" />
<ImageView
android:id="@+id/iv_selector"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_margin="8dp"
android:src="@drawable/bg_media_selector"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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="70dp"
android:layout_height="70dp"
android:layout_margin="6dp"
app:cardCornerRadius="8dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="ContentDescription" />
<ImageView
android:src="@drawable/bg_circle_selector_c2f300"
android:id="@+id/iv_selector"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_marginHorizontal="2dp"
android:layout_marginVertical="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment