如何解决recyclerview列表更新延迟

问题描述 投票:-1回答:2

更新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);
}

如果我单击特定视图,它将被回调到上述方法,并清除最初在回收器视图中的列表并更新要显示的新列表。其余代码负责其他处理。我尝试使用'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;
        }
    }
}

这是一个Recycler视图适配器类。在适配器的onBindViewHolder方法中,即使我使用System.currentTimeMillis计算时间,我也看不到任何可能发生的延迟。花了0.005到0.01秒。有一个疑问的地方,但我不确切知道在哪里检查它。看起来'onFolderCoverImgClick'和onBindViewHolder之间差异大约为0.6秒。

videoPortraitAdapter是VideoItemAdapter的一个实例。如果你认识任何人,如果可以,我将不胜感激。

android android-recyclerview adapter delay notify
2个回答
0
投票

您可以使用新的ListAdapter而不是RecyclerView.Adapter,它提供了submitList()方法,该方法管理列表中的差异并仅更新这些差异。请参阅this链接。


0
投票

更好的替代选择是使用设置滑动来刷新和使用

mSwipeRefreshLayout.setRefreshing(false); - 完成适配器更新或NotifyItemChanged。

这一直对我有用,希望这对你有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.