文件选择器
今天给大家分享下文件选择器的作用 , 具体就是获取用户在在sd卡选中的文件/文件夹路径 ,类似于c#中openfiledialog控件(对c#的一站式开发还是念念不忘)。功能实现起来比较简单,主要是帮助大家节省开发时间。
网上流传较广的一个成品如下 <[android实例] 文件选择器>, 本文也是根据上面的成品修改而成,使其更易理解,效率更高。 除此之外,主要特色有:
1、我们监听了用户按下back键的事件,使其返回上一层目录;
2、针对不同的文件类型(文件vs文件夹 , 目标文件vs其他文件)做了特殊处理。
知识点一、 file 类的使用
文件选择器的主要功能是:浏览文件文件夹、文件类型等;都是通过java file类来实现的。
知识点二、调用方法说明
使用了startactivityforresult()发起调用以及onactivityresult()方法接受回调后的信息。
截图如下:
其他的也没什么好说了,大家看看代码注释吧~~ so easy - - 。
filechooseractivity.java 实现文件选择的类 。
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
public class copyoffilechooseractivity extends activity { private string msdcardrootpath ; //sdcard 根路径 private string mlastfilepath ; //当前显示的路径 private arraylist<fileinfo> mfilelists ; private filechooseradapter madatper ; //配置适配器 private void setgridviewadapter(string filepath) { updatefileitems(filepath); madatper = new filechooseradapter( this , mfilelists); mgridview.setadapter(madatper); } //根据路径更新数据,并且通知adatper数据改变 private void updatefileitems(string filepath) { mlastfilepath = filepath ; mtvpath.settext(mlastfilepath); if (mfilelists == null ) mfilelists = new arraylist<fileinfo>() ; if (!mfilelists.isempty()) mfilelists.clear() ; file[] files = folderscan(filepath); if (files == null ) return ; for ( int i = 0 ; i < files.length; i++) { if (files[i].ishidden()) // 不显示隐藏文件 continue ; string fileabsolutepath = files[i].getabsolutepath() ; string filename = files[i].getname(); boolean isdirectory = false ; if (files[i].isdirectory()){ isdirectory = true ; } fileinfo fileinfo = new fileinfo(fileabsolutepath , filename , isdirectory) ; //添加至列表 mfilelists.add(fileinfo); } //when first enter , the object of madatper don't initialized if (madatper != null ) madatper.notifydatasetchanged(); //重新刷新 } //获得当前路径的所有文件 private file[] folderscan(string path) { file file = new file(path); file[] files = file.listfiles(); return files; } private adapterview.onitemclicklistener mitemclicklistener = new onitemclicklistener() { public void onitemclick(adapterview<?> adapterview, view view, int position, long id) { fileinfo fileinfo = (fileinfo)(((filechooseradapter)adapterview.getadapter()).getitem(position)); if (fileinfo.isdirectory()) //点击项为文件夹, 显示该文件夹下所有文件 updatefileitems(fileinfo.getfilepath()) ; else if (fileinfo.ispptfile()){ //是ppt文件 , 则将该路径通知给调用者 intent intent = new intent(); intent.putextra(extra_file_chooser, fileinfo.getfilepath()); setresult(result_ok , intent); finish(); } else { //其他文件..... toast(gettext(r.string.open_file_error_format)); } } }; public boolean onkeydown( int keycode , keyevent event){ if (event.getaction() == keyevent.action_down && event.getkeycode() == keyevent.keycode_back){ backprocess(); return true ; } return super .onkeydown(keycode, event); } //返回上一层目录的操作 public void backprocess(){ //判断当前路径是不是sdcard路径 , 如果不是,则返回到上一层。 if (!mlastfilepath.equals(msdcardrootpath)) { file thisfile = new file(mlastfilepath); string parentfilepath = thisfile.getparent(); updatefileitems(parentfilepath); } else { //是sdcard路径 ,直接结束 setresult(result_canceled); finish(); } } } |
界面依旧很丑陋,囧 ,大家可以根据需要在此基础上添加功能,下面选择目录也基本上同理。
目录选择器
chooserdialog.xml
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
|
<?xml version= "1.0" encoding= "utf-8" ?> <linearlayout xmlns:android= "http://schemas.android.com/apk/res/android" android:orientation= "vertical" android:layout_width= "fill_parent" android:layout_height= "fill_parent" > <linearlayout android:orientation= "horizontal" android:layout_width= "fill_parent" android:layout_height= "40dip" > <button android:layout_width= "40dip" android:layout_height= "40dip" android:text= "home" android:id= "@+id/btn_home" android:layout_gravity= "left" android:layout_weight= "1" /> <linearlayout android:layout_width= "140dip" android:layout_height= "35dip" android:id= "@+id/dir_layout" android:gravity= "center" android:layout_weight= "1" > </linearlayout> <!-- <textview android:layout_width= "140dip" android:layout_height= "35dip" android:id= "@+id/dir_str" android:gravity= "center" android:layout_weight= "1" /> --> <button android:layout_width= "40dip" android:layout_height= "40dip" android:text= "back" android:id= "@+id/btn_back" android:layout_gravity= "right" android:layout_weight= "1" /> </linearlayout> <listview android:layout_width= "fill_parent" android:layout_height= "300dip" android:id= "@+id/list_dir" /> <button android:layout_width= "fill_parent" android:layout_height= "wrap_content" android:id= "@+id/btn_ok" android:text= "ok" /> </linearlayout> |
-
package hkp.dirchooser;
-
import java.io.file;
-
import java.util.arraylist;
-
import java.util.list;
-
-
import android.app.dialog;
-
import android.content.context;
-
import android.os.bundle;
-
import android.os.environment;
-
import android.os.handler;
-
import android.view.gravity;
-
import android.view.view;
-
import android.widget.adapterview;
-
import android.widget.adapterview.onitemclicklistener;
-
import android.widget.arrayadapter;
-
import android.widget.button;
-
import android.widget.edittext;
-
import android.widget.linearlayout;
-
import android.widget.listview;
-
import android.widget.textview;
-
import android.widget.toast;
-
-
-
public class dirchooserdialog extends dialog implements android.view.view.onclicklistener{
-
-
private listview list;
-
arrayadapter<string> adapter;
-
arraylist<string> arr=new arraylist<string>();
-
-
context context;
-
private string path;
-
-
private textview title;
-
private edittext et;
-
private button home,back,ok;
-
private linearlayout titleview;
-
-
private int type = 1;
-
private string[] filetype = null;
-
-
public final static int typeopen = 1;
-
public final static int typesave = 2;
-
-
/**
-
* @param context
-
* @param type 值为1表示创建打开目录类型的对话框,2为创建保存文件到目录类型的对话框
-
* @param filetype 要过滤的文件类型,null表示只选择目录
-
* @param resultpath 点ok按钮返回的结果,目录或者目录+文件名
-
*/
-
public dirchooserdialog(context context,int type,string[]filetype,string resultpath) {
-
super(context);
-
// todo auto-generated constructor stub
-
this.context = context;
-
this.type = type;
-
this.filetype = filetype;
-
this.path = resultpath;
-
}
-
/* (non-javadoc)
-
* @see android.app.dialog#dismiss()
-
*/
-
@override
-
public void dismiss() {
-
// todo auto-generated method stub
-
super.dismiss();
-
}
-
/* (non-javadoc)
-
* @see android.app.dialog#oncreate(android.os.bundle)
-
*/
-
@override
-
protected void oncreate(bundle savedinstancestate) {
-
// todo auto-generated method stub
-
super.oncreate(savedinstancestate);
-
setcontentview(r.layout.chooserdialog);
-
-
path = getrootdir();
-
arr = (arraylist<string>) getdirs(path);
-
adapter = new arrayadapter<string>(context,android.r.layout.simple_list_item_1, arr);
-
-
list = (listview)findviewbyid(r.id.list_dir);
-
list.setadapter(adapter);
-
-
list.setonitemclicklistener(lvlis);
-
-
home = (button) findviewbyid(r.id.btn_home);
-
home.setonclicklistener(this);
-
-
back = (button) findviewbyid(r.id.btn_back);
-
back.setonclicklistener(this);
-
-
ok = (button) findviewbyid(r.id.btn_ok);
-
ok.setonclicklistener(this);
-
-
titleview = (linearlayout) findviewbyid(r.id.dir_layout);
-
-
if(type == typeopen){
-
title = new textview(context);
-
titleview.addview(title);
-
title.settext(path);
-
}else if(type == typesave){
-
et = new edittext(context);
-
et.setwidth(240);
-
et.setheight(70);
-
et.setgravity(gravity.center);
-
et.setpadding(0, 2, 0, 0);
-
titleview.addview(et);
-
et.settext("wffilename");
-
}
-
// title = (textview) findviewbyid(r.id.dir_str);
-
// title.settext(path);
-
-
}
-
//动态更新listview
-
runnable add=new runnable(){
-
-
@override
-
public void run() {
-
// todo auto-generated method stub
-
arr.clear();
-
//system.out.println("runnable path:"+path);
-
-
//必须得用这种方法为arr赋值才能更新
-
list<string> temp = getdirs(path);
-
for(int i = 0;i < temp.size();i++)
-
arr.add(temp.get(i));
-
adapter.notifydatasetchanged();
-
}
-
};
-
-
private onitemclicklistener lvlis=new onitemclicklistener(){
-
@override
-
public void onitemclick(adapterview<?> arg0, view arg1, int arg2,
-
long arg3) {
-
string temp = (string) arg0.getitematposition(arg2);
-
//system.out.println("onitemclick path1:"+path);
-
if(temp.equals(".."))
-
path = getsubdir(path);
-
else if(path.equals("/"))
-
path = path+temp;
-
else
-
path = path+"/"+temp;
-
-
//system.out.println("onitemclick path2"+path);
-
if(type == typeopen)
-
title.settext(path);
-
-
handler handler=new handler();
-
handler.post(add);
-
}
-
};
-
-
private list<string> getdirs(string ipath){
-
list<string> file = new arraylist<string>();
-
//system.out.println("getdirs path:"+ipath);
-
file[] myfile = new file(ipath).listfiles();
-
if(myfile == null){
-
file.add("..");
-
-
}else
-
for(file f: myfile){
-
//过滤目录
-
if(f.isdirectory()){
-
string tempf = f.tostring();
-
int pos = tempf.lastindexof("/");
-
string subtemp = tempf.substring(pos+1, tempf.length());
-
// string subtemp = tempf.substring(path.length(),tempf.length());
-
file.add(subtemp);
-
//system.out.println("files in dir:"+subtemp);
-
}
-
//过滤知道类型的文件
-
if(f.isfile() && filetype != null){
-
for(int i = 0;i< filetype.length;i++){
-
int typestrlen = filetype[i].length();
-
-
string filename = f.getpath().substring(f.getpath().length()- typestrlen);
-
if (filename.tolowercase().equals(filetype[i])) {
-
file.add(f.tostring().substring(path.length()+1,f.tostring().length()));
-
}
-
}
-
}
-
}
-
-
if(file.size()==0)
-
file.add("..");
-
-
// system.out.println("file[0]:"+file.get(0)+" file size:"+file.size());
-
return file;
-
}
-
/* (non-javadoc)
-
* @see android.view.view.onclicklistener#onclick(android.view.view)
-
*/
-
@override
-
public void onclick(view v) {
-
// todo auto-generated method stub
-
if(v.getid() == home.getid()){
-
path = getrootdir();
-
if(type == typeopen)
-
title.settext(path);
-
handler handler=new handler();
-
handler.post(add);
-
}else if(v.getid() == back.getid()){
-
path = getsubdir(path);
-
if(type == typeopen)
-
title.settext(path);
-
handler handler=new handler();
-
handler.post(add);
-
}else if(v.getid() == ok.getid()){
-
dismiss();
-
if(type == typesave)
-
path = path+"/"+et.geteditabletext().tostring()+".wf";
-
toast.maketext(context, path, toast.length_short).show();
-
}
-
-
-
}
-
-
private string getsdpath(){
-
file sddir = null;
-
boolean sdcardexist = environment.getexternalstoragestate()
-
.equals(android.os.environment.media_mounted); //判断sd卡是否存在
-
if(sdcardexist)
-
{
-
sddir = environment.getexternalstoragedirectory();//获取根目录
-
}
-
if(sddir == null){
-
//toast.maketext(context, "no sdcard inside!",toast.length_short).show();
-
return null;
-
}
-
return sddir.tostring();
-
-
}
-
-
private string getrootdir(){
-
string root = "/";
-
-
path = getsdpath();
-
if (path == null)
-
path="/";
-
-
return root;
-
}
-
-
private string getsubdir(string path){
-
string subpath = null;
-
-
int pos = path.lastindexof("/");
-
-
if(pos == path.length()){
-
path = path.substring(0,path.length()-1);
-
pos = path.lastindexof("/");
-
}
-
-
subpath = path.substring(0,pos);
-
-
if(pos == 0)
-
subpath = path;
-
-
return subpath;
-
}
-
}
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
|
package hkp.dirchooser; import android.app.activity; import android.os.bundle; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; public class mainactivity extends activity { /** called when the activity is first created. */ @override public void oncreate(bundle savedinstancestate) { super .oncreate(savedinstancestate); setcontentview(r.layout.main); button btn = (button) findviewbyid(r.id.btn_open); btn.setonclicklistener( new onclicklistener() { @override public void onclick(view v) { // todo auto-generated method stub string path = null ; string [] filetype = { "dst" }; //要过滤的文件类型列表 dirchooserdialog dlg = new dirchooserdialog(mainactivity. this , 2 ,filetype,path); dlg.settitle( "choose dst file dir" ); dlg.show(); } }); } } |