使用ListView显示Android SD卡中的文件列表
父类布局activity_main.xml,子类布局line.xml(一个文件的单独存放)
运行截图:
程序结构:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.asus.gary03_text"> <!--AndroidManifest.xml获取手机存储卡权限--> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
package com.example.asus.gary03_text; import android.support.v7.app.AppCompatActivity; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.Button; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends AppCompatActivity { ListView listView; TextView textView; //记录当前的父文件夹 File currentParent; //记录当前目录路径下的所有文件的文件数组 File[] currentFiles; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //获取列出全部文件的ListView listView = (ListView)findViewById(R.id.list); textView = (TextView)findViewById(R.id.path); //获取系统的SD卡的目录 File root = new File("/mnt/sdcard/"); //如果SD卡存在 if(root.exists()){ currentParent = root; currentFiles = root.listFiles(); //使用当前目录下的全部文件、文件夹来填充ListView inflateListView(currentFiles); } //为ListView的列表项的单击事件绑定监听器 listView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub //用户单击了文件,直接返回,不做任何处理 if(currentFiles[arg2].isFile()) return; //获取用户单击的文件夹下的所有文件 File[] tmp = currentFiles[arg2].listFiles(); if(tmp == null || tmp.length == 0){ Toast.makeText(MainActivity.this, "当前路径不可访问或该路径下没有文件",Toast.LENGTH_SHORT).show(); } else{ //获取用户单击的列表项对应的文件夹,设为当前的父文件夹 currentParent = currentFiles[arg2]; //保存当前的父文件夹内的全部文件和文件夹 currentFiles = tmp; //再次更新ListView inflateListView(currentFiles); } } }); //获取上一级目录的按钮 Button parent = (Button)findViewById(R.id.parent); parent.setOnClickListener(new OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub try{ if(!currentParent.getCanonicalPath().equals("/mnt/sdcard")){ //获取上级目录 currentParent = currentParent.getParentFile(); //列出当前目录下所有文件 currentFiles = currentParent.listFiles(); //再次更新ListView inflateListView(currentFiles); } }catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }); } private void inflateListView(File[] files){ //创建一个List集合,List集合的元素是Map List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>(); for(int i = 0; i < files.length; i++){ Map<String, Object> listItem = new HashMap<String, Object>(); //如果当前File是文件夹,使用floder图标;否则使用file图标 if(files[i].isDirectory()){ listItem.put("icon", R.drawable.folder); } else{ listItem.put("icon", R.drawable.file); } listItem.put("fileName", files[i].getName()); //添加List项 listItems.add(listItem); } //创建一个SimpleAdapter SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.line, new String[]{"icon","fileName"}, new int[]{R.id.icon, R.id.file_name}); //为ListView设置Adapter listView.setAdapter(simpleAdapter); try{ textView.setText("当前路径为: " + currentParent.getCanonicalPath()); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }
<?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" > <!-- 显示当前路径的的文本框 --> <TextView android:id="@+id/path" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" /> <!-- 列出当前路径下所有文件的ListView --> <ListView android:id="@+id/list" android:layout_width="wrap_content" android:layout_height="wrap_content" android:divider="#000" /> <!-- 返回上一级目录的按钮 --> <Button android:id="@+id/parent" android:layout_width="180dp" android:layout_height="80dp" android:text="返回" android:paddingTop="20dp" android:layout_gravity="center"/> </LinearLayout>
<?xml version="1.0" encoding="UTF-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" > <!-- 定义一个ImageView,用于作为列表项的一部分。 --> <ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingLeft="10dp" /> <!-- 定义一个TextView,用于作为列表项的一部分。 --> <TextView android:id="@+id/file_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16dp" android:gravity="center_vertical" android:paddingLeft="10dp" android:paddingTop="10dp" android:paddingBottom="10dp" /> </LinearLayout>
一、获取手机存储卡权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
二、界面布局
activity_main.xml布局中
TextView中显示当前路径的的文本框,ListView列出当前路径下所有文件的ListView ,Button按钮返回上一级目录
link.xml布局中
ImageView和extView,用于作为列表项的一部分
三、实现程序功能
1、ListView列表的事件监听器
listView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub //用户单击了文件,直接返回,不做任何处理 if(currentFiles[arg2].isFile()) return; //获取用户单击的文件夹下的所有文件 File[] tmp = currentFiles[arg2].listFiles(); if(tmp == null || tmp.length == 0){ Toast.makeText(MainActivity.this, "当前路径不可访问或该路径下没有文件",Toast.LENGTH_SHORT).show(); } else{ //获取用户单击的列表项对应的文件夹,设为当前的父文件夹 currentParent = currentFiles[arg2]; //保存当前的父文件夹内的全部文件和文件夹 currentFiles = tmp; //再次更新ListView inflateListView(currentFiles); } } });
2、返回按键按钮
Button parent = (Button)findViewById(R.id.parent); parent.setOnClickListener(new OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub try{ if(!currentParent.getCanonicalPath().equals("/mnt/sdcard")){ //获取上级目录 currentParent = currentParent.getParentFile(); //列出当前目录下所有文件 currentFiles = currentParent.listFiles(); //再次更新ListView inflateListView(currentFiles); } }catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } }); }
3、用List集合存放文件,并且创建一个适配器SimpleAdapter
构造方法:SimpleAdapter(Contextcontext,List>data,intresource,String[]from,int[]to)
context:要使用的上下文环境。
data:是一个List>类型的集合对象,该集合中每个Map对象生成一个列表项。
resource:界面布局文件的ID,对应的布局文件作为列表项的组件。
from:是一个String[]类型的参数,该参数决定提取Map对象中哪些key对应的value来生成列表项。
to:该参数是一个int[]类型的参数,该参数决定填充哪些组件。
private void inflateListView(File[] files){ //创建一个List集合,List集合的元素是Map List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>(); for(int i = 0; i < files.length; i++){ Map<String, Object> listItem = new HashMap<String, Object>(); //如果当前File是文件夹,使用floder图标;否则使用file图标 if(files[i].isDirectory()){ listItem.put("icon", R.drawable.folder); } else{ listItem.put("icon", R.drawable.file); } listItem.put("fileName", files[i].getName()); //添加List项 listItems.add(listItem); } //创建一个SimpleAdapter SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.line, new String[]{"icon","fileName"}, new int[]{R.id.icon, R.id.file_name}); //为ListView设置Adapter listView.setAdapter(simpleAdapter); try{ textView.setText("当前路径为: " + currentParent.getCanonicalPath()); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); } }