Skip to content

Commit

Permalink
Merge pull request #89 from rosuH/dev
Browse files Browse the repository at this point in the history
Improved custom file type.
  • Loading branch information
rosuH authored Sep 17, 2020
2 parents 8733b6e + 889f772 commit 7687193
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 65 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
ext.kotlin_version="1.3.60"
ext.kotlin_version="1.4.10"
repositories {
google()
jcenter()
Expand All @@ -10,7 +10,7 @@ buildscript {
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath 'com.android.tools.build:gradle:4.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
classpath "org.jlleitschuh.gradle:ktlint-gradle:9.1.1"
Expand Down
2 changes: 1 addition & 1 deletion filepicker/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${kotlin_version}"
implementation "com.android.support:appcompat-v7:${supportLibVersion}"
implementation "com.android.support:recyclerview-v7:${supportLibVersion}"
implementation "com.android.support.constraint:constraint-layout:1.1.3"
implementation "com.android.support.constraint:constraint-layout:2.0.1"
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,12 @@ class FileListAdapter(
when (holder) {
is FileListItemHolder -> {
holder.itemView.findViewById<CheckBox>(R.id.cb_list_file_picker)?.let {
it.isChecked = payloads[0] as Boolean
it.isChecked = getItem(position)?.isChecked() ?: false
}
}
is FileListItemSingleChoiceHolder -> {
holder.itemView.findViewById<RadioButton>(R.id.rb_list_file_picker)?.let {
it.isChecked = payloads[0] as Boolean
it.isChecked = getItem(position)?.isChecked() ?: false
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,39 @@ import me.rosuh.filepicker.filetype.*
*/
class DefaultFileDetector : AbstractFileDetector() {

var enableCustomTypes: Boolean = false
private set

private val allDefaultFileType: ArrayList<FileType> by lazy {
val fileTypes = ArrayList<FileType>()
fileTypes.add(AudioFileType())
fileTypes.add(RasterImageFileType())
fileTypes.add(CompressedFileType())
fileTypes.add(DataBaseFileType())
fileTypes.add(ExecutableFileType())
fileTypes.add(FontFileType())
fileTypes.add(PageLayoutFileType())
fileTypes.add(TextFileType())
fileTypes.add(VideoFileType())
fileTypes.add(WebFileType())
fileTypes
ArrayList<FileType>()
}

fun registerDefaultTypes() {
with(allDefaultFileType) {
clear()
add(AudioFileType())
add(RasterImageFileType())
add(CompressedFileType())
add(DataBaseFileType())
add(ExecutableFileType())
add(FontFileType())
add(PageLayoutFileType())
add(TextFileType())
add(VideoFileType())
add(WebFileType())
}
enableCustomTypes = false
}

/**
* @author [email protected]
* @date 2020/9/16
* save user's custom file types
*/
fun registerCustomTypes(customFileTypes: ArrayList<FileType>) {
allDefaultFileType.clear()
allDefaultFileType.addAll(customFileTypes)
enableCustomTypes = true
}

override fun fillFileType(itemBeanImpl: FileItemBeanImpl): FileItemBeanImpl {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.support.annotation.StringRes
import me.rosuh.filepicker.FilePickerActivity
import me.rosuh.filepicker.R
import me.rosuh.filepicker.engine.ImageEngine
import me.rosuh.filepicker.filetype.FileType

/**
*
Expand All @@ -14,6 +15,12 @@ import me.rosuh.filepicker.engine.ImageEngine
*/
class FilePickerConfig(private val pickerManager: FilePickerManager) {

var isAutoFilter: Boolean = false

private val customFileTypes: ArrayList<FileType> by lazy {
ArrayList<FileType>(2)
}

private val contextRes = pickerManager.contextRef!!.get()!!.resources

/**
Expand Down Expand Up @@ -77,9 +84,14 @@ class FilePickerConfig(private val pickerManager: FilePickerManager) {
/**
* 自定文件类型甄别器和默认类型甄别器
*/
@Deprecated(
"Use 'register' function instead.",
ReplaceWith("registerFileType(types)"),
level = DeprecationLevel.WARNING
)
var customDetector: AbstractFileDetector? = null
private set
val defaultFileDetector: DefaultFileDetector by lazy { DefaultFileDetector() }

val defaultFileDetector: DefaultFileDetector by lazy { DefaultFileDetector().also { it.registerDefaultTypes() } }

/**
* 点击操作接口,采用默认实现
Expand Down Expand Up @@ -140,7 +152,10 @@ class FilePickerConfig(private val pickerManager: FilePickerManager) {
}

@JvmOverloads
fun storageType(volumeName: String = "", @StorageMediaType storageMediaType: String): FilePickerConfig {
fun storageType(
volumeName: String = "",
@StorageMediaType storageMediaType: String
): FilePickerConfig {
mediaStorageName = volumeName
mediaStorageType = storageMediaType
return this
Expand All @@ -157,11 +172,19 @@ class FilePickerConfig(private val pickerManager: FilePickerManager) {
}

/**
* @author [email protected]
* @date 2020/9/15
* custom file type had upgrade to [registerFileType], which can simplify your usage.
* 实现 [AbstractFileDetector] 以自定义您自己的文件类型检测器
* Custom your file detector by implementing [AbstractFileDetector]
*/
@Deprecated(
"Use 'register' function instead.",
ReplaceWith("registerFileType(types)"),
level = DeprecationLevel.WARNING
)
fun customDetector(detector: AbstractFileDetector): FilePickerConfig {
customDetector = detector
this.customDetector = detector
return this
}

Expand Down Expand Up @@ -227,6 +250,28 @@ class FilePickerConfig(private val pickerManager: FilePickerManager) {
this.customImageEngine = ie
return this
}
/**
* @author [email protected]
* @date 2020/9/15
* 用于注册你自定义的文件类型。
* 库将自动调用你的自定义类型里的[FileType.verify]来识别文件。如果识别成功,就会自动填充到 [me.rosuh.filepicker.bean.FileItemBeanImpl.fileType] 中
* 如果[autoFilter]为 true,那么库将自动过滤掉不符合你自定义类型的文件。不会在结果中显示出来。
* 如果为 false,那么就只是检测类型。不会对结果列表做修改
* 你不需要再调用[fileType]方法,否则将默认使用[fileType]
* ---
* Pass your custom [FileType] instances list and all done! This lib would auto detect file type
* by using [FileType.verify].
* If [autoFilter] is true, this lib will filter result by using your custom file types.
* If [autoFilter] is true, the library will automatically filter out files that do not meet your custom type.
* Will not show up in the results. * If it is false, then only the detection type. No changes to the result list
* You don't need to call [fileType] again !
*/
fun registerFileType(types: List<FileType>, autoFilter: Boolean = true): FilePickerConfig {
this.customFileTypes.addAll(types)
this.defaultFileDetector.registerCustomTypes(customFileTypes)
this.isAutoFilter = autoFilter
return this
}

fun forResult(requestCode: Int) {
val activity = pickerManager.contextRef?.get()!!
Expand All @@ -246,16 +291,19 @@ class FilePickerConfig(private val pickerManager: FilePickerManager) {
*/
@get:StorageMediaType
const val STORAGE_EXTERNAL_STORAGE = "STORAGE_EXTERNAL_STORAGE"

/**
* TODO 可拔插的 SD 卡
*/
@get:StorageMediaType
const val STORAGE_UUID_SD_CARD = "STORAGE_UUID_SD_CARD"

/**
* TODO 可拔插 U 盘
*/
@get:StorageMediaType
const val STORAGE_UUID_USB_DRIVE = "STORAGE_UUID_USB_DRIVE"

/**
* 自定义路径
*/
Expand Down
35 changes: 22 additions & 13 deletions filepicker/src/main/java/me/rosuh/filepicker/utils/FileUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import me.rosuh.filepicker.bean.FileItemBeanImpl
import me.rosuh.filepicker.bean.FileNavBeanImpl
import me.rosuh.filepicker.config.FilePickerConfig.Companion.STORAGE_CUSTOM_ROOT_PATH
import me.rosuh.filepicker.config.FilePickerConfig.Companion.STORAGE_EXTERNAL_STORAGE
import me.rosuh.filepicker.config.FilePickerManager
import me.rosuh.filepicker.config.FilePickerManager.config
import java.io.File

/**
Expand All @@ -24,16 +24,16 @@ class FileUtils {
* 根据配置参数获取根目录文件
* @return File
*/
fun getRootFile(): File {
return when (FilePickerManager.config.mediaStorageType) {
fun getRootFile():File {
return when (config.mediaStorageType) {
STORAGE_EXTERNAL_STORAGE -> {
File(Environment.getExternalStorageDirectory().absoluteFile.toURI())
}
STORAGE_CUSTOM_ROOT_PATH -> {
if (FilePickerManager.config.customRootPath.isEmpty()) {
if (config.customRootPath.isEmpty()) {
File(Environment.getExternalStorageDirectory().absoluteFile.toURI())
} else {
File(FilePickerManager.config.customRootPath)
File(config.customRootPath)
}
}
else -> {
Expand All @@ -50,10 +50,11 @@ class FileUtils {
beanSubscriber: BeanSubscriber
): ArrayList<FileItemBeanImpl> {
val listData: ArrayList<FileItemBeanImpl> = ArrayList()
var isDetected = false
for (file in rootFile.listFiles()) {
//以符号 . 开头的视为隐藏文件或隐藏文件夹,后面进行过滤
val isHiddenFile = file.name.startsWith(".")
if (!FilePickerManager.config.isShowHiddenFiles && isHiddenFile) {
if (!config.isShowHiddenFiles && isHiddenFile) {
// skip hidden files
continue
}
Expand Down Expand Up @@ -81,16 +82,24 @@ class FileUtils {
beanSubscriber
)
// 如果调用者没有实现文件类型甄别器,则使用的默认甄别器
FilePickerManager.config.customDetector?.fillFileType(itemBean)
?: FilePickerManager.config.defaultFileDetector.fillFileType(itemBean)
config.customDetector?.fillFileType(itemBean)
?: config.defaultFileDetector.fillFileType(itemBean)
isDetected = itemBean.fileType != null
if (config.defaultFileDetector.enableCustomTypes
&& config.isAutoFilter
&& !isDetected
) {
// enable auto filter AND using user's custom file type. Filter them.
continue
}
listData.add(itemBean)
}
// 默认字典排序
// Default sort by alphabet
listData.sortWith(compareBy({ !it.isDir }, { it.fileName.toUpperCase() }))
// 将当前列表数据暴露,以供调用者自己处理数据
// expose data list to outside caller
return FilePickerManager.config.selfFilter?.doFilter(listData) ?: listData
return config.selfFilter?.doFilter(listData) ?: listData
}

/**
Expand All @@ -107,10 +116,10 @@ class FileUtils {
// 优先级:目标设备名称 --> 自定义路径 --> 默认 SD 卡
currentDataSource.add(
FileNavBeanImpl(
if (!FilePickerManager.config.mediaStorageName.isNullOrEmpty()) {
FilePickerManager.config.mediaStorageName
} else if (!FilePickerManager.config.customRootPath.isEmpty()) {
FilePickerManager.config.customRootPath
if (!config.mediaStorageName.isNullOrEmpty()) {
config.mediaStorageName
} else if (!config.customRootPath.isEmpty()) {
config.customRootPath
} else {
context.getString(R.string.file_picker_tv_sd_card)
},
Expand Down
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Wed Nov 27 14:17:28 CST 2019
#Wed Sep 16 10:42:32 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
2 changes: 1 addition & 1 deletion sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ dependencies {
// implementation 'com.squareup.picasso:picasso:2.5.2'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support.constraint:constraint-layout:2.0.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
Expand Down
30 changes: 10 additions & 20 deletions sample/src/main/java/me/rosuh/sample/SampleActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import me.rosuh.filepicker.bean.FileItemBeanImpl
import me.rosuh.filepicker.config.*
import me.rosuh.filepicker.engine.ImageEngine
import me.rosuh.filepicker.filetype.FileType
import me.rosuh.filepicker.config.AbstractFileFilter
import me.rosuh.filepicker.config.FilePickerConfig
import me.rosuh.filepicker.config.FilePickerManager
import me.rosuh.filepicker.config.SimpleItemClickListener
import me.rosuh.filepicker.filetype.AudioFileType
import me.rosuh.filepicker.filetype.RasterImageFileType
import me.rosuh.filepicker.utils.ScreenUtils

Expand Down Expand Up @@ -125,15 +130,13 @@ class SampleActivity : AppCompatActivity() {
}
})
.skipDirWhenSelect(false)
.setTheme(R.style.FilePickerThemeReply)
.forResult(FilePickerManager.REQUEST_CODE)
}
// 多选文件
btn_multi_file.setOnClickListener {
FilePickerManager
.from(this@SampleActivity)
.setTheme(getRandomTheme())
.setTheme(R.style.FilePickerThemeCrane)
.forResult(FilePickerManager.REQUEST_CODE)
}
// 多选文件夹
Expand All @@ -149,7 +152,6 @@ class SampleActivity : AppCompatActivity() {
}
})
.skipDirWhenSelect(false)
.setTheme(R.style.FilePickerThemeShrine)
.forResult(FilePickerManager.REQUEST_CODE)
}
// 自定义根目录
Expand All @@ -160,29 +162,17 @@ class SampleActivity : AppCompatActivity() {
// 不指定名称则为导航栏将显示绝对路径
// .storageType(FilePickerConfig.STORAGE_CUSTOM_ROOT_PATH)
.setCustomRootPath("/storage/emulated/0/Download")
.setTheme(R.style.FilePickerThemeReply)
.forResult(FilePickerManager.REQUEST_CODE)
}
// 自定义文件类型
// the new api for register your custom file type
btn_custom_file_type.setOnClickListener {
FilePickerManager
.from(this@SampleActivity)
// 1. 使用自定义文件检测器来检测类型,并赋值给 [FileItemBeanImpl.fileType] 属性
// 1. Using detector detect file's type and fill it into [FileItemBeanImpl.fileType]
.customDetector(CustomFileDetector())
.filter(object : AbstractFileFilter() {
override fun doFilter(listData: ArrayList<FileItemBeanImpl>): ArrayList<FileItemBeanImpl> {
// 2. 接收结果列表,然后过滤出您想要的类型
// 2. Receive result list and filter what you want
listData.removeAll {
(it.fileType !is CustomFileType) && !it.isDir
}
return listData
}
})
.showHiddenFiles(true)
FilePickerManager.from(this@SampleActivity)
.setTheme(getRandomTheme())
.registerFileType(arrayListOf(AudioFileType()))
.forResult(FilePickerManager.REQUEST_CODE)
}

findViewById<Button>(R.id.btn_show_in_fragment).setOnClickListener {
SampleFragment.show(supportFragmentManager, "SampleFragment")
}
Expand Down
Loading

0 comments on commit 7687193

Please sign in to comment.