Skip to content

Commit d5e2f78

Browse files
authored
Merge pull request #54 from rosuH/dev
🐛 🎨
2 parents 98b8f0a + 93c533d commit d5e2f78

File tree

7 files changed

+121
-80
lines changed

7 files changed

+121
-80
lines changed

filepicker/src/main/java/me/rosuh/filepicker/FilePickerActivity.kt

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ import android.support.v7.widget.RecyclerView
1515
import android.view.LayoutInflater
1616
import android.view.View
1717
import android.view.animation.AnimationUtils
18-
import android.widget.*
18+
import android.widget.CheckBox
19+
import android.widget.RelativeLayout
20+
import android.widget.Toast
21+
import kotlinx.android.synthetic.main.empty_file_list_file_picker.view.*
1922
import kotlinx.android.synthetic.main.main_activity_for_file_picker.*
2023
import me.rosuh.filepicker.R.string
2124
import me.rosuh.filepicker.adapter.FileListAdapter
@@ -39,8 +42,10 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
3942

4043
private var mainHandler = Handler(Looper.getMainLooper())
4144

42-
private val loadFileThread by lazy {
43-
Thread{
45+
private var loadFileThread: Thread? = null
46+
47+
private val loadFileRunnable: Runnable by lazy {
48+
Runnable {
4449
val rootFile = if (navDataSource.isEmpty()) {
4550
FileUtils.getRootFile()
4651
} else {
@@ -57,7 +62,7 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
5762
},
5863
this@FilePickerActivity
5964
)
60-
mainHandler.post{
65+
mainHandler.post {
6166
initRv(listData, navDataSource)
6267
setLoadingFinish()
6368
}
@@ -80,14 +85,14 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
8085
* 文件夹为空时展示的空视图
8186
*/
8287
private var selectedCount: AtomicInteger = AtomicInteger(0)
83-
private val maxSelectable = FilePickerManager.config?.maxSelectable ?: Int.MAX_VALUE
88+
private val maxSelectable = FilePickerManager.config.maxSelectable
8489
private val pickerConfig by lazy { FilePickerManager.config }
8590
private val fileListListener: RecyclerViewListener by lazy { getListener(rv_list_file_picker) }
8691
private val navListener: RecyclerViewListener by lazy { getListener(rv_nav_file_picker) }
8792

8893

8994
override fun onCreate(savedInstanceState: Bundle?) {
90-
setTheme(pickerConfig?.themeId ?: R.style.FilePickerThemeReply)
95+
setTheme(pickerConfig.themeId)
9196
super.onCreate(savedInstanceState)
9297
setContentView(R.layout.main_activity_for_file_picker)
9398
// 核验权限
@@ -100,12 +105,15 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
100105

101106
override fun onDestroy() {
102107
super.onDestroy()
103-
if (loadFileThread.isAlive){
104-
loadFileThread.interrupt()
108+
if (loadFileThread?.isAlive == true) {
109+
loadFileThread?.interrupt()
105110
}
106111
}
107112

108-
private fun isPermissionGrated() = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
113+
private fun isPermissionGrated() = ContextCompat.checkSelfPermission(
114+
this,
115+
Manifest.permission.READ_EXTERNAL_STORAGE
116+
) == PackageManager.PERMISSION_GRANTED
109117

110118
/**
111119
* 申请权限
@@ -156,17 +164,17 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
156164

157165
btn_selected_all_file_picker.apply {
158166
// 单选模式时隐藏并且不初始化
159-
if (pickerConfig?.singleChoice == true) {
167+
if (pickerConfig.singleChoice) {
160168
visibility = View.GONE
161169
return@apply
162170
}
163171
setOnClickListener(this@FilePickerActivity)
164-
FilePickerManager.config?.selectAllText?.let {
172+
FilePickerManager.config.selectAllText.let {
165173
text = it
166174
}
167175
}
168176
btn_confirm_file_picker.apply {
169-
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT){
177+
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
170178
// 小于 4.4 的样式兼容
171179
layoutParams = RelativeLayout.LayoutParams(
172180
RelativeLayout.LayoutParams.WRAP_CONTENT,
@@ -179,14 +187,18 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
179187

180188
}
181189
setOnClickListener(this@FilePickerActivity)
182-
FilePickerManager.config?.confirmText?.let {
190+
FilePickerManager.config.confirmText.let {
183191
text = it
184192
}
185193
}
186194
}
187195

188196
private fun loadList() {
189-
loadFileThread.start()
197+
if (loadFileThread?.isAlive == true) {
198+
loadFileThread?.interrupt()
199+
}
200+
loadFileThread = Thread(loadFileRunnable)
201+
loadFileThread?.start()
190202
}
191203

192204
private fun setLoadingFinish() {
@@ -201,7 +213,7 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
201213
isRefreshing = true
202214
setColorSchemeColors(
203215
*resources.getIntArray(
204-
when (pickerConfig?.themeId) {
216+
when (pickerConfig.themeId) {
205217
R.style.FilePickerThemeCrane -> {
206218
R.array.crane_swl_colors
207219
}
@@ -240,7 +252,9 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
240252
listAdapter = produceListAdapter(listData)
241253
rv_list_file_picker?.apply {
242254
emptyView = LayoutInflater.from(context)
243-
.inflate(R.layout.empty_file_list_file_picker, null, false)
255+
.inflate(R.layout.empty_file_list_file_picker, null, false).apply {
256+
tv_empty_list.text = pickerConfig.emptyListTips
257+
}
244258
adapter = listAdapter
245259
layoutAnimation =
246260
AnimationUtils.loadLayoutAnimation(context, R.anim.layout_item_anim_file_picker)
@@ -295,7 +309,7 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
295309
// 如果是文件夹,则进入
296310
enterDirAndUpdateUI(item)
297311
} else {
298-
FilePickerManager.config?.fileItemOnClickListener?.onItemClick(
312+
FilePickerManager.config.fileItemOnClickListener.onItemClick(
299313
recyclerAdapter,
300314
view,
301315
position
@@ -345,7 +359,7 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
345359
val item = (recyclerAdapter as FileListAdapter).getItem(position)
346360
item ?: return
347361
val file = File(item.filePath)
348-
val isSkipDir = FilePickerManager.config?.isSkipDir ?: true
362+
val isSkipDir = FilePickerManager.config.isSkipDir
349363
// 如果是文件夹并且没有略过文件夹
350364
if (file.exists() && file.isDirectory && isSkipDir) return
351365
val cb = view.findViewById<CheckBox>(R.id.cb_list_file_picker)
@@ -354,7 +368,7 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
354368
cb.isChecked -> {
355369
// 当前被选中,现在取消选中
356370
selectedCount.decrementAndGet()
357-
FilePickerManager.config?.fileItemOnClickListener?.onItemLongClick(
371+
FilePickerManager.config.fileItemOnClickListener.onItemLongClick(
358372
recyclerAdapter,
359373
view,
360374
position
@@ -363,7 +377,7 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
363377
isCanSelect() -> {
364378
// 新增选中项情况
365379
selectedCount.incrementAndGet()
366-
FilePickerManager.config?.fileItemOnClickListener?.onItemLongClick(
380+
FilePickerManager.config.fileItemOnClickListener.onItemLongClick(
367381
recyclerAdapter,
368382
view,
369383
position
@@ -373,7 +387,7 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
373387
// 新增失败的情况
374388
Toast.makeText(
375389
this@FilePickerActivity.applicationContext,
376-
resources.getString(R.string.max_select_count_tips, maxSelectable),
390+
resources.getString(pickerConfig.maxSelectCountTips, maxSelectable),
377391
Toast.LENGTH_SHORT
378392
).show()
379393
}
@@ -398,7 +412,7 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
398412
val item = (recyclerAdapter as FileListAdapter).getItem(position)
399413
item ?: return
400414
// 文件夹直接进入
401-
if (item.isDir && pickerConfig?.isSkipDir != false) {
415+
if (item.isDir && pickerConfig.isSkipDir) {
402416
enterDirAndUpdateUI(item)
403417
return
404418
}
@@ -507,15 +521,13 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
507521
override fun updateItemUI(isCheck: Boolean) {
508522
// 取消选中,并且选中数为 0
509523
if (selectedCount.get() == 0) {
510-
btn_selected_all_file_picker!!.text =
511-
pickerConfig?.selectAllText ?: getString(string.file_picker_tv_select_all)
524+
btn_selected_all_file_picker.text = pickerConfig.selectAllText
512525
tv_toolbar_title_file_picker.text = ""
513526
return
514527
}
515-
btn_selected_all_file_picker!!.text =
516-
pickerConfig?.deSelectAllText ?: getString(string.file_picker_tv_select_all)
528+
btn_selected_all_file_picker.text = pickerConfig.deSelectAllText
517529
tv_toolbar_title_file_picker.text =
518-
resources.getString(R.string.file_picker_selected_count, selectedCount.get())
530+
resources.getString(pickerConfig.hadSelectedText, selectedCount.get())
519531
}
520532

521533
override fun onBackPressed() {
@@ -538,7 +550,7 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
538550
selectedCount.set(0)
539551
for (data in listAdapter!!.data!!) {
540552
val file = File(data.filePath)
541-
if (pickerConfig?.isSkipDir != false && file.exists() && file.isDirectory) {
553+
if (pickerConfig.isSkipDir && file.exists() && file.isDirectory) {
542554
continue
543555
}
544556
data.setCheck(false)
@@ -548,7 +560,7 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
548560
for (i in selectedCount.get() until listAdapter!!.data!!.size) {
549561
val data = listAdapter!!.data!![i]
550562
val file = File(data.filePath)
551-
if (pickerConfig?.isSkipDir != false && file.exists() && file.isDirectory) {
563+
if (pickerConfig.isSkipDir && file.exists() && file.isDirectory) {
552564
continue
553565
}
554566
selectedCount.incrementAndGet()
@@ -590,7 +602,7 @@ class FilePickerActivity : AppCompatActivity(), View.OnClickListener,
590602
var count: Long = 0
591603
for (item in listAdapter!!.data!!) {
592604
val file = File(item.filePath)
593-
if (pickerConfig?.isSkipDir != false && file.exists() && file.isDirectory) {
605+
if (pickerConfig.isSkipDir && file.exists() && file.isDirectory) {
594606
continue
595607
}
596608
count++

filepicker/src/main/java/me/rosuh/filepicker/config/FilePickerConfig.kt

Lines changed: 49 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package me.rosuh.filepicker.config
22

33
import android.content.Intent
4+
import android.support.annotation.NonNull
5+
import android.support.annotation.StringRes
46
import me.rosuh.filepicker.FilePickerActivity
57
import me.rosuh.filepicker.R
68

@@ -68,31 +70,18 @@ class FilePickerConfig(private val pickerManager: FilePickerManager) {
6870
*/
6971
internal var themeId: Int = R.style.FilePickerThemeRail
7072
/**
71-
* 全选文字,取消全选文字,返回文字,已选择文字
73+
* 全选文字,取消全选文字,返回文字,已选择文字,确认按钮,选择限制提示语,空列表提示
7274
*/
73-
internal var selectAllText: String? = contextRes.getString(R.string.file_picker_tv_select_all)
74-
internal var deSelectAllText: String? = contextRes.getString(R.string.file_picker_tv_deselect_all)
75-
internal var goBackText: String? = contextRes.getString(R.string.file_picker_go_back)
76-
internal var hadSelectedText: String? = contextRes.getString(R.string.file_picker_selected_count)
77-
internal var confirmText: String? = contextRes.getString(R.string.file_picker_tv_select_done)
78-
79-
private fun reset(): FilePickerConfig {
80-
isShowHiddenFiles = false
81-
isShowingCheckBox = true
82-
isSkipDir = true
83-
maxSelectable = Int.MAX_VALUE
84-
mediaStorageName = contextRes.getString(R.string.file_picker_tv_sd_card)
85-
mediaStorageType = STORAGE_EXTERNAL_STORAGE
86-
selfFilter = null
87-
selfFileType = null
88-
fileItemOnClickListener = FileItemOnClickListenerImpl()
89-
themeId = R.style.FilePickerThemeRail
90-
selectAllText = contextRes.getString(R.string.file_picker_tv_select_all)
91-
deSelectAllText = contextRes.getString(R.string.file_picker_tv_deselect_all)
92-
goBackText = contextRes.getString(R.string.file_picker_go_back)
93-
hadSelectedText = contextRes.getString(R.string.file_picker_selected_count)
94-
return this
95-
}
75+
internal var selectAllText: String = contextRes.getString(R.string.file_picker_tv_select_all)
76+
77+
internal var deSelectAllText: String =
78+
contextRes.getString(R.string.file_picker_tv_deselect_all)
79+
@StringRes
80+
internal var hadSelectedText: Int = R.string.file_picker_selected_count
81+
internal var confirmText: String = contextRes.getString(R.string.file_picker_tv_select_done)
82+
@StringRes
83+
internal var maxSelectCountTips: Int = R.string.max_select_count_tips
84+
internal var emptyListTips: String = contextRes.getString(R.string.empty_list_tips_file_picker)
9685

9786
fun showHiddenFiles(isShow: Boolean): FilePickerConfig {
9887
isShowHiddenFiles = isShow
@@ -154,16 +143,44 @@ class FilePickerConfig(private val pickerManager: FilePickerManager) {
154143
return this
155144
}
156145

146+
/**
147+
* 设置界面的字符串,包括:
148+
* 选中全部[selectAllString]
149+
* 取消选中[unSelectAllString]
150+
* 已选择[hadSelectedStrRes]
151+
* 确认[confirmText]
152+
* 多选限制提示:“您只能选择 1 个条目”[maxSelectCountTipsStrRes]
153+
* 空试图体视:“空空如也”[emptyListTips]
154+
* 注意:
155+
* [hadSelectedStrRes] 和 [maxSelectCountTipsStrRes] 是 String format 限制的字符串,你需要传入 [string.xml]
156+
* 中的 id,并且包含一个可传入 Int 类型参数的占位符
157+
*----------------------------------------------------------------------------------------------
158+
* Set the string of the interface, including:
159+
 * Select all [selectAllString]
160+
 * Uncheck [unSelectAllString]
161+
 * Selected [hadSelectedStrRes]
162+
 * Confirm [confirmText]
163+
 * Multiple selection limit prompt: "You can only select 1 item" [maxSelectCountTipsStrRes]
164+
 * Empty tries to look at the stereo: "empty as well" [emptyListTips]
165+
* Note:
166+
* [hadSelectedStrRes] and [maxSelectCountTipsStrRes] are strings of String format restrictions, you need to pass in [string.xml]
167+
* The id in * and contains a placeholder for passing in an Int type parameter
168+
*/
169+
@JvmOverloads
157170
fun setText(
158-
selectAllString: String?,
159-
unSelectAllString: String?,
160-
goBackString: String?,
161-
hadSelectedString: String?
171+
@NonNull selectAllString: String = contextRes.getString(R.string.file_picker_tv_select_all),
172+
@NonNull unSelectAllString: String = contextRes.getString(R.string.file_picker_tv_deselect_all),
173+
@NonNull @StringRes hadSelectedStrRes: Int = R.string.file_picker_selected_count,
174+
@NonNull confirmText: String = contextRes.getString(R.string.file_picker_tv_select_done),
175+
@NonNull @StringRes maxSelectCountTipsStrRes: Int = R.string.max_select_count_tips,
176+
@NonNull emptyListTips: String = contextRes.getString(R.string.empty_list_tips_file_picker)
162177
): FilePickerConfig {
163-
selectAllText = selectAllString
164-
deSelectAllText = unSelectAllString
165-
goBackText = goBackString
166-
hadSelectedText = hadSelectedString
178+
this.selectAllText = selectAllString
179+
this.deSelectAllText = unSelectAllString
180+
this.hadSelectedText = hadSelectedStrRes
181+
this.confirmText = confirmText
182+
this.maxSelectCountTips = maxSelectCountTipsStrRes
183+
this.emptyListTips = emptyListTips
167184
return this
168185
}
169186

filepicker/src/main/java/me/rosuh/filepicker/config/FilePickerManager.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,24 @@ import java.lang.ref.WeakReference
99
* @author rosu
1010
* @date 2018/11/22
1111
*/
12-
object FilePickerManager{
12+
object FilePickerManager {
1313

1414

1515
/**
1616
* 启动 Launcher Activity 所需的 request code
1717
*/
1818
const val REQUEST_CODE = 10401
1919

20-
internal var contextRef:WeakReference<Activity> ?= null
21-
internal var fragmentRef:WeakReference<Fragment> ?= null
22-
internal var config: FilePickerConfig? = null
20+
internal var contextRef: WeakReference<Activity>? = null
21+
internal var fragmentRef: WeakReference<Fragment>? = null
22+
internal val config: FilePickerConfig by lazy {
23+
FilePickerConfig(this)
24+
}
2325

24-
fun from(activity: Activity):FilePickerConfig{
26+
fun from(activity: Activity): FilePickerConfig {
2527
reset()
2628
this.contextRef = WeakReference(activity)
27-
this.config = FilePickerConfig(this)
28-
return config!!
29+
return config
2930
}
3031

3132
private fun reset() {
@@ -36,12 +37,11 @@ object FilePickerManager{
3637
/**
3738
* 不能使用 fragmentRef.getContext(),因为无法保证外部的代码环境
3839
*/
39-
fun from(fragment: Fragment):FilePickerConfig{
40+
fun from(fragment: Fragment): FilePickerConfig {
4041
reset()
4142
this.fragmentRef = WeakReference(fragment)
4243
this.contextRef = WeakReference(fragment.activity!!)
43-
this.config = FilePickerConfig(this)
44-
return config!!
44+
return config
4545
}
4646

4747
private var dataList: List<String> = ArrayList()

0 commit comments

Comments
 (0)