Skip to content

Commit 618d8b8

Browse files
author
Majid Arabi
committed
Merge remote-tracking branch 'origin/dev'
2 parents 21bf5af + c21a1fc commit 618d8b8

File tree

17 files changed

+143
-83
lines changed

17 files changed

+143
-83
lines changed

app/src/main/java/ir/one_developer/filepickerlibrary/MainActivity.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import android.os.Bundle
44
import androidx.appcompat.app.AppCompatActivity
55
import androidx.core.content.ContextCompat
66
import com.github.file_picker.FileType
7-
import com.github.file_picker.adapter.ItemAdapter
7+
import com.github.file_picker.adapter.FilePickerAdapter
88
import com.github.file_picker.extension.showFilePicker
99
import com.github.file_picker.listener.OnItemClickListener
1010
import com.github.file_picker.listener.OnSubmitClickListener
@@ -16,10 +16,11 @@ class MainActivity : AppCompatActivity() {
1616
private lateinit var adapter: FileAdapter
1717
private val selectedFiles = arrayListOf<Media>()
1818
private lateinit var binding: ActivityMainBinding
19-
19+
2020
private var fileType: FileType = FileType.IMAGE
2121
private var accentColor: Int = R.color.purple_500
2222
private var spanCount: Int = 2
23+
private var limit: Int = 2
2324

2425
override fun onCreate(savedInstanceState: Bundle?) {
2526
super.onCreate(savedInstanceState)
@@ -38,16 +39,19 @@ class MainActivity : AppCompatActivity() {
3839
fileType = when (i) {
3940
1 -> {
4041
spanCount = 2
42+
limit = 7
4143
accentColor = R.color.purple_500
4244
FileType.IMAGE
4345
}
4446
2 -> {
4547
spanCount = 2
48+
limit = 3
4649
accentColor = R.color.pink_500
4750
FileType.VIDEO
4851
}
4952
3 -> {
5053
spanCount = 3
54+
limit = 1
5155
accentColor = R.color.blue_500
5256
FileType.AUDIO
5357
}
@@ -58,7 +62,7 @@ class MainActivity : AppCompatActivity() {
5862

5963
private fun showFiles(): Unit = showFilePicker(
6064
fileType = fileType,
61-
limitItemSelection = 2,
65+
limitItemSelection = limit,
6266
gridSpanCount = spanCount,
6367
selectedFiles = selectedFiles,
6468
accentColor = ContextCompat.getColor(this@MainActivity, accentColor),
@@ -70,7 +74,7 @@ class MainActivity : AppCompatActivity() {
7074
}
7175
},
7276
onItemClickListener = object : OnItemClickListener {
73-
override fun onClick(media: Media, position: Int, adapter: ItemAdapter) {
77+
override fun onClick(media: Media, position: Int, adapter: FilePickerAdapter) {
7478
if (!media.file.isDirectory) {
7579
adapter.setSelected(position)
7680
}

file-picker/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ afterEvaluate {
5858
from components.release
5959
groupId = 'com.github.majidarabi'
6060
artifactId = 'file-picker'
61-
version = '0.0.8'
61+
version = '0.0.9'
6262
}
6363
}
6464
}

file-picker/src/main/java/com/github/file_picker/FilePicker.kt

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class FilePicker private constructor(
4848
private val binding get() = _binding!!
4949
private var _binding: FilePickerBinding? = null
5050

51-
private var itemAdapter: ItemAdapter? = null
51+
private var itemsAdapter: ItemAdapter? = null
5252

5353
private var title: String
5454
private var titleTextColor by Delegates.notNull<Int>()
@@ -331,15 +331,14 @@ class FilePicker private constructor(
331331
changeSubmitButtonState()
332332
setupRecyclerView(rvFiles)
333333
setFixedSubmitButton()
334-
showSelectedCount()
334+
updateSelectedCount()
335335

336336
cardLine.setCardBackgroundColor(ColorStateList.valueOf(accentColor))
337337
progress.indeterminateTintList = ColorStateList.valueOf(accentColor)
338338
tvTitle.apply {
339339
text = title
340340
setTextColor(titleTextColor)
341341
}
342-
343342
btnSubmit.apply {
344343
text = submitText
345344
setOnClickListener {
@@ -353,45 +352,48 @@ class FilePicker private constructor(
353352
* Show selected count
354353
*
355354
*/
356-
private fun showSelectedCount() {
355+
private fun updateSelectedCount() {
357356
val selectedCount = getSelectedItems()?.size ?: 0
358357
binding.tvTitle.text = "$title ($selectedCount/$limitCount)"
359358
}
360359

361360
/**
362361
* Setup recycler view
363362
*
364-
* @param rvFiles
363+
* @param recyclerView
365364
*/
366-
private fun setupRecyclerView(rvFiles: RecyclerView) {
367-
itemAdapter = ItemAdapter(
365+
private fun setupRecyclerView(recyclerView: RecyclerView) {
366+
itemsAdapter = ItemAdapter(
368367
accentColor = accentColor,
369368
limitSelectionCount = limitCount,
370369
listener = { itemPosition ->
371-
if (onItemClickListener != null) {
372-
if (itemAdapter == null) return@ItemAdapter
373-
val media = itemAdapter?.currentList?.get(itemPosition)
374-
if (media != null) {
375-
onItemClickListener?.onClick(media, itemPosition, itemAdapter!!)
376-
}
377-
} else {
378-
itemAdapter?.setSelected(itemPosition)
379-
}
380-
381-
showSelectedCount()
370+
setupOnItemClickListener(itemPosition)
371+
updateSelectedCount()
382372
changeSubmitButtonState()
383373
}
384374
)
385-
rvFiles.apply {
375+
recyclerView.apply {
386376
layoutDirection = when (listDirection) {
387377
ListDirection.LTR -> RecyclerView.LAYOUT_DIRECTION_LTR
388378
ListDirection.RTL -> RecyclerView.LAYOUT_DIRECTION_RTL
389379
}
390380
layoutManager = GridLayoutManager(requireContext(), gridSpanCount)
391-
adapter = itemAdapter
381+
adapter = itemsAdapter
392382
}
393383
}
394384

385+
/**
386+
* Setup on item click listener
387+
*
388+
* @param position
389+
*/
390+
private fun setupOnItemClickListener(position: Int) {
391+
if (onItemClickListener == null) return
392+
if (itemsAdapter == null) return
393+
val media = itemsAdapter?.currentList?.get(position) ?: return
394+
onItemClickListener?.onClick(media, position, itemsAdapter!!)
395+
}
396+
395397
/**
396398
* change submit button state
397399
* if has selected item change to enable otherwise disable it
@@ -415,16 +417,19 @@ class FilePicker private constructor(
415417
val files = getStorageFiles(fileType = fileType)
416418
.map { Media(file = it, type = fileType) }
417419

418-
selectedFiles.forEach { media ->
419-
val selectedMedia = files.find { it.id == media.id }
420-
if (selectedMedia != null) {
421-
selectedMedia.isSelected = media.isSelected
420+
if (selectedFiles.isNotEmpty()) {
421+
selectedFiles.forEach { media ->
422+
val selectedMedia = files.find { it.id == media.id }
423+
if (selectedMedia != null) {
424+
selectedMedia.isSelected = media.isSelected
425+
selectedMedia.order = media.order
426+
}
422427
}
423428
}
424429

425430
requireActivity().runOnUiThread {
426-
itemAdapter?.submitList(files)
427-
showSelectedCount()
431+
itemsAdapter?.submitList(files)
432+
updateSelectedCount()
428433
setFixedSubmitButton()
429434
changeSubmitButtonState()
430435
binding.progress.isVisible = false
@@ -445,7 +450,7 @@ class FilePicker private constructor(
445450
* @return
446451
*/
447452
private fun getSelectedItems(): List<Media>? =
448-
itemAdapter?.currentList?.filter { it.isSelected }
453+
itemsAdapter?.currentList?.filter { it.isSelected }?.sortedBy { it.order }
449454

450455
/**
451456
* Has selected item
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.github.file_picker.adapter
2+
3+
interface FilePickerAdapter {
4+
fun setSelected(position: Int)
5+
}

file-picker/src/main/java/com/github/file_picker/adapter/ItemAdapter.kt

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,20 @@ import com.github.file_picker.extension.isValidPosition
99
import com.github.file_picker.model.Media
1010
import ir.one_developer.file_picker.databinding.ItemLayoutBinding
1111

12-
class ItemAdapter(
12+
internal class ItemAdapter(
1313
private var accentColor: Int = FilePicker.DEFAULT_ACCENT_COLOR,
1414
private var limitSelectionCount: Int = FilePicker.DEFAULT_LIMIT_COUNT,
1515
private var listener: ((Int) -> Unit)? = null
16-
) : ListAdapter<Media, ItemVH>(COMPARATOR) {
16+
) : ListAdapter<Media, ItemVH>(COMPARATOR), FilePickerAdapter {
1717

1818
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemVH(
1919
listener = listener,
2020
accentColor = accentColor,
21+
limitSelectionCount = limitSelectionCount,
2122
binding = ItemLayoutBinding.inflate(
22-
LayoutInflater.from(
23-
parent.context
24-
), parent, false
23+
LayoutInflater.from(parent.context),
24+
parent,
25+
false
2526
)
2627
)
2728

@@ -34,31 +35,40 @@ class ItemAdapter(
3435
*
3536
* @param position the selected item position
3637
*/
37-
fun setSelected(position: Int) {
38+
override fun setSelected(position: Int) {
3839
if (limitSelectionCount > 1) {
3940
val item = getItem(position)
41+
val selectedItems = currentList.filter { it.isSelected && it.id != item.id }
42+
val selectedItemCount = selectedItems.size
4043

4144
if (item.isSelected) {
42-
item.isSelected = !item.isSelected
45+
item.isSelected = false
4346
notifyItemChanged(position)
47+
selectedItems.forEach { media ->
48+
if (media.order > item.order) {
49+
media.order--
50+
notifyItemChanged(currentList.indexOf(media))
51+
}
52+
}
4453
return
4554
}
4655

47-
if (currentList.filter { it.isSelected }.size < limitSelectionCount) {
48-
item.isSelected = !item.isSelected
56+
if (selectedItemCount < limitSelectionCount) {
57+
item.isSelected = true
58+
item.order = selectedItemCount + 1
4959
notifyItemChanged(position)
5060
}
61+
return
62+
}
5163

52-
} else {
53-
if (!currentList.isValidPosition(lastSelectedPosition)) {
54-
lastSelectedPosition = position
55-
}
56-
getItem(lastSelectedPosition).isSelected = false
57-
notifyItemChanged(lastSelectedPosition)
64+
if (!currentList.isValidPosition(lastSelectedPosition)) {
5865
lastSelectedPosition = position
59-
getItem(lastSelectedPosition).isSelected = true
60-
notifyItemChanged(lastSelectedPosition)
6166
}
67+
getItem(lastSelectedPosition).isSelected = false
68+
notifyItemChanged(lastSelectedPosition)
69+
lastSelectedPosition = position
70+
getItem(lastSelectedPosition).isSelected = true
71+
notifyItemChanged(lastSelectedPosition)
6272
}
6373

6474
override fun setHasStableIds(hasStableIds: Boolean) {

file-picker/src/main/java/com/github/file_picker/adapter/ItemVH.kt

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ import com.github.file_picker.model.Media
1818
import ir.one_developer.file_picker.R
1919
import ir.one_developer.file_picker.databinding.ItemLayoutBinding
2020

21-
class ItemVH(
21+
internal class ItemVH(
2222
private val listener: ((Int) -> Unit)?,
2323
private val binding: ItemLayoutBinding,
24-
private val accentColor: Int
24+
private val accentColor: Int,
25+
private val limitSelectionCount: Int
2526
) : RecyclerView.ViewHolder(binding.root) {
2627

2728
init {
@@ -35,11 +36,14 @@ class ItemVH(
3536

3637
fun bind(item: Media) = binding.apply {
3738
cardErrorState.isVisible = false
38-
tvFileSize.text = item.file.size()
39-
ivChecked.isVisible = item.isSelected
4039
frameChecked.isVisible = item.isSelected
40+
cardOrder.isVisible = item.isSelected && limitSelectionCount > 1
41+
ivChecked.isVisible = item.isSelected && limitSelectionCount == 1
42+
43+
tvOrder.text = "${item.order}"
44+
tvFileSize.text = item.file.size()
4145

42-
val previewImage = when (item.type) {
46+
val previewImage: Any? = when (item.type) {
4347
FileType.AUDIO -> {
4448
tvPath.text = item.file.name
4549
ivMediaIcon.setImageResource(R.drawable.ic_audiotrack)
@@ -59,6 +63,8 @@ class ItemVH(
5963

6064
Glide.with(ivImage)
6165
.load(previewImage)
66+
.diskCacheStrategy(DiskCacheStrategy.NONE)
67+
.transition(DrawableTransitionOptions.withCrossFade())
6268
.listener(object : RequestListener<Drawable> {
6369
override fun onLoadFailed(
6470
e: GlideException?,
@@ -81,8 +87,6 @@ class ItemVH(
8187
}
8288

8389
})
84-
.diskCacheStrategy(DiskCacheStrategy.NONE)
85-
.transition(DrawableTransitionOptions.withCrossFade())
8690
.into(ivImage)
8791
}
8892

file-picker/src/main/java/com/github/file_picker/extension/CollectionExt.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ package com.github.file_picker.extension
66
* @param position
77
* @return
88
*/
9-
fun List<*>.isValidPosition(position: Int): Boolean {
9+
internal fun List<*>.isValidPosition(position: Int): Boolean {
1010
return if (isNotEmpty()) position in 0 until size else position >= 0
11-
}
11+
}

file-picker/src/main/java/com/github/file_picker/extension/ContextExt.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import java.io.File
1313
* @param permission permission name ex: Manifest.permission.READ_EXTERNAL_STORAGE
1414
* @return if has permission return true otherwise false
1515
*/
16-
fun Context.hasPermission(
16+
internal fun Context.hasPermission(
1717
permission: String
1818
): Boolean = ActivityCompat.checkSelfPermission(
1919
this,
@@ -25,7 +25,7 @@ fun Context.hasPermission(
2525
*
2626
* @return list of file path, ex: /storage/0/emulated/download/image.jpg
2727
*/
28-
fun Context.getStorageFiles(
28+
internal fun Context.getStorageFiles(
2929
fileType: FileType = FileType.IMAGE
3030
): List<File> {
3131

@@ -53,7 +53,8 @@ fun Context.getStorageFiles(
5353
cursor.moveToPosition(i)
5454
val dataColumnIndex = cursor.getColumnIndex(MediaStore.Images.Media.DATA)
5555
//Store the path of the image
56-
files.add(File(cursor.getString(dataColumnIndex)))
56+
val file = File(cursor.getString(dataColumnIndex))
57+
if (file.size > 0.0) files.add(file)
5758
}
5859

5960
// The cursor should be freed up after use with close()

0 commit comments

Comments
 (0)