Android本地文件管理器思路解析一一增删改查具体实现
花了一天的时间撸完了Android本地文件管理器~!!GitHub下载地址为:PumpkinFileManager
南瓜文件管理器1.0.
功能列表:
1: 实现了在ListView中浏览本地所有文件.
2: 实现了对文件的增(新建文件夹)
3: 删(删除文件或文件夹).
4: 改(重命名以及复制粘贴文件).
5: 查(对当前路径下的递归查询).
6: 排(对显示在listView中的文件按时间,大小或文件名排序).
整体思路:
大概的思路是首先遍历本地所有文件的根目录,然后通过使用栈结构存储文件路径,因为出栈入栈的特性很适合处理随着用户操作不断推出存入的文件路径,之后增删改查的具体实现在下文都有详细解释以及缩略图,总共花费大概10个小时(折腾了好久Github..sad),也是完成了周末の任务2333
具体实现:
1: 实现了在ListView中浏览本地所有文件.
实现原理:
使用了栈结构保存当前的文件路径,每一次点击文件夹,就会把当前文件名推入栈组成新的文件路径。
实现得到当前栈路径的方法:
//得到当前栈路径的Stringprivate String getPathString() {Stack<String> temp = new Stack<>();temp.addAll(nowPathStack);String result = "";while (temp.size() != 0) {result = temp.pop() + result;}return result;}
在item的onItemClick方法中将点击的文件名推入栈:
//如果是文件夹// 清除列表数据// 获得目录中的内容,计入列表中// 适配器通知数据集改变nowPathStack.push("/" + file.getName());showChangge(getPathString());
显示改变路径之后的listview文件列表:
//显示改变data之后的文件数据列表private void showChangge(String path) {showtv.setText(path);files = new File(path).listFiles();data.clear();for (File f : files) {data.add(f);}files = fileAdapter.setfiledata(data);}
2: 实现了对文件的增(新建文件夹)
实现原理:
根据当前路径,以及通过dialog得到的用户输入的文件名执行新建文件夹的操作:
/*** 创建新文件夹*/private void doCreateNewFolder() {mydialog = new AlertDialog.Builder(MainActivity.this).create();mydialog.show();mydialog.getWindow().setContentView(R.layout.newfloder_dialog);mydialog.setView(new EditText(MainActivity.this));//加入下面两句以后即可弹出输入法mydialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);mydialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);newfloder_name = (EditText) mydialog.getWindow().findViewById(R.id.newfloder_name);mydialog.getWindow().findViewById(R.id.newfloder_cancle).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mydialog.dismiss();}});mydialog.getWindow().findViewById(R.id.newfloder_create).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String name = newfloder_name.getText().toString();if (name != null) {File folder = new File(getPathString() + "/" + name);folder.mkdirs();if (folder.exists()) {Toast.makeText(MainActivity.this,"文件:"+name + " 创建成功",Toast.LENGTH_SHORT).show();showChangge(getPathString());mydialog.dismiss();}}}});}
3: 删(删除文件或文件夹).
在adapter中直接执行删除操作:
/*** 删除*/private void doRemove() {final File file = filedata.get(position);judgeAlertDialog(context, "提醒", "你确认删除" + file.getName() + "吗(不可逆)?", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {deleteDir(file);filedata.remove(file);notifyDataSetChanged();showToast(file.getName() + " 删除成功");}}, null);}
4: 改(重命名以及复制粘贴文件).
实现原理:
1、重命名
在adapter中直接执行重命名操作:
/*** 重命名*/private void doRename() {showToast("重命名" + position);RenameFileDialog dialog = new RenameFileDialog(context, filedata, position);dialog.setOnFileRenameListener(new RenameFileDialog.OnFileRenameListener() {@Overridepublic void onFileRenamed(boolean success) {String message = null;if (filedata.get(position).isFile()) {message = "文件";} else {message = "文件夹";}if (success) {message += "重命名成功";} else {message += "重命名失败";}showToast(message);}});dialog.show();setfiledata(filedata);}
2、复制文件:
如下图所示:
使用了简单的回调执行复制操作,在FileAdapter定义复制接口,然后在MainActivity中实现接口,并通过setListener将自身实例传入FileAdapter,从而实现在FileAdapter中执行复制操作。
MainActivity中的粘贴操作实现如下:
/*** 复制或粘贴*/private void doPaste() {File newFile = new File(getPathString()+"/"+watingCopyFile.getName());if (watingCopyFile.equals(null)) {Snackbar.make(findViewById(R.id.main_view), "当前粘贴板为空,不能粘贴", Snackbar.LENGTH_SHORT).show();} else {if (watingCopyFile.isFile()&&watingCopyFile.exists()){try {FileInputStream fis = new FileInputStream(watingCopyFile);FileOutputStream fos = new FileOutputStream(newFile);int len = -1;long contentSize = watingCopyFile.length();long readed = 0;byte[] buff = new byte[8192];while ((len=fis.read(buff))!=-1){//写文件fos.write(buff,0,len);readed+=len;//发布进度}fos.flush();fis.close();fos.close();} catch (IOException e) {e.printStackTrace();} finally {}}if (newFile.exists()) {Toast.makeText(MainActivity.this,"复制" + newFile.getName() + "成功",Toast.LENGTH_SHORT).show();fileAdapter.notifyDataSetChanged();}}}
5: 查(对当前路径下的递归查询).
实现原理:
data = new ArrayList<>();searchfilemap = new HashMap<>();searchByPath(path);if (searchfilemap.size() > 0) {//取出map中数据,赋值给dataObject[] list = searchfilemap.entrySet().toArray();for (int i = 0; i < searchfilemap.size(); i++) {data.add(new File(list[i].toString()));}}
通过递归查找本地所有文件,寻找匹配输入字符query的文件名的文件,并全部显示在listview上。
递归方法:
/*** 通过路径递归查找文件* @param path*/private void searchByPath(String path) {File[] files = new File(path).listFiles();filenum += files.length;publishProgress(filenum);for (int i = 0; i < files.length; i++) {File f = files[i];if (f.isDirectory()) {searchByPath(path + "/" + f.getName());} else {if (f.getName().contains(query)) {searchfilemap.put(files[i], files[i].getName());}}}}
6:排(对显示在listView中的文件按时间,大小或文件名排序)
实现方法使用杨羿的方式,通过对文件种类进行分类比较实现排序:
首先需要一个格式工厂类:
public class FileSortFactory {public static final int SORT_BY_FOLDER_AND_NAME = 1;public static final int SORT_BY_FOLDER_REVERSE_AND_NAME = 2;public static final int SORT_BY_FOLDER_AND_NAME_REVERSE = 3;public static final int SORT_BY_FOLDER_REVERSE_AND_NAME_REVERSE = 4;public static final int SORT_BY_FOLDER_AND_SIZE = 5;public static final int SORT_BY_FOLDER_REVERSE_AND_SIZE = 6;public static final int SORT_BY_FOLDER_AND_SIZE_REVERSE = 7;public static final int SORT_BY_FOLDER_REVERSE_AND_SIZE_REVERSE = 8;public static final int SORT_BY_FOLDER_AND_TIME = 9;public static final int SORT_BY_FOLDER_REVERSE_AND_TIME = 10;public static final int SORT_BY_FOLDER_AND_TIME_REVERSE = 11;public static final int SORT_BY_FOLDER_REVERSE_AND_TIME_REVERSE = 12;public static Comparator<File> getWebFileQueryMethod(int method) {switch (method) {case SORT_BY_FOLDER_AND_NAME:return new SortByFolderAndName(true, true);case SORT_BY_FOLDER_REVERSE_AND_NAME:return new SortByFolderAndName(false, true);case SORT_BY_FOLDER_AND_NAME_REVERSE:return new SortByFolderAndName(true, false);case SORT_BY_FOLDER_REVERSE_AND_NAME_REVERSE:return new SortByFolderAndName(false, false);case SORT_BY_FOLDER_AND_SIZE:return new SortByFolderAndSize(true, true);case SORT_BY_FOLDER_REVERSE_AND_SIZE:return new SortByFolderAndSize(false, true);case SORT_BY_FOLDER_AND_SIZE_REVERSE:return new SortByFolderAndSize(true, false);case SORT_BY_FOLDER_REVERSE_AND_SIZE_REVERSE:return new SortByFolderAndSize(false, false);case SORT_BY_FOLDER_AND_TIME:return new SortByFolderAndTime(true, true);case SORT_BY_FOLDER_REVERSE_AND_TIME:return new SortByFolderAndTime(false, true);case SORT_BY_FOLDER_AND_TIME_REVERSE:return new SortByFolderAndTime(true, false);case SORT_BY_FOLDER_REVERSE_AND_TIME_REVERSE:return new SortByFolderAndTime(false, false);default:break;}return null;}
}
之后再对应的具体排序方法类(这里只列出一种):
public class SortByFolderAndName implements Comparator<File> {boolean first;boolean second;public SortByFolderAndName(boolean first,boolean second) {this.first = first;this.second = second;}@Overridepublic int compare(File lhs, File rhs) {if (first) {if (!lhs.isFile() && rhs.isFile()) {return -1;}if (lhs.isFile() && !rhs.isFile()) {return 1;}} else {if (!lhs.isFile() && rhs.isFile()) {return 1;}if (lhs.isFile() && !rhs.isFile()) {return -1;}}if (second) {if (!(lhs.isFile() ^ rhs.isFile())) {return lhs.getName().compareTo(rhs.getName());}} else {if (!(lhs.isFile() ^ rhs.isFile())) {return -lhs.getName().compareTo(rhs.getName());}}return 0;}}
最后,在Adapter中通过排序方法实现对所有文件的排序:
/*** 将文件列表排序*/private void sort() {Collections.sort(this.filedata, FileSortFactory.getWebFileQueryMethod(sortWay));}
*************************************(づ ̄ 3 ̄)づ完结收工****************************************************************
以上,就是这两天の战斗成果总结了。
话说这两天碰到的坑实在太多,先是Github提交以后不显示进度点,折腾了好久才发现是邮箱写错了!
编码过程中倒是没有太大的难点,虽然这个项目比较简单但是也把以前学过的东西很好的复习了一遍。
但是还是平时练得太少了!!!很多东西很久不用就忘掉了~!
orz,哎好想找个实习充实自己~~~2333(残念脸)
Android本地文件管理器思路解析一一增删改查具体实现相关推荐
- ExtJS EditorGridPanel 示例之Array格式(自定义Array解析器)Store前后台增删改查
本示例入口html页面: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http: ...
- 对xml文件的sax解析(增删改查)之一
crud(增删改查): c:creat r:retrieve u:update d:delete 以下笔记来自于韩顺平老师的讲解. 现在是用java来操作. 第一步:新建java工程.file-new ...
- Android中数据库的一些操作(增删改查)
提起Android的开发,就不得不提数据库,几乎每个App中都会用到Sqlit数据库存储一些数据,小编闲暇时期,写了一个小demo关于数据库的增删改查,之前也介绍过数据库的一个开源框架ORMLite, ...
- Android整合SQLite数据库进行基本的增删改查
简言 使用Android整合SQLite数据库进行数据存储,大致可以划分为三步: ①继承 SQLiteOpenHelper,创建数据库 ②继承 ContentProvider 类,重写方法 ③在清单文 ...
- XML解析以及增删改查的操作6
有一个字符串操作类StringUtil要贴出来,之前代码里用到: public class StringUtil {public static final String BLANKS = " ...
- android中对sim卡联系人的增删改查以及监听sim卡联系数据的改变
sim卡联系人的增删改查主要是通过ContentProvider来进行操作的,在android中对sim卡联系人操作的provider是定义在IccProvider.java这个类中的,这个类位于an ...
- Android中访问通讯录,数据的增删改查
1.权限 <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-pe ...
- C# 使用自定义类+字典+JSON填充数据,脱离真实数据库,实现简单的增删改查和本地存储与读取数据
前言 这个文章将不会用到数据库,另辟蹊径去实现本地的存储与读取,增删改查!~ 之前写项目用到的思路,因为是非常小的项目,不想依赖数据库来增删改查,以此避免复杂的数据库环境支持和安装.之前想上网查找有没 ...
- Python写一个账号密码小助手(包含增删改查功能)
背景 随着现在的应用越来越多,人们注册账号密码的数量也越来越多,很多时候,我都不记得这个平台有没有创建账号密码,这是第一点.还有一点就是,因为很多人不愿意记很多个密码,或者也记不住很多个密码,导致很多 ...
最新文章
- VS中C#读取app.config数据库配置字符串的三种方法(转)
- 用js判断时间的先后顺序
- 框架:Spring Aop、拦截器、过滤器的区别
- python作业网站_python大作业
- 编程求以孩子兄弟表示法存储的森林的叶子结点数☆
- .NET平台4.0 发布网站流程及出错总结
- 19款探岳刷隐藏教程_三星S10系列如何隐藏导航栏 官微“手把手”教你设置
- LongAdder源码分析
- Java 8 中的 CompletableFuture 太好用了!20 个示例全分享…
- 阶段2 JavaWeb+黑马旅游网_15-Maven基础_第5节 使用骨架创建maven的java工程_13使用骨架创建maven的web工程...
- 自己写代码解析工具的注意事项
- ios 纯代码 图标排列
- 从命令行安装IIS 7.0
- MySQL修改表字段的长度
- 2019年上半年软件设计师上午试题及答案
- 阿里云弹性手机购买与配置
- 数字系统设计中形式验证
- Span 介绍及使用(一)
- 【Alpha】第二次Daily Scrum Meeting
- Snowflake生成的ID是全局递增唯一么?怎么实现全局递增的唯一ID?