因项目需要打开文件,因此做了一个打开文件的对话框,现在把这部分的代码共享出来了。 首先是一个回调接口,该接口在文件选择完毕的通知调用者进行如果何种操作。文件接口声明,如下: // filename: CallbackBundle.javapackage com.example.openfiledemo;import android.os.Bundle;// 简单的Bundle参数回调接口public interface CallbackBundle { abstract void callback(Bundle bundle);} 然后的打开文件对话框的一下封装:// filename: OpenFileDialog.javapackage com.example.openfiledemo;import java.io.File;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import android.app.Activity;import android.app.AlertDialog;import android.app.Dialog;import android.content.Context;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.Toast;import android.widget.AdapterView.OnItemClickListener;public class OpenFileDialog { public static String tag = 'OpenFileDialog'; static final public String sRoot = '/'; static final public String sParent = '..'; static final public String sFolder = '.'; static final public String sEmpty = ''; static final private String sOnErrorMsg = 'No rights to access!'; // 参数说明 // context:上下文 // dialogid:对话框ID // title:对话框标题 // callback:一个传递Bundle参数的回调接口 // suffix:需要选择的文件后缀,比如需要选择wav、mp3文件的时候设置为'.wav;.mp3;',注意最后需要一个分号(;) // images:用来根据后缀显示的图标资源ID。 // 根目录图标的索引为sRoot; // 父目录的索引为sParent; // 文件夹的索引为sFolder; // 默认图标的索引为sEmpty; // 其他的直接根据后缀进行索引,比如.wav文件图标的索引为'wav' public static Dialog createDialog(int id, Context context, String title, CallbackBundle callback, String suffix, Map images){ AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setView(new FileSelectView(context, id, callback, suffix, images)); Dialog dialog = builder.create(); //dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); dialog.setTitle(title); return dialog; } static class FileSelectView extends ListView implements OnItemClickListener{ private CallbackBundle callback = null; private String path = sRoot; private List<>> list = null; private int dialogid = 0; private String suffix = null; private Map imagemap = null; public FileSelectView(Context context, int dialogid, CallbackBundle callback, String suffix, Map images) { super(context); this.imagemap = images; this.suffix = suffix==null?'':suffix.toLowerCase(); this.callback = callback; this.dialogid = dialogid; this.setOnItemClickListener(this); refreshFileList(); } private String getSuffix(String filename){ int dix = filename.lastIndexOf('.'); if(dix<0){ return="" '';="" }="" else{="" return="" filename.substring(dix+1);="" }="" }="" private="" int="" getimageid(string="" s){="" if(imagemap="=" null){="" return="" 0;="" }="" else="" if(imagemap.containskey(s)){="" return="" imagemap.get(s);="" }="" else="" if(imagemap.containskey(sempty)){="" return="" imagemap.get(sempty);="" }="" else="" {="" return="" 0;="" }="" }="" private="" int="" refreshfilelist()="" {="" 刷新文件列表="" file[]="" files="null;" try{="" files="new" file(path).listfiles();="" }="" catch(exception="" e){="" files="null;" }="" if(files="=null){" 访问出错="" toast.maketext(getcontext(),="" soncgmsg,toast.length_short).show();="" return="" -1;="" }="" if(list="" !="null){" list.clear();="" }="" else{="" list="new">0){><>>(files.length); } // 用来先保存文件夹和文件夹的两个列表 ArrayList<>> lfolders = new ArrayList<>>(); ArrayList<>> lfiles = new ArrayList<>>(); if(!this.path.equals(sRoot)){ // 添加根目录 和 上一层目录 Map map = new HashMap(); map.put('name', sRoot); map.put('path', sRoot); map.put('img', getImageId(sRoot)); list.add(map); map = new HashMap(); map.put('name', sParent); map.put('path', path); map.put('img', getImageId(sParent)); list.add(map); } for(File file: files) { if(file.isDirectory() && file.listFiles()!=null){ // 添加文件夹 Map map = new HashMap(); map.put('name', file.getName()); map.put('path', file.getPath()); map.put('img', getImageId(sFolder)); lfolders.add(map); } else if(file.isFile()){ // 添加文件 String sf = getSuffix(file.getName()).toLowerCase(); if(suffix == null || suffix.length()==0 || (sf.length()>0 && suffix.indexOf('.'+sf+';')>=0)){ Map map = new HashMap(); map.put('name', file.getName()); map.put('path', file.getPath()); map.put('img', getImageId(sf)); lfiles.add(map); } } } list.addAll(lfolders); // 先添加文件夹,确保文件夹显示在上面 list.addAll(lfiles); //再添加文件 SimpleAdapter adapter = new SimpleAdapter(getContext(), list, R.layout.filedialogitem, new String[]{'img', 'name', 'path'}, new int[]{R.id.filedialogitem_img, R.id.filedialogitem_name, R.id.filedialogitem_path}); this.setAdapter(adapter); return files.length; } @Override public void onItemClick(AdapterView?> parent, View v, int position, long id) { // 条目选择 String pt = (String) list.get(position).get('path'); String fn = (String) list.get(position).get('name'); if(fn.equals(sRoot) || fn.equals(sParent)){ // 如果是更目录或者上一层 File fl = new File(pt); String ppt = fl.getParent(); if(ppt != null){ // 返回上一层 path = ppt; } else{ // 返回更目录 path = sRoot; } } else{ File fl = new File(pt); if(fl.isFile()){ // 如果是文件 ((Activity)getContext()).dismissDialog(this.dialogid); // 让文件夹对话框消失 // 设置回调的返回值 Bundle bundle = new Bundle(); bundle.putString('path', pt); bundle.putString('name', fn); // 调用事先设置的回调函数 this.callback.callback(bundle); return; } else if(fl.isDirectory()){ // 如果是文件夹 // 那么进入选中的文件夹 path = pt; } } this.refreshFileList(); } }}
下面是文件条目的一个布局(文件名:filedialogitem.xml): 下面是使用的例子:// filename: OpenFileDemo.javapackage com.example.openfiledemo;import java.util.HashMap;import java.util.Map;import android.os.Bundle;import android.app.Activity;import android.app.Dialog;import android.view.View;import android.view.View.OnClickListener;public class OpenFileDemo extends Activity { static private int openfileDialogId = 0; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_open_file_demo); // 设置单击按钮时打开文件对话框 findViewById(R.id.button_openfile).setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { showDialog(openfileDialogId); } }); } @Override protected Dialog onCreateDialog(int id) { if(id==openfileDialogId){ Map images = new HashMap(); // 下面几句设置各文件类型的图标, 需要你先把图标添加到资源文件夹 images.put(OpenFileDialog.sRoot, R.drawable.filedialog_root); // 根目录图标 images.put(OpenFileDialog.sParent, R.drawable.filedialog_folder_up); //返回上一层的图标 images.put(OpenFileDialog.sFolder, R.drawable.filedialog_folder); //文件夹图标 images.put('wav', R.drawable.filedialog_wavfile); //wav文件图标 images.put(OpenFileDialog.sEmpty, R.drawable.filedialog_root); Dialog dialog = OpenFileDialog.createDialog(id, this, '打开文件', new CallbackBundle() { @Override public void callback(Bundle bundle) { String filepath = bundle.getString('path'); setTitle(filepath); // 把文件路径显示在标题上 } }, '.wav;', images); return dialog; } return null; }}
工程源代码: https://pan.baidu.com/s/1mh7Z3YS 放两张效果图:![](http://image106.360doc.com/DownloadImg/2017/06/0411/100859245_1.png)
![](http://image106.360doc.com/DownloadImg/2017/06/0411/100859245_2.png)
|