Android ListView展示指定格式文件时如何获取正确文件大小及默认图标
问题1:所有文件大小显示错误的原因&修复方案
你代码中给所有列表项传的大小参数都是items.length,这个值是你筛选到的文件总数(你的场景里总数是22),所以所有项都固定显示22字节,没有读取对应文件的真实大小。
修复步骤:
- 将筛选得到的File列表设置为全局变量,不要仅在
showList方法内定义,需要保留每个文件的完整File对象才能读取大小、后缀等信息 - 在Adapter的
getView方法中,根据position拿到对应File对象,调用length()方法获取真实文件大小传入计算方法即可
修正代码示例:
// 调整全局变量部分 ListView listView; ArrayList<File> myApps; // 新增全局存储文件对象的列表 String[] items;
// 调整showList方法 private void showList() { myApps = findList(Environment.getExternalStorageDirectory()); // 赋值给全局变量 items = new String[myApps.size()]; for (int i = 0; i<myApps.size(); i++){ items[i] = myApps.get(i).getName().toString(); } customAdapter customAdapter = new customAdapter(); listView.setAdapter(customAdapter); }
// 调整getView里的大小赋值逻辑 // 替换原有sizeApp.setText(readableFileSize(items.length)); sizeApp.setText(readableFileSize(myApps.get(position).length()));
问题2:加载不同格式文件对应默认图标的实现方案
可以通过Android系统的PackageManager结合文件MIME类型获取系统对应的默认图标,APK文件可以单独读取安装包自带的图标,实现代码如下:
// 新增获取文件图标的方法 private Drawable getFileIcon(File file) { // 单独处理APK文件,读取安装包自带图标 if (file.getName().endsWith(".apk")) { PackageManager pm = getContext().getPackageManager(); PackageInfo info = pm.getPackageArchiveInfo(file.getAbsolutePath(), 0); if (info != null) { info.applicationInfo.sourceDir = file.getAbsolutePath(); info.applicationInfo.publicSourceDir = file.getAbsolutePath(); return info.applicationInfo.loadIcon(pm); } } // 其他格式文件匹配系统默认图标 String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(file.getAbsolutePath())); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), mimeType); List<ResolveInfo> resolveInfos = getContext().getPackageManager().queryIntentActivities(intent, 0); if (!resolveInfos.isEmpty()) { return resolveInfos.get(0).loadIcon(getContext().getPackageManager()); } // 匹配不到时返回通用文件图标 return ContextCompat.getDrawable(getContext(), android.R.drawable.ic_menu_file); }
在getView中调用方法设置图标即可:
appImage.setImageDrawable(getFileIcon(myApps.get(position)));
优化建议
- 当前Adapter没有做布局复用,每次
getView都重新inflate布局,列表滑动会卡顿,建议补充convertView复用逻辑,或使用RecyclerView替换ListView - 遍历整机存储的IO操作建议放到子线程执行,避免阻塞主线程导致ANR
内容的提问来源于stack exchange,提问作者IMBROS TV
相关产品推荐
相关产品推荐

