我正在使用以下代码从文件夹中提取所有视频,并将其显示在recyclerview中。我面临的问题是,在少数设备中,有时同一项目在RecyclerView中多次显示。我看到onLoadFinished
被多次调用,但是每次清除列表时也不应显示重复项。按照其他答案,我尝试将initLoader()调用移到onResume()内,但这也没有解决我的问题。
活动
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
rvVideos = (RecyclerView) findViewById(R.id.rvVideos);
videoList=new ArrayList<VideoInfo>();
rvVideos.setHasFixedSize(true);
rvVideos.setLayoutManager(new LinearLayoutManager(this));
videoAdapter = new VideoAdapter (this, videoList, filePath);
rvVideos.setAdapter(videoAdapter);
getLoaderManager().initLoader(URL_LOADER_SPLIT, null, VidActivity.this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String selection = MediaStore.Video.Media.DATA + " like?";
String[] selectionArgs = new String[]{"%" + filePath + "%"};
return new CursorLoader(this, MediaStore.Video.Media.EXTERNAL_CONTENT_URI, COLUMNS_OF_INTEREST, selection, selectionArgs,
MediaStore.Video.Media.DATE_ADDED + " ASC");
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
if(cursor != null) {
videoList.clear();
while (cursor.moveToNext()) {
VideoInfo videoInfo = new VideoInfo();
videoInfo.setTitleValue(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME)));
videoInfo.setSizeValue(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE)));
videoInfo.setDurationValue(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION)));
videoInfo.setWidthValue(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.WIDTH)));
videoInfo.setHeightValue(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.HEIGHT)));
videoInfo.setVideoid(cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID)));
videoList.add(videoInfo);
videoAdapter.notifyDataSetChanged();
}
}
}
适配器
public class VideoAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
ArrayList<VideoInfo> videoList;
Context mContext;
String filePath;
Bitmap bmp;
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
public VideoAdapter(Context context, ArrayList<VideoInfo> videoList, String filePath) {
mContext = context;
this.videoList = videoList;
this.filePath = filePath;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_HEADER) {
View headerView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_header, parent, false);
return new HeaderViewHolder(headerView);
} else if (viewType == TYPE_ITEM) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.tab_child, parent, false);
return new ItemViewHolder(itemView);
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
if (viewHolder instanceof HeaderViewHolder) {
((HeaderViewHolder) viewHolder).tvInstruction.setText(mContext.getResources().getString(R.string.folderCreatedPath, filePath));
} else if (viewHolder instanceof ItemViewHolder) {
VideoInfo videoInfo = videoList.get(position-1);
String videoFullPath = filePath + "/" + videoInfo.getTitleValue();
String size = Converters.BytesToMb(String.valueOf(videoInfo.getSizeValue()));
String resolution = videoInfo.getWidthValue() + "X" + videoInfo.getHeightValue();
((ItemViewHolder) viewHolder).title.setText(videoInfo.getTitleValue());
((ItemViewHolder) viewHolder).size.setText(videoInfo.getSizeValue() > 0 ? size : "");
((ItemViewHolder) viewHolder).duration.setText(videoInfo.getDurationValue() > 0 ? String.format("%d:%d:%d", TimeUnit.MILLISECONDS.toHours((long) videoInfo.getDurationValue()), TimeUnit.MILLISECONDS.toMinutes((long) videoInfo.getDurationValue()) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours((long) videoInfo.getDurationValue())),
TimeUnit.MILLISECONDS.toSeconds((long) videoInfo.getDurationValue()) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) videoInfo.getDurationValue()))) : "");
((ItemViewHolder) viewHolder).resolution.setText(videoInfo.getWidthValue() > 0 ? resolution : "");
((ItemViewHolder) viewHolder).mainLayout.setTag(position-1);
((ItemViewHolder) viewHolder).mainLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String videoFullPath = filePath + "/" + videoList.get(Integer.valueOf(view.getTag().toString())).getTitleValue();
Intent intent = new Intent(mContext, PreviewActivity.class);
intent.putExtra("filepath", videoFullPath);
mContext.startActivity(intent);
}
});
}
}
@Override
public int getItemCount() {
return videoList.size() + 1;
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
CustomImageView thumbnail;
TextView title;
TextView resolution;
TextView size;
TextView duration;
RelativeLayout mainLayout;
public ItemViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.VideoTitleNew);
resolution = (TextView) itemView.findViewById(R.id.VideoResolutionNew);
size = (TextView) itemView.findViewById(R.id.VideoSizeNew);
thumbnail = (CustomImageView) itemView.findViewById(R.id.VideoThumbnailNew);
duration = (TextView) itemView.findViewById(R.id.VideoDurationNew);
mainLayout = (RelativeLayout) itemView.findViewById(R.id.VideoMainLayout);
}
}
public class HeaderViewHolder extends RecyclerView.ViewHolder {
TextView tvInstruction;
public HeaderViewHolder(View itemView) {
super(itemView);
tvInstruction = (TextView) itemView.findViewById(R.id.tvInstruction);
}
}
@Override
public int getItemViewType(int position) {
if (isPositionHeader(position))
return TYPE_HEADER;
return TYPE_ITEM;
}
private boolean isPositionHeader(int position) {
return position == 0;
}
}