本文主要介绍如何自定义显示手机sd卡当中的文件及文件夹,这样做的好处主要是能够自己定义文件夹和文件的图标样式,而且能够按照应用的需要设计选择的模式(本文介绍的是单选文件)。
第一步:创建ListView的自定义item文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp">
//用于显示文件和文件夹的图标
<ImageView
android:id="@+id/iv_icon"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="@dimen/interval_common"
android:layout_centerVertical="true"
android:src="@mipmap/ic_launcher_round"/>
//用于显示文件和文件夹的名称
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/colorPrimaryDark"
android:text="yinxinwdjwwwwwwwwwwwwww"
android:textSize="20sp"
android:layout_toRightOf="@+id/iv_icon"
android:layout_toLeftOf="@+id/iv_check"
android:layout_marginLeft="@dimen/interval_common"
android:layout_marginRight="@dimen/interval_common"
android:layout_centerVertical="true"
android:ellipsize="middle"
android:maxLines="1"/>
//用于显示文件被选中的图标,文件夹则不显示这个控件
<ImageView
android:id="@+id/iv_check"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentRight="true"
android:layout_marginRight="@dimen/interval_common"
android:layout_centerVertical="true"
android:src="@mipmap/ic_launcher"/>
</RelativeLayout>
</LinearLayout>
第二步:构建Adapter,这里采用的是itemview的方式。
Adapter文件
public class FileAdapter extends BaseAdapter {
private Context context;
private List<FileInfo> fileList;
public FileAdapter(Context context, List<FileInfo> fileList) {
this.context = context;
this.fileList = fileList;
}
@Override
public int getCount() {
return fileList.size();
}
@Override
public Object getItem(int position) {
return fileList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
FileInfo info = fileList.get(position);
FileItemView itemView;
if (convertView == null) {
itemView = new FileItemView(context);
} else {
itemView = (FileItemView) convertView;
}
itemView.bind(info);
itemView.setTag(info);
return itemView;
}
}
FileItemView类
public class FileItemView extends LinearLayout {
@BindView(R.id.tv_name)
TextView tvName;
@BindView(R.id.iv_icon)
ImageView ivIcon;
@BindView(R.id.iv_check)
ImageView ivCheck;
public FileItemView(Context context) {
super(context);
init();
}
public FileItemView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
public FileItemView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
inflate(getContext(), R.layout.item_file_adapter, this);
ButterKnife.bind(this);
}
public void bind(FileInfo info){
tvName.setText(info.getFile().getName());
if (info.getFile().isDirectory()){
ivIcon.setImageResource(R.mipmap.ic_launcher_round);
ivCheck.setVisibility(View.GONE);
}else {
/**
*这里可以根据文件的后缀名,设置对应文件的图标
**/
ivIcon.setImageResource(R.mipmap.ic_launcher);
ivCheck.setVisibility(View.VISIBLE);
if (info.isCheck()){
//设置文件选中时的图标
ivCheck.setImageResource(R.color.colorPrimary);
}else {
//设置文件未选中时的图标
ivCheck.setImageResource(R.color.colorAccent);
}
}
}
}
FileInfo类
public class FileInfo {
private File file;
private boolean isCheck;
public FileInfo(File file) {
this.file = file;
this.isCheck = false;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public boolean isCheck() {
return isCheck;
}
public void setCheck(boolean check) {
isCheck = check;
}
}
注:FileItemView当中的控件ID,采用的是BindView的方式,需要在gradle文件当中添加依赖
compile 'com.jakewharton:butterknife:8.4.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
第三步:在activity当中使用adapter
activity的layout文件,添加一个ListView控件即可
对应的xml文件
<ListView
android:id="@+id/lv_phone_file"
android:layout_width="match_parent"
android:layout_height="wrap_content"></ListView>
activity文件
public class InputFileActivity extends BaseActivity {
@BindView(R.id.lv_phone_file)
ListView lvFile;
private File currentFile;
private List<FileInfo> fileList = new ArrayList<>();
private FileAdapter fileAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_input_file);
ButterKnife.bind(this);
init();
}
private void init() {
//初始为sdcard内文件
currentFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
fileAdapter = new FileAdapter(InputFileActivity.this, fileList);
lvFile.setAdapter(fileAdapter);
lvFile.setOnItemClickListener(new LvItemClick());
refreshFile();
}
/**
* 刷新文件列表
*/
private void refreshFile() {
if (fileList != null) {
fileList.clear();
}
File files[] = currentFile.listFiles();
for (File file : files) {
fileList.add(new FileInfo(file));
}
fileAdapter.notifyDataSetChanged();
}
/**
* 返回上级文件
*/
private void goBack() {
File parent = currentFile.getParentFile();
if (parent == null || (currentFile.getAbsolutePath().equals(Environment.getExternalStorageDirectory().getAbsolutePath()))) {
InputFileActivity.this.finish();
} else {
if (currentFile.isFile()) {
currentFile = parent.getParentFile();
} else {
currentFile = parent;
}
refreshFile();
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
goBack();
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}
/**
* listview的item单击事件响应
*/
private class LvItemClick implements AdapterView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
FileInfo fileInfo = (FileInfo) view.getTag();
if (fileInfo.getFile().isFile()) {
if (fileInfo.isCheck()) {
fileInfo.setCheck(false);
} else {
for (FileInfo info : fileList) {
info.setCheck(false);
}
fileInfo.setCheck(true);
}
fileAdapter.notifyDataSetChanged();
} else {
currentFile = fileInfo.getFile();
refreshFile();
}
}
}
}
最后结果如下: