android - 如何解决recyclerv视图列表更新延迟
问题描述
更新 Recycler 视图列表存在延迟。当列表中的项目很小时,它们会被快速处理,但当项目很大时,就会出现延迟。所有项目的模型都是相同的,但似乎无法使用类似的方法,NotifyItemChanged
因为它表示不同的信息和数字。
@Override
public void onFolderCoverImgClick(int position) {
setVideoTopBarByFolderData(position);
AppVideoData.FolderData folderData = videoLayoutFolderList.get(position);
String folderId = folderData.getFolderId();
videoByFolderList.clear();
for (int i = 0; i < videoLayoutList.size(); i++) {
if (folderId.equals(videoLayoutList.get(i).getFolderId())) {
videoByFolderList.add(videoLayoutList.get(i));
}
}
String path = getFilesDir() + File.separator + "vid";
for (int i = 0; i < videoByFolderList.size(); i++) {
if (new File(path + File.separator + videoByFolderList.get(i).getId() + ".mp4").exists()) {
videoByFolderList.get(i).setVideoType("Download");
} else {
videoByFolderList.get(i).setVideoType("vimeo");
}
if(videoIdF.equals(videoByFolderList.get(i).getId())) {
videoPosF = i;
}
}
videoPortraitAdapter.updateList(videoByFolderList);
videoPortraitAdapter.checkSelectedVideoWhenFolder(videoPosF, videoIdF);
}
如果我点击一个特定的视图,它会回调到上面的方法,并清除原来在recycler视图中的列表,并更新要显示的新列表。其余代码负责额外的处理。我尝试使用 ' System.currentTimeMillis
' 方法计算时间,但它似乎不会导致附加代码延迟。
public class VideoItemAdapter extends RecyclerView.Adapter<VideoItemAdapter.VideoViewHolder> {
public VideoItemAdapterListener videoItemAdapterListener;
public VideoItemDrawDoneListener videoItemDrawDoneListener;
private Context context;
private LiveActivity liveActivity;
private List<AppVideoData.AppYouTube> dataList;
private String skinColor;
private boolean fullScreen;
private boolean isFolder;
private int videoPosF;
private String videoIdF;
public VideoItemAdapter(Context context, List<AppVideoData.AppYouTube> dataList, String skinColor, boolean fullScreen, boolean isFolder) {
this.context = context;
this.dataList = dataList;
this.skinColor = skinColor;
this.fullScreen = fullScreen;
if (context instanceof LiveActivity) {
liveActivity = (LiveActivity) context;
}
this.isFolder = isFolder;
}
public void updateList(List<AppVideoData.AppYouTube> dataList) {
this.dataList = dataList;
notifyDataSetChanged();
}
public void setOnVideoItemClickListener(VideoItemAdapterListener videoItemAdapterListener) {
this.videoItemAdapterListener = videoItemAdapterListener;
}
public void setOnVideoItemDrawDoneListener(VideoItemDrawDoneListener videoItemDrawDoneListener) {
this.videoItemDrawDoneListener = videoItemDrawDoneListener;
}
@NonNull
@Override
public VideoItemAdapter.VideoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.video_item, parent, false);
VideoViewHolder holder = new VideoViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(@NonNull final VideoItemAdapter.VideoViewHolder holder, final int position) {
Log.d("time", "onBindViewHolder: " + System.currentTimeMillis());
int adapterPosition = 0;
if(holder.getAdapterPosition() != RecyclerView.NO_POSITION) { adapterPosition = holder.getAdapterPosition(); }
AppVideoData.AppYouTube videoData = dataList.get(adapterPosition);
String videoType = videoData.getVideoType();
Glide.with(context).load(videoData.getVideoThumbnail()).into(holder.itemThumbnail);
holder.itemSelected.setImageResource(R.drawable.shining_selected);
holder.itemTitle.setText(videoData.getTitle());
holder.itemDivider.setBackgroundColor(Color.parseColor(skinColor));
holder.itemDuration.setText(getDuration(videoData.getDuration()));
changeVideo(holder, adapterPosition, videoData.getId());
if (!videoType.equals("Download")) {
holder.itemDownload.setVisibility(View.VISIBLE);
holder.itemDelete.setVisibility(View.INVISIBLE);
} else {
holder.itemDownload.setVisibility(View.INVISIBLE);
holder.itemDelete.setVisibility(View.VISIBLE);
}
if(fullScreen) {
holder.itemDownload.setVisibility(View.INVISIBLE);
holder.itemDelete.setVisibility(View.INVISIBLE);
}
Log.d("time", "onBindViewHolder1: " + System.currentTimeMillis());
}
@Override
public int getItemCount() {
return (dataList != null) ? dataList.size() : 0;
}
private String getDuration(int original) {
int hour = original / 60 / 60;
int min = (original - (hour * 60 * 60)) / 60;
int sec = original - (hour * 60 * 60) - (min * 60);
return (hour > 0) ? String.format("%02d:%02d:%02d", hour, min, sec) : String.format("%02d:%02d", min, sec);
}
public void checkSelectedVideoWhenFolder(int videoPosF, String videoIdF) {
this.videoPosF = videoPosF;
this.videoIdF = videoIdF;
notifyItemChanged(videoPosF);
}
private void changeVideo(VideoViewHolder holder, int position, String videoId) {
if (!liveActivity.isFolder) {
if ((liveActivity.videoPos == position)) {
holder.itemSelected.setVisibility(View.VISIBLE);
} else {
holder.itemSelected.setVisibility(View.INVISIBLE);
}
} else {
if ((videoPosF == position) && videoIdF.equals(videoId)) {
holder.itemSelected.setVisibility(View.VISIBLE);
} else {
holder.itemSelected.setVisibility(View.INVISIBLE);
}
}
}
public class VideoViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
protected RelativeLayout itemBody;
protected TextView itemTitle;
protected TextView itemDuration;
protected TextView itemDivider;
protected ImageView itemThumbnail;
protected ImageView itemSelected;
protected ImageButton itemDownload;
protected ImageButton itemDelete;
public VideoViewHolder(View itemView) {
super(itemView);
itemBody = (RelativeLayout) itemView.findViewById(R.id.video_item_body);
itemTitle = (TextView) itemView.findViewById(R.id.video_item_title);
itemDuration = (TextView) itemView.findViewById(R.id.video_item_duration);
itemDivider = (TextView) itemView.findViewById(R.id.video_item_divider);
itemThumbnail = (ImageView) itemView.findViewById(R.id.video_item_thumbnail);
itemSelected = (ImageView) itemView.findViewById(R.id.video_item_selected);
itemDownload = (ImageButton) itemView.findViewById(R.id.video_item_download);
itemDelete = (ImageButton) itemView.findViewById(R.id.video_item_delete);
itemBody.setOnClickListener(this);
itemDownload.setOnClickListener(this);
itemDelete.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.video_item_body:
videoItemAdapterListener.onVideoItemClick(getAdapterPosition(), fullScreen, itemSelected);
break;
case R.id.video_item_download:
videoItemAdapterListener.onVideoDownloadClick(getAdapterPosition(), fullScreen);
break;
case R.id.video_item_delete:
videoItemAdapterListener.onVideoDeleteClick(getAdapterPosition(), fullScreen);
break;
}
}
}
这是一个回收器视图适配器类。在onBindViewHolder
适配器的方法中,即使我使用 计算时间System.currentTimeMillis
,我也看不到任何可能发生延迟的事情。耗时 0.005 到 0.01 秒。有一个怀疑的地方,但我不知道在哪里检查它。'onFolderCoverImgClick' 和onBindViewHolder
.
videoPortraitAdapter
是 VideoItemAdapter 的一个实例。如果你认识任何人,如果可以的话,我将不胜感激。
解决方案
您可以使用新的 ListAdapter 而不是 RecyclerView.Adapter,它提供了 submitList() 方法,该方法管理列表中的差异并仅更新这些差异。参考这个链接。
推荐阅读
- macos - 从 Windows 迁移到 macOS 后更改 subversion 本地存储库路径
- node.js - Nodejs,MongoDB用multer上传图片
- three.js - CSS3DObject 在 Firefox 上不可点击
- flutter - 扑两个孩子:
在同一个 Stack() 内 - php - 如何在进行 PHP 工匠存储时更改符号链接文件夹的位置:链接?
- ansible - 在 Ansible 问题 (authorized_keys) 中创建然后编辑文件
- javascript - Moment.js - 直到时刻的确切时间
- c# - 是否有从 REST API 控制器反序列化基类的通用解决方案?
- java - 从文件中读取公钥或私钥时如何修复“无效的密钥格式”?
- nagios - Nagios 核心 4.4.3 | 通知配置