FileSelector使用手册

引用方式

Gradle 7.0以下,需要在项目级build.gradle文件中加入

1
2
3
4
5
6
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}

Gradle 7.0以上,需要在setting.gradle文件中加入

1
2
3
4
5
6
dependencyResolutionManagement {
repositories {
...
maven { url 'https://jitpack.io' }
}
}

远程仓库配置之后,即可在模块的build.gradle中引入FileSelector

1
2
3
dependencies {
implementation 'com.github.xxinPro:FileSelector:1.0'
}

启动方式

1、启动Activity

1
2
3
4
5
6
7
8
9
10
11
12
FileSelector.create(this)
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

2、注入frameLayout,其中forResult()的第一个参数代表需要被注入的frameLayoutid

1
2
3
4
5
6
7
8
9
10
11
12
FileSelector.create(this)
.forResult(R.id.frame_layout, new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

操作文件

在选择文件后,FileSelector将回调OnResultCallbackListeneronResult()方法,在onResult()方法中通过List<FileBean>集合可对文件进行操作

对于FileBean类,其中仅包含一个可用的FileDocumentFile类型文件对象,因为在Android 11及以上的系统中,dataobb目录中的子文件是DocumentFile类型文件对象

可以通过如下方法判断FileBean中包含的文件类型

方法名返回结果
public boolean isFileType()true时表示FileBean中包含一个File类型文件对象,反之为DocumentFile类型文件对象
public boolean isDocumentFileType()true时表示FileBean中包含一个DocumentFile类型文件对象,反之为File类型文件对象

通过如下方法可以获取FileBean中包含的FileDocumentFile文件对象

方法名返回结果
public File getFile()获取FileBean中包含的File类型文件对象
public DocumentFile getDocumentFile()获取FileBean中包含的DocumentFile类型文件对象

通过如下方法可以对FileBean类进行一些快捷操作

方法名返回结果
public long lastModified()FileBean中包含文件的最后修改时间
public long length()FileBean中包含文件的大小
public String getName()FileBean中包含文件的文件名

基本使用

设置起始路径

设置FileSelector打开的起始路径,默认起始路径为/storage/emulated/0,可以自定义设置为任何一个存在的路径,包括data(obb)目录及其子目录,若data(obb)目录或其子目录没有访问权限将会自动申请

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.setInitPath(Environment.getExternalStorageDirectory().getAbsolutePath()) // 设置起始路径
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

设置排序规则

设置文件列表的排序规则,默认根据文件名排序

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.setSortRule(SortRule.Name) // 设置排序规则
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

setSortRule()重载方法的第二个参数用于控制是否逆序,为true时代表逆序

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.setSortRule(SortRule.Name, true) // 设置排序规则,并进行逆序
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

FileSelector提供了如下三种排序规则

1
2
3
4
5
public enum SortRule {
Time, // 按时间排序
Name, // 按文件名排序
Size, // 按大小排序
}

若不满足,可以使用自定义的排序规则;需要注意的是,设置自定义排序规则后FileSelector中的排序规则将不生效

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
FileSelector.create(this)
.selfSortRule(new Comparator<FileItemBean>() {
@Override
public int compare(FileItemBean o1, FileItemBean o2) {
// 自定义排序逻辑
return 0;
}
})
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

自定义文件图标

FileSelector提供了默认的文件图标,若不满足可以对文件图标进行自定义设置

未知文件图标

FileSelector通过文件的后缀名来设置对应的图标,所以当文件有一些不明所以的后缀名时,FileSelector将会为其设置一个未知文件图标,通过如下代码可以对该图标进行自定义

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.setDefaultFileIcon(R.drawable.file_icon) // 设置未知文件的图标
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

文件夹图标

自定义文件夹图标

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.setDefaultFolderIcon(R.drawable.folder_icon) // 设置文件夹的图标
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

给指定类型文件添加图标

FileSelector给小部分常见文件添加了图标,例如jpgpng,若对此图标不满足或想添加其他类型文件的图标,可以通过如下方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FileSelector.create(this)
.addIconBySuffix("jpg", R.drawable.img_icon) // 给指定类型文件添加图标
.addIconBySuffix("png", R.drawable.img_icon) // 给指定类型文件添加图标
.addIconBySuffix("mp3", R.drawable.music_icon) // 给指定类型文件添加图标
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

批量添加公用同一图标的文件类型,如下代码将jpgpngwebp的图标设置为R.drawable.img_icon

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FileSelector.create(this)
.addBatchesIconBySuffix(
new String[] {"jpg", "png", "webp"}, R.drawable.img_icon)
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

批量添加,注意后缀名和图标的drawable id一一对应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FileSelector.create(this)
.addBatchesIconBySuffix(
new String[] {"jpg", "png", "mp3"},
new int[] {R.drawable.img_icon, R.drawable.img_icon, R.drawable.music_icon})
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

加载略缩图

开启略缩图加载后,图片、GIF图片以及视频的图标将显示一个略缩图,但是加载略缩图需要加载引擎,可以参考下面使用Glide实现的GlideEngine

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FileSelector.create(this)
.isDisplayThumbnail(true) // 开启略缩图加载
.setImageEngine(GlideEngine.createGlideEngine()) // 设置略缩图加载引擎
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

GlideEngine

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class GlideEngine implements ImageEngine {
private static volatile GlideEngine glideEngine;

private GlideEngine () {}

public static GlideEngine createGlideEngine() {
if (glideEngine == null) {
synchronized (GlideEngine.class) {
if (glideEngine == null) {
glideEngine = new GlideEngine();
}
}
}
return glideEngine;
}

@Override
public void loadFileImage(Context context, File file, ImageView imageView, int defaultDrawableId) {
RequestOptions options = new RequestOptions()
.centerCrop()
.placeholder(defaultDrawableId);
Glide.with(context)
.load(file)
.apply(options)
.into(imageView);
}

@Override
public void loadDocumentFileImage(Context context, DocumentFile documentFile, ImageView imageView, int defaultDrawableId) {
RequestOptions options = new RequestOptions()
.centerCrop()
.placeholder(defaultDrawableId);
Glide.with(context)
.load(documentFile.getUri())
.apply(options)
.into(imageView);
}
}

文件修改时间的格式

FileSelector中默认的文件修改时间的显示格式是2024-01-01 12:30:26,可以通过如下方式修改

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.setLastModifiedPattern("yyyy年MM月dd日 HH时mm分ss秒") // 设置文件最后修改时间的显示格式
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

只显示文件夹

设置文件列表中只显示文件夹,不显示文件

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.isOnlyDisplayFolder(true) // 只显示文件夹
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

只选择文件

设置只能选择文件,禁止选择文件夹

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.isOnlySelectFile(true) // 只能选择文件
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

显示指定类型文件

设置仅显示指定类型的文件,如下代码设置后,将仅显示jpgtxtmp3类型的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.addDisplayType("jpg", "txt", "mp3") // 仅显示指定类型文件
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

设置最大选择数

如下代码设置后,在选择文件时最多只能选择5

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.setMaxSelectValue(5) // 设置文件最大选择数
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

设置最大选择数支持添加一个文件选择回调,将会在选择item时调用该回调方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
FileSelector.create(this)
// 设置文件最大选择数,同时设置一个文件选择回调
.setMaxSelectValue(5, new OnSelectCallBackListener() {
@Override
public void onSelectCallBack(int maxSelectCount, int currentSelectCount) {
if (currentSelectCount >= maxSelectCount) {
Toast.makeText(SelectActivity.this, "最多选择" + maxSelectCount + "个文件~", Toast.LENGTH_SHORT).show();
}
}
})
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

设置单选模式

在设置单选模式后,将仅能选择一个文件或文件夹;单选模式不同于设置最大选择数为1,具体区别请自行测试

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.isSingle(true) // 设置为单选模式
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

开启震动

默认为开启状态,选择文件或文件夹时将轻微震动手机

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.isVibrator(true) // 开启震动
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

自动打开选择模式

开启后,在进入文件选择页面时将自动打开文件选择模式

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.isAutoOpenSelectMode(true) // 自动打开选择模式
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

设置状态栏颜色

设置状态栏的颜色在fragment注入模式下同样生效,所以在选择文件之后可能需要重新设置frameLayout所属Activity的状态栏颜色

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.setStatusBarColor(R.color.blue) // 设置状态栏颜色
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

设置状态栏字体颜色

状态栏字体颜色只有黑色和白色两种,当为true时状态栏字体颜色将显示黑色

fragment注入模式下同样生效,所以在选择文件之后可能需要重新设置frameLayout所属Activity的状态栏字体颜色

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.setStatusBarTextColor(true) // 设置状态栏字体颜色
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

设置导航栏颜色

设置底部虚拟导航栏的颜色在fragment注入模式下同样生效,所以在选择文件之后可能需要重新设置frameLayout所属Activity的导航栏颜色

1
2
3
4
5
6
7
8
9
10
11
12
13
FileSelector.create(this)
.setNavigationBarColor(R.color.blue) // 设置导航栏颜色
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

进阶使用

1、设置FileSelector最下面一层view的样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
FileSelectorViewStyle fileSelectorViewStyle = new FileSelectorViewStyle();
fileSelectorViewStyle.setBackgroundColorId(R.color.white); // 底层背景色
fileSelectorViewStyle.setBackgroundDrawableId(R.drawable.background); // 底层背景图

FileSelector.create(this)
.setFileSelectorViewStyle(fileSelectorViewStyle)
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

2、设置FileSelector顶部栏的样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
FileSelectorTitleBarStyle fileSelectorTitleBarStyle = new FileSelectorTitleBarStyle();
// 设置顶部栏高度,以dp为单位
fileSelectorTitleBarStyle.setHeight(50);
// 设置顶部栏背景色
fileSelectorTitleBarStyle.setBackgroundColorId(R.color.blue);
// 设置顶部栏左侧返回按钮的图片drawable资源id
fileSelectorTitleBarStyle.setOverImageDrawableId(R.drawable.back);
// 设置顶部栏中间标题text
fileSelectorTitleBarStyle.setTitleText("请选择文件");
// 设置顶部栏中间标题的字体大小,以sp为单位
fileSelectorTitleBarStyle.setTitleTextSize(20);
// 设置顶部栏中间标题的字体颜色
fileSelectorTitleBarStyle.setTitleTextColorId(R.color.white);
// 设置顶部栏右侧的按钮,在进入选择模式之后的text
fileSelectorTitleBarStyle.setStartControlText("取消");
// 设置顶部栏右侧的按钮,在退出选择模式之后的text
fileSelectorTitleBarStyle.setEndControlText("全选");
// 设置顶部栏右侧的按钮的字体大小
fileSelectorTitleBarStyle.setControlTextSize(16);
// 设置顶部栏右侧的按钮的字体颜色
fileSelectorTitleBarStyle.setControlTextColorId(R.color.white);

FileSelector.create(this)
.setFileSelectorTitleBarStyle(fileSelectorTitleBarStyle)
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

3、设置FileSelector路径显示栏的样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
FileSelectorPathBarStyle fileSelectorPathBarStyle = new FileSelectorPathBarStyle();
// 设置路径栏背景色
fileSelectorPathBarStyle.setBackgroundColorId(R.color.white);
// 设置路径栏头item的背景色
fileSelectorPathBarStyle.setHeadItemBackgroundColorId(R.color.blue);
// 设置路径栏头item的字体颜色
fileSelectorPathBarStyle.setHeadItemTextColorId(R.color.white);
// 设置路径栏其余item的背景色
fileSelectorPathBarStyle.setItemBackgroundColorId(R.color.gray);
// 设置路径栏其余item的字体颜色
fileSelectorPathBarStyle.setItemTextColorId(R.color.black);
// 设置路径栏所有item的字体大小
fileSelectorPathBarStyle.setItemTextSize(16);
// 设置路径栏item之间箭头图片的drawable资源id
fileSelectorPathBarStyle.setArrowImageDrawableId(R.drawable.arrow);
// 设置文件数量的描述
fileSelectorPathBarStyle.setFileCountDescription("文件数量:");
// 设置文件夹数量的描述
fileSelectorPathBarStyle.setFolderCountDescription("文件夹数量:");
// 设置文件及文件夹数量描述的字体颜色
fileSelectorPathBarStyle.setDescriptionColorId(R.color.black);
// 设置文件及文件夹数量描述的字体大小
fileSelectorPathBarStyle.setDescriptionTextSize(16);

FileSelector.create(this)
.setFileSelectorPathBatStyle(fileSelectorPathBarStyle)
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

4、设置FileSelector列表样式

列表item的宽高、内边距、外边距及下划线,可以通过RecyclerViewaddItemDecoration()方法设置,ItemDecoration可以参考下面的LineItemDecorationImageItemDecoration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
FileSelectorListViewStyle fileSelectorListViewStyle = new FileSelectorListViewStyle();
// 设置列表背景色
fileSelectorListViewStyle.setBackgroundColorId(R.color.white);
// 设置当前目录为空时的提示
fileSelectorListViewStyle.setEmptyFolderDescription("当前文件夹为空");
// 设置当前目录为空时提示的字体颜色
fileSelectorListViewStyle.setEmptyFolderDescriptionTextColorId(R.color.black);
// 设置当前目录为空时提示的字体大小
fileSelectorListViewStyle.setEmptyFolderDescriptionTextSize(20);
// 设置当前目录为空时页面的背景色
fileSelectorListViewStyle.setEmptyFolderBackgroundColorId(R.color.white);
// 设置列表加载过程的提示
fileSelectorListViewStyle.setLoadProgressDescription("文件加载中...");
// 设置列表加载过程提示的字体颜色
fileSelectorListViewStyle.setLoadProgressDescriptionTextColorId(R.color.black);
// 设置列表加载过程提示的字体大小
fileSelectorListViewStyle.setLoadProgressDescriptionTextSize(20);
// 设置加载时环形进度条的颜色
fileSelectorListViewStyle.setLoadProgressBarColorId(R.color.blue);
// 设置加载页面的背景色
fileSelectorListViewStyle.setLoadProgressBackgroundColorId(R.color.white);
// 设置item的装饰
fileSelectorListViewStyle.setItemDecoration(new CustomItemDecoration(this));

// 以下代码是对item一些样式的设置
FileSelectorListViewStyle.FileSelectorListItemStyle fileSelectorListItemStyle = new FileSelectorListViewStyle.FileSelectorListItemStyle();
// 设置item背景色
fileSelectorListItemStyle.setItemBackgroundColorId(R.color.white);
// 设置item被点击时变化的背景色
fileSelectorListItemStyle.setItemActionDownBackgroundColorId(R.color.gray);
// 设置item中文件名的字体颜色
fileSelectorListItemStyle.setFileNameTextColorId(R.color.black);
// 设置item中文件名的字体大小
fileSelectorListItemStyle.setFileSizeTextSize(16);
// 设置item中文件修改时间的字体颜色
fileSelectorListItemStyle.setLastModifiedTextColorId(R.color.gray);
// 设置item中文件修改时间的字体大小
fileSelectorListItemStyle.setLastModifiedTextSize(16);
// 设置item中文件大小的字体颜色
fileSelectorListItemStyle.setFileSizeTextColorId(R.color.gray);
// 设置item中文件大小的字体大小
fileSelectorListItemStyle.setFileSizeTextSize(16);
// 设置item文件夹右侧箭头图片drawable资源id
fileSelectorListItemStyle.setArrowDrawableId(R.drawable.arrow);
// 设置item被选中后,checkBox显示的图片drawable资源id
fileSelectorListItemStyle.setSelectedDrawableId(R.drawable.selected);
// 设置item未被选中时,checkBox显示的图片drawable资源id
fileSelectorListItemStyle.setDeselectedDrawableId(R.drawable.deselected);

// 设置item的样式
fileSelectorListViewStyle.setFileSelectorListItemStyle(fileSelectorListItemStyle);

FileSelector.create(this)
.setFileSelectorListViewStyle(fileSelectorListViewStyle)
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

LineItemDecoration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class LineItemDecoration extends RecyclerView.ItemDecoration {
private final Context context;
private final int lineStrokeWidth;

public LineItemDecoration(Context context, int lineStrokeWidth) {
this.context = context;
this.lineStrokeWidth = lineStrokeWidth;
}

@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.onDraw(c, parent, state);
// 在相邻item之间绘制一条分割线
Paint paint = new Paint();
paint.setColor(context.getResources().getColor(R.color.black));
paint.setStrokeWidth(PixelsUtil.dp2px(lineStrokeWidth, context));

int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
c.drawLine(child.getLeft() + 20, child.getBottom(), child.getRight() - 20, child.getBottom(), paint);
}
}

@Override
public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.onDrawOver(c, parent, state);
}

@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
// 相当于设置item的margin,在底部或顶部空出空间,用于显示onDraw中绘制的分割线
outRect.set(0, 0, 0, PixelsUtil.dp2px(lineStrokeWidth, context));
// 设置item的padding,不会影响onDraw中绘制的分割线
view.setPadding(0,0,0,0);
// 设置item宽高
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) view.getLayoutParams();
layoutParams.height = RecyclerView.LayoutParams.WRAP_CONTENT;
layoutParams.width = RecyclerView.LayoutParams.MATCH_PARENT;
// layoutParams.setMargins(0,0,0,0); // 也可以通过layoutParams设置item的margin
view.setLayoutParams(layoutParams);
}
}

ImageItemDecoration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class ImageItemDecoration extends RecyclerView.ItemDecoration {
private final Context context;
private final int imageDrawableId;

public ImageItemDecoration(Context context, int imageDrawableId) {
this.context = context;
this.imageDrawableId = imageDrawableId;
}

@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int dp10 = PixelsUtil.dp2px(10, context);
outRect.set(0, dp10, 0, dp10);
}

@Override
public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
super.onDraw(c, parent, state);
Drawable drawable = ResourcesUtil.getDrawableById(context, imageDrawableId);

Paint paint = new Paint();
paint.setAntiAlias(true);

int childCount = parent.getChildCount();
for (int i = 0; i < childCount - 1; i++) {
View child = parent.getChildAt(i);

int dp20 = PixelsUtil.dp2px(20, context);

int left = child.getLeft() + dp20; // item左边界
int top = child.getBottom(); // item上边界
int right = child.getRight() - dp20; // item右边界
int bottom = child.getBottom() + dp20; // item下边界

// 设置图片绘制区域
drawable.setBounds(left, top, right, bottom);
// 绘制图片
drawable.draw(c);
}
}
}

5、设置FileSelector底部栏样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
FileSelectorFootBarStyle fileSelectorFootBarStyle = new FileSelectorFootBarStyle();
// 设置底部栏背景色
fileSelectorFootBarStyle.setBackgroundColorId(R.color.gray);
// 设置底部栏按钮的背景色
fileSelectorFootBarStyle.setBtnBackgroundColorId(R.color.white);
// 设置底部栏按钮按下后变化的背景色
fileSelectorFootBarStyle.setBtnActionDownBackgroundColorId(R.color.gray);
// 设置底部栏左边按钮的text
fileSelectorFootBarStyle.setLeftButtonText("全选");
// 设置item被全选后底部栏左边按钮的text
fileSelectorFootBarStyle.setLeftButtonSelectedAllText("取消全选");
// 设置底部栏右边按钮的text
fileSelectorFootBarStyle.setRightButtonText("确定");
// 设置底部栏按钮的字体颜色
fileSelectorFootBarStyle.setButtonTextColorId(R.color.black);
// 设置底部栏按钮的字体大小
fileSelectorFootBarStyle.setButtonTextSize(16);

FileSelector.create(this)
.setFileSelectorFootBarStyle(fileSelectorFootBarStyle)
.forResult(new OnResultCallbackListener() {
@Override
public void onResult(List<FileBean> result) {
// 文件处理逻辑
}

@Override
public void onCancel() {
// 未选择处理逻辑
}
});

开源地址

https://github.com/xxinPro/FileSelector