Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in / Register
Toggle navigation
H
HFile Manager Master
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wanglei
HFile Manager Master
Commits
aa4eb488
Commit
aa4eb488
authored
Mar 14, 2024
by
wanglei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
重复图片数据比对和UI展示
parent
edd06204
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
231 additions
and
53 deletions
+231
-53
DupImageData.kt
...ain/java/com/zxhy/hfilemanagermaster/data/DupImageData.kt
+2
-3
DupImageAdapter.kt
.../com/zxhy/hfilemanagermaster/duplicate/DupImageAdapter.kt
+72
-4
DupPictureActivity.kt
...m/zxhy/hfilemanagermaster/duplicate/DupPictureActivity.kt
+20
-5
ImageAdapter.kt
...in/java/com/zxhy/hfilemanagermaster/files/ImageAdapter.kt
+2
-9
DupImageEx.kt
...main/java/com/zxhy/hfilemanagermaster/knife/DupImageEx.kt
+26
-3
xmlEx.kt
app/src/main/java/com/zxhy/hfilemanagermaster/knife/xmlEx.kt
+15
-0
LagerFileSelectorAdapter.kt
.../hfilemanagermaster/largefile/LagerFileSelectorAdapter.kt
+1
-9
LargeImageSelectorAdapter.kt
...hfilemanagermaster/largefile/LargeImageSelectorAdapter.kt
+1
-9
LargeVideoSelectorAdapter.kt
...hfilemanagermaster/largefile/LargeVideoSelectorAdapter.kt
+1
-9
activity_dup_picture.xml
app/src/main/res/layout/activity_dup_picture.xml
+4
-2
item_dup_image_select.xml
app/src/main/res/layout/item_dup_image_select.xml
+54
-0
item_image_select_2.xml
app/src/main/res/layout/item_image_select_2.xml
+33
-0
No files found.
app/src/main/java/com/zxhy/hfilemanagermaster/data/DupImageData.kt
View file @
aa4eb488
...
...
@@ -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
app/src/main/java/com/zxhy/hfilemanagermaster/duplicate/DupImageAdapter.kt
View file @
aa4eb488
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
app/src/main/java/com/zxhy/hfilemanagermaster/duplicate/DupPictureActivity.kt
View file @
aa4eb488
...
...
@@ -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
)
}
}
}
...
...
app/src/main/java/com/zxhy/hfilemanagermaster/files/ImageAdapter.kt
View file @
aa4eb488
...
...
@@ -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
>)
{
...
...
app/src/main/java/com/zxhy/hfilemanagermaster/knife/DupImageEx.kt
View file @
aa4eb488
...
...
@@ -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 ==
1
0) {
// if (list.size ==
3
0) {
// 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
app/src/main/java/com/zxhy/hfilemanagermaster/knife/xmlEx.kt
0 → 100644
View file @
aa4eb488
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
)
}
app/src/main/java/com/zxhy/hfilemanagermaster/largefile/LagerFileSelectorAdapter.kt
View file @
aa4eb488
...
...
@@ -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
{
...
...
app/src/main/java/com/zxhy/hfilemanagermaster/largefile/LargeImageSelectorAdapter.kt
View file @
aa4eb488
...
...
@@ -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
>)
{
...
...
app/src/main/java/com/zxhy/hfilemanagermaster/largefile/LargeVideoSelectorAdapter.kt
View file @
aa4eb488
...
...
@@ -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
>)
{
...
...
app/src/main/res/layout/activity_dup_picture.xml
View file @
aa4eb488
...
...
@@ -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"
...
...
app/src/main/res/layout/item_dup_image_select.xml
0 → 100644
View file @
aa4eb488
<?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
app/src/main/res/layout/item_image_select_2.xml
0 → 100644
View file @
aa4eb488
<?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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment