文件选择器
今天给大家分享下文件选择器的作用 , 具体就是获取用户在在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();
}
});
}
}
|