如何在RecyclerView Adapter中获取并显示视频文件夹大小
问题:视频文件夹大小无法显示
我正在开发一款视频播放App,已成功获取视频文件夹并在RecyclerView中展示,但无法显示视频文件夹的大小。相关代码如下:
VideoFoldersAdapter代码
package com.fun.rapidplayer; import static java.security.AccessController.getContext; import android.content.Context; import android.content.res.AssetManager; import android.graphics.Color; import android.graphics.Typeface; import android.graphics.drawable.GradientDrawable; import android.os.FileUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.cardview.widget.CardView; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; public class VideoFoldersAdapter extends RecyclerView.Adapter<VideoFoldersAdapter.ViewHolder> { private ArrayList<MediaFiles> mediaFiles; private ArrayList<String> folderPath; private Context context; public VideoFoldersAdapter(ArrayList<MediaFiles> mediaFiles, ArrayList<String> folderPath, Context context) { this.mediaFiles = mediaFiles; this.folderPath = folderPath; this.context = context; } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.floder_item,parent,false); return new ViewHolder(view); } @NonNull @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { int indexPath = folderPath.get(position).lastIndexOf ("/"); String nameOfFolder = folderPath.get(position).substring(indexPath+1); holder.folderName.setText(nameOfFolder); holder.nooffiles.setText(noOffiles(folderPath.get(position))+" Videos"); String size = how to get please help } @Override public int getItemCount() { return folderPath.size(); } public class ViewHolder extends RecyclerView.ViewHolder { TextView folderName; TextView nooffiles; TextView foldersize; CardView cardview1,cardview2; public ViewHolder(@NonNull View itemView) { super(itemView); folderName = itemView.findViewById(R.id.folderName); nooffiles = itemView.findViewById(R.id.nooffiles); foldersize = itemView.findViewById(R.id.foldersize); cardview1 = itemView.findViewById(R.id.cardview1); cardview2 = itemView.findViewById(R.id.cardview2); } } int noOffiles(String folder_name) { int files_no = 0; for (MediaFiles mediaFiles : mediaFiles) { if (mediaFiles.getPath().substring(0, mediaFiles.getPath().lastIndexOf("/")) .endsWith(folder_name)) { files_no++; } } return files_no; } public void _shapeRadius(final View _v, final String _color, final double _radius) { android.graphics.drawable.GradientDrawable shape = new android.graphics.drawable.GradientDrawable(); shape.setShape(android.graphics.drawable.GradientDrawable.RECTANGLE); shape.setCornerRadius((int)_radius); shape.setColor(Color.parseColor(_color)); _v.setBackgroundDrawable(shape); } private String bytesIntoHumanReadable(long bytes) { long kilobyte = 1024; long megabyte = kilobyte * 1024; long gigabyte = megabyte * 1024; long terabyte = gigabyte * 1024; if ((bytes >= 0) && (bytes < kilobyte)) { return bytes + " B"; } else if ((bytes >= kilobyte) && (bytes < megabyte)) { return (bytes / kilobyte) + " KB"; } else if ((bytes >= megabyte) && (bytes < gigabyte)) { return (bytes / megabyte) + " MB"; } else if ((bytes >= gigabyte) && (bytes < terabyte)) { return (bytes / gigabyte) + " GB"; } else if (bytes >= terabyte) { return (bytes / terabyte) + " TB"; } else { return bytes + " Bytes"; } } }
MediaFiles模型类代码
package com.fun.rapidplayer; public class MediaFiles { public String id; public String title; public String displayNam; public String size; public String duration; public String path; public String datAdded; public MediaFiles(String id, String title, String displayNam, String size, String duration, String path, String datAdded) { this.id = id; this.title = title; this.displayNam = displayNam; this.size = size; this.duration = duration; this.path = path; this.datAdded = datAdded; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDisplayNam() { return displayNam; } public void setDisplayNam(String displayNam) { this.displayNam = displayNam; } public String getSize() { return size; } public void setSize(String size) { this.size = size; } public String getDuration() { return duration; } public void setDuration(String duration) { this.duration = duration; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getDatAdded() { return datAdded; } public void setDatAdded(String datAdded) { this.datAdded = datAdded; } }
MainActivity代码
package com.fun.rapidplayer; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.annotation.SuppressLint; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private ArrayList<MediaFiles> mediaFiles = new ArrayList<>(); private ArrayList<String> allfolderList = new ArrayList<>(); RecyclerView recyclerview1; VideoFoldersAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); recyclerview1 = findViewById(R.id.recyclerview1); showfolder(); } private void showfolder() { mediaFiles = fetchMedeia(); adapter = new VideoFoldersAdapter(mediaFiles, allfolderList, this); recyclerview1.setAdapter(adapter); recyclerview1.setLayoutManager(new LinearLayoutManager(this, recyclerview1.VERTICAL, false)); adapter.notifyDataSetChanged(); } public ArrayList<MediaFiles> fetchMedeia() { ArrayList<MediaFiles> mediaFilesArrayList = new ArrayList<>(); Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; Cursor cursor = getContentResolver().query(uri, null, null, null, null); if (cursor != null && cursor.moveToNext()) { do { String id = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media._ID)); String title = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE)); String displayName = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DISPLAY_NAME)); String size = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.SIZE)); String duration = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DURATION)); String path = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA)); String dateAdded = cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATE_ADDED)); MediaFiles mediaFiles = new MediaFiles(id, title, displayName, size, duration, path, dateAdded); int index = path.lastIndexOf("/"); String substring = path.substring(0, index); if (!allfolderList.contains(substring)) { allfolderList.add(substring); } mediaFilesArrayList.add(mediaFiles); } while (cursor.moveToNext()); } return mediaFilesArrayList; } }
解决方案
要计算并显示视频文件夹的总大小,只需遍历目标文件夹下所有视频的大小并求和,再转换为可读格式即可,具体修改如下:
1. 添加文件夹总大小计算方法
在VideoFoldersAdapter类中新增方法,用于统计指定文件夹下所有视频的总字节数:
private long calculateFolderTotalSize(String folderPath) { long totalSize = 0; for (MediaFiles file : mediaFiles) { // 获取当前视频所在的文件夹路径 String fileFolder = file.getPath().substring(0, file.getPath().lastIndexOf("/")); // 匹配目标文件夹,累加视频大小 if (fileFolder.equals(folderPath)) { try { totalSize += Long.parseLong(file.getSize()); } catch (NumberFormatException e) { e.printStackTrace(); } } } return totalSize; }
2. 在绑定ViewHolder时计算并设置大小
修改onBindViewHolder方法,调用上述方法计算大小并显示到对应的TextView:
@NonNull @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { int indexPath = folderPath.get(position).lastIndexOf("/"); String nameOfFolder = folderPath.get(position).substring(indexPath + 1); holder.folderName.setText(nameOfFolder); holder.nooffiles.setText(noOffiles(folderPath.get(position)) + " Videos"); // 计算文件夹总大小并转换为可读格式 long totalBytes = calculateFolderTotalSize(folderPath.get(position)); String readableSize = bytesIntoHumanReadable(totalBytes); holder.foldersize.setText(readableSize); }
3. 可选优化建议
- 如果视频文件数量较多,建议在后台线程中计算总大小,避免阻塞UI线程(可使用Coroutine或AsyncTask实现)
- 可以缓存已计算的文件夹大小,避免每次绑定ViewHolder时重复遍历计算
- 完善异常处理逻辑,避免因视频大小格式异常导致崩溃
内容的提问来源于stack exchange,提问作者Ayan Mishra
相关产品推荐
相关产品推荐

