#GitHub地址
引用:
implementation 'com.github.ns3chz:Picker:1.0.2'
#使用姿势
开启选择界面如下:
//创建对象
//传递requestCode,传递Activity或Fragment或androidx.fragment.app.Fragment参数
FilePicker.build(MainActivity.this, 1)
//设置初始打开的目录,默认为sdcard
.setOpenFile(new File("sdcard/123/"))//
//设置选择文件还是文件夹,默认为文件
.setPickFileType(FilePickerUiParams.PickType.FILE)
//设置为单选,setMultiPick为设置多选,不可设置多选文件夹
.setSinglePick(new FilePicker.OnSinglePickListener() {
@Override
public void pick(@NonNull File path) {
tvResult.setText("单选 : \n" + path.getAbsolutePath());
}
@Override
public void cancel() {
tvResult.setText("取消选择了");
}
})
//打开选择界面
.open();
另外需要在onActivityResult中添加代码:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//会自动去集合中找到对应的组件、请求码做返回
FilePicker.onActivityResult(this, requestCode, resultCode, data);
}
pick.gif
#方法参数
setPickFileType : 设置选择类型,多选无效(强制为FILE类型)
- PickType.FILE :选择文件
- PickType.FOLDER : 选择文件夹,可以新建文件夹
- PickType.FILE_OR_FOLDER : 选择文件。当没有选择文件时,返回当前文件夹
setOpenFile : 设置初始打开的目录,默认为sdcard
setSinglePick : 设置为单选
setMultiPick : 设置为多选,最后设置的单(多)选有效
另外,可以自定义列表item的布局
/**
* @param layout RecyclerView#Item的布局
* @param icon 文件图标{@link android.widget.ImageView}id
* @param name 文件名称{@link android.widget.TextView}id
* @param desc 文件描述{@link android.widget.TextView}id
* @param select 选择状态View{@link android.view.View}id,
* 这里的选中状态的变化通过{@link #setChoiceState(BaseRecyclerAdapter.ChoiceState)}控制
* @return
*/
public FilePicker setItemFileLayoutRes(@LayoutRes int layout, @IdRes int icon, @IdRes int name, @IdRes int desc, @IdRes int select)
/**
* @param file 文件图标
* @param folder 文件夹图标
* @return
*/
public FilePicker setItemFileDrawable(@DrawableRes int file, @DrawableRes int folder)
检查存储权限
//检擦权限
boolean hasPermission = UtilPermission.hasPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (!hasPermission) {
UtilPermission.request(this, 1, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
new UtilPermission.OnPermissionRequestListener() {
@Override
public void listen(int requestCode, @Nullable String[] requestPermissions,
@Nullable List<String> grantedPermissions, @Nullable List<String> deniedPermissions) {
if (grantedPermissions != null) {
viewDataBinding.getVmFilePicker().refreshFolder();
}
}
});
}
Adapter代码
ViewHolder
class Holder extends RecyclerView.ViewHolder {
@Nullable
final View desc;
@Nullable
final View icon;
@Nullable
final View name;
@Nullable
final View select;
Holder(@NonNull View itemView) {
super(itemView);
desc = itemView.findViewById(uiParams.getId_picker_recycler_item_desc());
icon = itemView.findViewById(uiParams.getId_picker_recycler_item_icon());
name = itemView.findViewById(uiParams.getId_picker_recycler_item_name());
select = itemView.findViewById(uiParams.getId_picker_recycler_item_select());
}
}
onBindViewHolder
@Override
public void onBindsViewHolder(Holder holder, int position) {
File file = dataList.get(position);
//
if (holder.icon != null) {
if (holder.icon instanceof ImageView) {
((ImageView) holder.icon).setImageResource(file.isFile() ?
uiParams.getRes_drawable_type_file() : uiParams.getRes_drawable_type_folder());
} else {
holder.icon.setBackgroundResource(file.isFile() ?
uiParams.getRes_drawable_type_file() : uiParams.getRes_drawable_type_folder());
}
}
//
if (holder.name != null) {
if (holder.name instanceof TextView) {
((TextView) holder.name).setText(file.getName());
}
}
//
if (holder.desc != null) {
if (holder.desc instanceof TextView) {
if (file.isDirectory() && (FilePickerUiParams.PickType.FILE.equals(uiParams.getPickType()) ||
FilePickerUiParams.PickType.FILE_OR_FOLDER.equals(uiParams.getPickType()))) {
String[] list = file.list();
((TextView) holder.desc).setText((list == null ? 0 : list.length) + " 项");
} else {
((TextView) holder.desc).setText(null);
}
}
}
//
}
在选择取消选择后,根据参数改变selectView的状态
@Override
public void onBindChooseState(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull ChoiceState choiceState, boolean hadChoice) {
if (holder instanceof Holder) {
Holder vHolder = (Holder) holder;
if (vHolder.select != null) {
switch (choiceState) {
case SELECT:
setViewSelected(vHolder.select, hadChoice);
break;
case CHECKED:
setViewChecked(vHolder.select, hadChoice);
break;
case NONE:
setViewSelected(vHolder.select, false);
setViewChecked(vHolder.select, false);
break;
}
}
}
}
文件排序
@NonNull
private List<File> getSortData() {
File currentFile = uiParams.getCurrentFile();
if (!currentFile.canRead()) {
return new ArrayList<>();
}
List<File> fileList = new ArrayList<>(Arrays.asList(currentFile.listFiles()));
switch (uiParams.getPickType()) {
case FOLDER:
for (int i = fileList.size() - 1; i >= 0; i--) {
try {
File file = fileList.get(i);
if (file.isFile()) {
fileList.remove(i);
}
} catch (Exception e) {
e.printStackTrace();
}
}
break;
case FILE:
case FILE_OR_FOLDER:
break;
}
//排序
Collections.sort(fileList, new Comparator<File>() {
@Override
public int compare(File f1, File f2) {
boolean f1isDir = f1.isDirectory();
boolean f2isDir = f2.isDirectory();
if (f1isDir && !f2isDir) return -1;
if (!f1isDir && f2isDir) return 1;
//以.开头的文件放到最后
boolean conP1 = f1.getName().startsWith(".");
boolean conP2 = f2.getName().startsWith(".");
if (!conP1 && conP2) return -1;
if (conP1 && !conP2) return 1;
return f1.compareTo(f2);
}
});
return fileList;
}
选择item的逻辑放到BaseRecyclerAdapter中了
#总结
- 缺点:
- 不能对文件进行分类选择
- 多选情况下,不能跨文件夹进行选择
- 不能选择多个文件夹
- 优点:
- 可以选择文件夹
- 可以选择多个文件
- 可以搜索文件
- 选择文件夹时,可以新建文件夹
- 使用只需要两步
谢谢
stormtroopocat.png