Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 rosuh@qq.com
* @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 rosuh@qq.com
* @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 rosuh@qq.com
* @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