首先搭建activity_main.xml布局
搭建ListView中显示的布局
创建适配器
将File数据和UI适配
MainActivity中将ListView设置适配器,并设置监听
//获取SD卡根目录,必须获取权限,权限在AndroidManifest.xml/Permissions中添加
1、首先搭建activity_main.xml布局
文件目录置顶,给一个不同的颜色
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent" 4 android:orientation="vertical" > 5 6 <LinearLayout 7 android:id="@+id/ll_root" 8 android:layout_width="match_parent" 9 android:layout_height="wrap_content" 10 android:orientation="horizontal" > 11 12 <TextView 13 android:id="@+id/root" 14 android:layout_width="wrap_content" 15 android:layout_height="wrap_content" 16 android:background="@android:color/holo_green_light" 17 android:text="手机目录>" /> 18 </LinearLayout> 19 20 <ListView 21 android:id="@+id/lv" 22 android:layout_width="match_parent" 23 android:layout_height="match_parent" /> 24 25 </LinearLayout>
2、搭建ListView中显示的布局
左边显示图片,右边也是一个LinearLayout布局,上面显示文件名称,下面显示最后修改时间
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent" 4 android:layout_gravity="center" 5 android:orientation="horizontal" > 6 7 <ImageView 8 android:id="@+id/img" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:src="@drawable/folder" /> 12 13 <LinearLayout 14 android:layout_width="match_parent" 15 android:layout_height="wrap_content" 16 android:layout_marginLeft="10dp" 17 android:orientation="vertical" > 18 19 <TextView 20 android:id="@+id/name" 21 android:layout_width="wrap_content" 22 android:layout_height="wrap_content" 23 android:text="文件名" /> 24 25 <TextView 26 android:id="@+id/time" 27 android:layout_width="wrap_content" 28 android:layout_height="wrap_content" 29 android:layout_marginTop="10dp" 30 android:text="时间" /> 31 </LinearLayout> 32 33 </LinearLayout>
3、创建适配器
1 public class MyAdapter extends BaseAdapter { 2 Context context; 3 List<File> list; 4 5 public MyAdapter(Context context, List<File> list) { 6 this.context = context; 7 this.list = list; 8 } 9 10 @Override 11 public int getCount() { 12 return list.size(); 13 } 14 15 @Override 16 public Object getItem(int position) { 17 return list.get(position); 18 } 19 20 @Override 21 public long getItemId(int position) { 22 return position; 23 } 24 25 @Override 26 public View getView(int position, View convertView, ViewGroup parent) { 27 ViewHolder viewHolder; 28 if (convertView == null) { 29 //布局实例化 30 convertView = View.inflate(context, R.layout.item_filelayout, null); 31 viewHolder = new ViewHolder(convertView); 32 convertView.setTag(viewHolder); 33 } else { 34 viewHolder = (ViewHolder) convertView.getTag(); 35 } 36 // 设置数据 37 File file = (File) getItem(position); 38 if (file.isDirectory()) { 39 viewHolder.img.setImageResource(R.drawable.folder); 40 } else { 41 if (file.getName().endsWith(".jpg") 42 || file.getName().endsWith(".png") 43 || file.getName().endsWith(".gif")) { 44 viewHolder.img.setImageResource(R.drawable.pic); 45 } else if (file.getName().endsWith(".txt") || file.getName().endsWith(".log")) { 46 viewHolder.img.setImageResource(R.drawable.text); 47 } else { 48 viewHolder.img.setImageResource(R.drawable.unknown); 49 } 50 } 51 viewHolder.name.setText(file.getName()); 52 viewHolder.time.setText(new SimpleDateFormat("yy-M-d HH:mm:ss") 53 .format(new Date(file.lastModified()))); 54 55 return convertView; 56 } 57 58 class ViewHolder { 59 ImageView img; 60 TextView name; 61 TextView time; 62 63 public ViewHolder(View convertView) { 64 img = (ImageView) convertView.findViewById(R.id.img); 65 name = (TextView) convertView.findViewById(R.id.name); 66 time = (TextView) convertView.findViewById(R.id.time); 67 } 68 69 } 70 71 }
4、MainAcitivity中给ListView设置适配器
//获取SD卡根目录,必须获取权限,权限在AndroidManifest.xml/Permissions中添加
1 public class MainActivity extends Activity implements OnItemClickListener, OnClickListener { 2 3 LinearLayout ll_root; 4 TextView root; 5 ListView lv; 6 List<File> list = new ArrayList<File>(); 7 8 //获取SD卡根目录,必须获取权限,权限在AndroidManifest.xml/Permissions中添加 9 public static final String SDCard = Environment 10 .getExternalStorageDirectory().getAbsolutePath(); 11 12 // 当前文件目录 13 public static String currDir = SDCard; 14 MyAdapter adapter; 15 16 @Override 17 protected void onCreate(Bundle savedInstanceState) { 18 super.onCreate(savedInstanceState); 19 setContentView(R.layout.activity_main); 20 initData(); 21 adapter = new MyAdapter(MainActivity.this, list); 22 lv.setAdapter(adapter); 23 getAllFiles(); 24 25 } 26 27 private void initData() { 28 ll_root = (LinearLayout) findViewById(R.id.ll_root); 29 root = (TextView) findViewById(R.id.root); 30 lv = (ListView) findViewById(R.id.lv); 31 lv.setOnItemClickListener(this); 32 root.setOnClickListener(this); 33 } 34 35 public void getAllFiles() { 36 list.clear(); 37 File file = new File(currDir); 38 if (file.isDirectory()) { 39 File[] files = file.listFiles(); 40 if (files != null) { 41 for (File file2 : files) { 42 list.add(file2); 43 } 44 } 45 } 46 // 文件排序 47 sort(); 48 49 // 数据改变之后刷新 50 // notifyDataSetChanged方法通过一个外部的方法控制如果适配器的内容改变时需要强制调用getView来刷新每个Item的内容, 51 // 可以实现动态的刷新列表的功能 52 adapter.notifyDataSetChanged(); 53 } 54 55 private void sort() { 56 //使用Collection.sort排序,给定一个比较器,使用匿名内部类实现比较器接口 57 Collections.sort(list, new Comparator<File>() { 58 59 @Override 60 public int compare(File o1, File o2) { 61 if (o1.isDirectory() && o2.isDirectory() || o1.isFile() 62 && o2.isFile()) { 63 return o1.compareTo(o2); 64 } 65 //文件夹在前 66 return o1.isDirectory() ? -1 : 1; 67 } 68 }); 69 } 70 71 //ListView 监听 72 @Override 73 public void onItemClick(AdapterView<?> parent, View view, int position, 74 long id) { 75 File file = list.get(position); 76 if (file.isDirectory()) { 77 // 下一层目录 78 currDir = file.getAbsolutePath(); 79 //根目录名加上当前文件夹名 80 addDirText(file); 81 getAllFiles(); 82 } else { 83 Toast.makeText(MainActivity.this, "打开" + file.getName(), 84 Toast.LENGTH_SHORT).show(); 85 } 86 } 87 88 private void addDirText(File file) { 89 String name = file.getName(); 90 TextView tv = new TextView(this); 91 tv.setText(name+">"); 92 ll_root.addView(tv); 93 //将当前的路径保存 94 tv.setTag(file.getAbsolutePath()); 95 96 tv.setOnClickListener(new OnClickListener() { 97 98 @Override 99 public void onClick(View v) { 100 String tag = v.getTag().toString(); 101 currDir = tag; 102 getAllFiles(); 103 104 //将后面的所有TextView的tag移除 105 //从后往前删,一个一个删 106 for (int i = ll_root.getChildCount(); i >1; i--) { 107 View view = ll_root.getChildAt(i-1); 108 String currTag = view.getTag().toString(); 109 if(!currTag.equals(currDir)){ 110 ll_root.removeViewAt(i-1); 111 }else{ 112 return; 113 } 114 } 115 } 116 }); 117 } 118 119 // Back键返回上一级 120 @Override 121 public void onBackPressed() { 122 // 如果当前目录就是系统根目录,直接调用父类 123 if (currDir.equals(SDCard)) { 124 super.onBackPressed(); 125 } else { 126 // 返回上一层,显示上一层所有文件 127 currDir = new File(currDir).getParent(); 128 getAllFiles(); 129 130 //将当前TextView的tag移除 131 //总是将最后一个TextView移除 132 View view = ll_root.getChildAt(ll_root.getChildCount()-1); 133 ll_root.removeView(view); 134 135 } 136 } 137 138 //SD卡根目录TextView监听 139 @Override 140 public void onClick(View v) { 141 currDir = SDCard; 142 getAllFiles(); 143 144 //移除ll_root布局中的其他所有组件 145 for (int i = ll_root.getChildCount(); i >1; i--) { 146 ll_root.removeViewAt(i-1); 147 } 148 149 } 150 151 }
运行效果如下图:
图1
图2