使用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(); } }