Android 自定義檔案路徑選擇器
阿新 • • 發佈:2019-02-05
文中涉及到檔名稱排序,固定根目錄以及返回上一層在上面,方便選擇等。根據檔案字尾,篩選檔案還沒做。先看效果。
1、效果圖
2、核心程式碼如下
是通過繼承BaseAdapter 完成的,裡面有自定義layout介面。進行管理返回跟目錄以及上一層,方便管理。
package com.filebrowser; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; import java.io.File; import java.io.FileFilter; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; public class MyAdapter extends BaseAdapter implements View.OnClickListener, AdapterView.OnItemClickListener { private String rootPath; private LayoutInflater mInflater; private Bitmap mIcon3; private Bitmap mIcon4; private List<File> fileList; private View header; private View layoutReturnRoot; private View layoutReturnPre; private TextView curPathTextView; private String suffix = ""; private String currentDirPath; private FileSelectListener listener; public MyAdapter(View fileSelectListView, String rootPath, String defaultPath) { this.rootPath = rootPath; Context context = fileSelectListView.getContext(); mInflater = LayoutInflater.from(context); mIcon3 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon_fodler); mIcon4 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon_file); curPathTextView = (TextView) fileSelectListView.findViewById(R.id.curPath); header = fileSelectListView.findViewById(R.id.layoutFileListHeader); layoutReturnRoot = fileSelectListView.findViewById(R.id.layoutReturnRoot); layoutReturnPre = fileSelectListView.findViewById(R.id.layoutReturnPre); layoutReturnRoot.setOnClickListener(this); layoutReturnPre.setOnClickListener(this); if (defaultPath != null && !defaultPath.isEmpty()) { getFileDir(defaultPath); } else { getFileDir(rootPath); } ListView listView = (ListView) fileSelectListView.findViewById(R.id.list); listView.setAdapter(this); listView.setOnItemClickListener(this); } private class ViewHolder { TextView text; ImageView icon; } public interface FileSelectListener { void onFileSelect(File selectedFile); void onDirSelect(File selectedDir); } public void setOnFileSelectListener(FileSelectListener listener) { this.listener = listener; } /** * 獲取所選檔案路徑下的所有檔案,並且更新到listview中 */ private void getFileDir(String filePath) { File file = new File(filePath); File[] files = file.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { if (pathname.isFile()&&!suffix.isEmpty()){ return pathname.getName().endsWith(suffix); } return true; } }); fileList = Arrays.asList(files); //按名稱排序 Collections.sort(fileList, new Comparator<File>() { @Override public int compare(File o1, File o2) { if (o1.isFile() && o2.isDirectory()) return 1; if (o1.isDirectory() && o2.isFile()) return -1; return o1.getName().compareTo(o2.getName()); } }); if (header != null) { header.setVisibility(filePath.equals(rootPath) ? View.GONE : View.VISIBLE); } notifyDataSetChanged(); if (curPathTextView != null) { curPathTextView.setText(filePath); } currentDirPath = filePath; if (listener!=null){ listener.onDirSelect(file); } } public int getCount() { return fileList.size(); } public Object getItem(int position) { return fileList.get(position); } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.file_item, null); holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.text); holder.icon = (ImageView) convertView.findViewById(R.id.icon); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } File file = fileList.get(position); holder.text.setText(file.getName()); if (file.isDirectory()) { holder.icon.setImageBitmap(mIcon3); } else { holder.icon.setImageBitmap(mIcon4); } return convertView; } @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { File file = fileList.get(position); if (file.isDirectory()) { getFileDir(file.getPath()); } else { if (listener!=null){ listener.onFileSelect(file); } } } @Override public void onClick(View v) { if (v.getId() == R.id.layoutReturnRoot) { getFileDir(rootPath); } else if (v.getId() == R.id.layoutReturnPre) { getFileDir(new File(currentDirPath).getParent()); } } }
使用的佈局如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:background="@color/white" android:layout_height="wrap_content"> <LinearLayout android:id="@+id/layoutFileSelectList" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="10dp" android:orientation="vertical" android:showDividers="middle|end"> <TextView android:id="@+id/curPath" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="6dp" android:paddingLeft="10dp" android:textSize="16sp" /> <LinearLayout android:id="@+id/layoutFileListHeader" android:layout_width="match_parent" android:layout_height="wrap_content" android:divider="@drawable/shape_divider_line" android:showDividers="beginning|middle|end" android:orientation="vertical"> <LinearLayout android:id="@+id/layoutReturnRoot" android:layout_width="match_parent" android:layout_height="50dp" android:paddingLeft="10dp" android:gravity="center" android:orientation="horizontal"> <ImageView android:id="@+id/iv_return_root" android:layout_width="30dp" android:layout_height="30dp" android:background="@drawable/icon_back"> </ImageView> <TextView android:id="@+id/tv_return_root" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_vertical" android:paddingLeft="10dp" android:text="@string/ReturnRootDir" android:textSize="16sp"> </TextView> </LinearLayout> <LinearLayout android:id="@+id/layoutReturnPre" android:layout_width="match_parent" android:layout_height="50dp" android:paddingLeft="10dp" android:gravity="center" android:orientation="horizontal"> <ImageView android:id="@+id/iv_return_pre" android:layout_width="30dp" android:layout_height="30dp" android:background="@drawable/icon_back02"> </ImageView> <TextView android:id="@+id/tv_return_pre" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center_vertical" android:paddingLeft="10dp" android:text="@string/ReturnPreDir" android:textSize="16sp"> </TextView> </LinearLayout> </LinearLayout> <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> </LinearLayout> </LinearLayout>
呼叫方式
package com.filebrowser; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.TextView; import java.io.File; public class FileBrowserActivity extends Activity implements View.OnClickListener, MyAdapter.FileSelectListener { private TextView curPathTextView; private String rootPath = ""; private MyAdapter listAdapter; //初始化進入的目錄,預設目錄 private String filePath = ""; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_file_browser_acitivity); initView(); //跟目錄 rootPath = getIntent().getStringExtra("rootPath"); //指定資料夾 filePath = getIntent().getStringExtra("path"); curPathTextView.setText(filePath); filePath = filePath.isEmpty() ? rootPath : filePath; View layoutFileSelectList = findViewById(R.id.layoutFileSelectList); listAdapter = new MyAdapter(layoutFileSelectList, rootPath, filePath); listAdapter.setOnFileSelectListener(this); findViewById(R.id.btnSure).setOnClickListener(this); findViewById(R.id.btnCancel).setOnClickListener(this); } @Override public void finish() { Intent intent = new Intent(); intent.putExtra("file", filePath); setResult(RESULT_OK, intent); super.finish(); } private void initView() { curPathTextView = (TextView) findViewById(R.id.curPath); } @Override public void onFileSelect(File selectedFile) { filePath = selectedFile.getPath(); } @Override public void onDirSelect(File selectedDir) { filePath = selectedDir.getPath(); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.btnSure: finish(); break; case R.id.btnCancel: filePath =""; finish(); break; default: break; } } }
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layoutProgramManagerMainView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true"
android:orientation="vertical">
<include
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
layout="@layout/layout_file_select_list"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="bottom"
android:layout_weight="0"
android:orientation="vertical"
android:showDividers="beginning">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="@+id/btnCancel"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="@string/cancel"
android:textSize="16sp" />
<Button
android:id="@+id/btnSure"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1"
android:text="@string/sure"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
返回選擇的目錄
package com.filebrowser;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.storage.StorageManager;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale;
public class MainActivity extends Activity {
public static final int FILE_RESULT_CODE = 1;
private Button btn_open;
private TextView changePath;
private String rootPath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initListener();
}
private void initView() {
btn_open = (Button) findViewById(R.id.btn_open);
changePath = (TextView) findViewById(R.id.changePath);
}
private void initListener() {
btn_open.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openBrowser();
}
});
findViewById(R.id.btn_open1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
openBrowser1();
}
});
}
private void openBrowser() {
rootPath = System.getenv("SECONDARY_STORAGE");
if (rootPath == null) {
rootPath = Environment.getExternalStorageDirectory().toString();
}
if ((rootPath.equals(Environment.getExternalStorageDirectory().toString()))) {
String filePath = rootPath + "/Android";
Intent intent = new Intent(MainActivity.this, FileBrowserActivity.class);
//根目錄
intent.putExtra("rootPath", rootPath);
//進去指定資料夾
intent.putExtra("path", filePath);
startActivityForResult(intent, FILE_RESULT_CODE);
}
}
private void openBrowser1() {
rootPath = getSdcardPath();
if (rootPath == null || rootPath.isEmpty()) {
rootPath = Environment.getExternalStorageDirectory().toString();
}
Intent intent = new Intent(MainActivity.this, FileBrowserActivity.class);
intent.putExtra("rootPath", rootPath);
intent.putExtra("path", rootPath);
startActivityForResult(intent, FILE_RESULT_CODE);
}
public String getSdcardPath() {
String sdcardPath = "";
String[] pathArr = null;
StorageManager storageManager = (StorageManager) getSystemService(STORAGE_SERVICE);
try {
Method getVolumePaths = storageManager.getClass().getMethod("getVolumePaths");
pathArr = (String[]) getVolumePaths.invoke(storageManager);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (pathArr != null && pathArr.length >= 3) {
sdcardPath = pathArr[1];
}
return sdcardPath;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (FILE_RESULT_CODE == requestCode) {
Bundle bundle = null;
if (data != null && (bundle = data.getExtras()) != null) {
String path = bundle.getString("file","");
if(!path.isEmpty()){
changePath.setText("選擇路徑為 : " + path);
}
}
}
}
}
3、最後肯定是許可權
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
其實後面可以封裝成一個自定義的view 進行繼承LinearLayout進行封裝即可。