首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

notifyDatasetChanged()之后RecyclerView闪烁

notifyDatasetChanged() 是 Android 开发中用于通知 RecyclerView 数据集发生变化的方法。当调用此方法时,RecyclerView 会重新绑定数据并刷新界面。然而,有时会出现闪烁现象,这通常是由于以下原因造成的:

原因分析

  1. 视图重绘:当数据集发生变化时,RecyclerView 需要重新绘制视图。如果重绘过程中布局计算不准确或者数据更新频繁,可能会导致视图闪烁。
  2. 动画效果RecyclerView 默认启用了动画效果,当数据集发生变化时,动画可能会导致视图闪烁。
  3. 布局问题:如果 RecyclerView 的布局管理器或布局文件设置不当,也可能导致视图闪烁。

解决方案

  1. 减少数据更新频率:避免频繁调用 notifyDatasetChanged(),可以考虑使用 DiffUtil 来计算数据集的变化,并只更新变化的部分。
代码语言:txt
复制
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new MyDiffCallback(oldData, newData));
diffResult.dispatchUpdatesTo(adapter);
  1. 关闭动画效果:可以通过设置 RecyclerView 的动画效果为 null 来关闭动画。
代码语言:txt
复制
recyclerView.setItemAnimator(null);
  1. 优化布局:确保 RecyclerView 的布局管理器和布局文件设置合理,避免不必要的视图嵌套和复杂的布局计算。
  2. 使用 notifyItemRangeChanged():如果只有部分数据发生变化,可以使用 notifyItemRangeChanged() 来通知 RecyclerView 只更新变化的部分。
代码语言:txt
复制
adapter.notifyItemRangeChanged(startPosition, itemCount);

示例代码

以下是一个简单的示例,展示了如何使用 DiffUtil 来优化数据更新:

代码语言:txt
复制
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private List<MyData> dataList;

    public MyAdapter(List<MyData> dataList) {
        this.dataList = dataList;
    }

    public void updateData(List<MyData> newData) {
        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new MyDiffCallback(dataList, newData));
        dataList.clear();
        dataList.addAll(newData);
        diffResult.dispatchUpdatesTo(this);
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        MyData data = dataList.get(position);
        holder.textView.setText(data.getText());
    }

    @Override
    public int getItemCount() {
        return dataList.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView textView;

        ViewHolder(View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.textView);
        }
    }

    static class MyDiffCallback extends DiffUtil.Callback {
        private List<MyData> oldData;
        private List<MyData> newData;

        MyDiffCallback(List<MyData> oldData, List<MyData> newData) {
            this.oldData = oldData;
            this.newData = newData;
        }

        @Override
        public int getOldListSize() {
            return oldData.size();
        }

        @Override
        public int getNewListSize() {
            return newData.size();
        }

        @Override
        public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
            return oldData.get(oldItemPosition).getId() == newData.get(newItemPosition).getId();
        }

        @Override
        public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
            return oldData.get(oldItemPosition).equals(newData.get(newItemPosition));
        }
    }
}

参考链接

通过以上方法,可以有效减少 notifyDatasetChanged() 调用后 RecyclerView 的闪烁现象。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • RecyclerView notifyItem闪烁的问题

    功能都顺利实现,美中不足的是当前Item闪了一下,QA甚至为此提了Bug,一开始以为是图片加载库的问题,之后随着图片加载库从ImageLoader换成Picaso,又换成Glide,这个Bug一直如影随形...看来加不加这句,RecyclerView都默认执行了这个动画,看来还有点小麻烦。 ? before.gif 先来了解下这个RecyclerView的动画吧。...(new DefaultItemAnimator()); 在之前的版本中,当数据集合发生改变时,我们通过调用notifyDataSetChanged()来刷新列表,因为这样做会触发列表的重绘,所以并不会出现任何动画效果...与同行们交流了下,也有人遇到同样的问题,解决办法居然是调用notifyDataSetChanged()方法来刷新数据,这样就不会有闪一下的动画了。...但是这样不就失去使用RecyclerView的优势和意义了吗? 最后我是通过重写RecyclerView的动画来解决这一“Bug”。

    3.8K50

    RecyclerViewnotifyDataSetChanged和notifyItemRemoved之间的区别

    RecyclerView 提供了多种方法来通知适配器(Adapter)数据集发生变化,其中 notifyDataSetChanged() 和 notifyItemRemoved(int position...) 是两种不同的方法,它们各自有不同的用途和效果: notifyDataSetChanged() 用途:这个方法用于通知 RecyclerView 整个数据集已经发生变化,需要刷新所有的数据项。...效果:当调用 notifyDataSetChanged() 时,RecyclerView 会认为所有的数据项都可能发生了变化,因此它会刷新显示的所有数据项。...区别总结 影响范围:notifyDataSetChanged() 影响整个数据集,而 notifyItemRemoved(int position) 只影响指定位置的数据项。...性能开销:notifyDataSetChanged() 可能会导致整个 RecyclerView 的重新布局和绘制,性能开销较大;notifyItemRemoved(int position) 只处理指定位置的数据项

    12310

    日常开发踩坑记-刷新抖动

    recyclerview刷新抖动踩坑记 问题:下拉刷新后,更新数据,页面顶部的UI会闪烁 看下目前的实现 整个页面是一个大的Recycle了View,顶部是一个item,内部也是采用RecyclerView...notifyDataSetChanged() }...(binding.root) { } } 看到这里,基本能猜到闪烁的原因了吧 其实是在notifyDataChange后,holder在复用的时候,每个holder不是原来位置的holder...了,所以重新绑定数据,发生了闪烁 我们验证下上面的猜想 class TabMainCategoryItemHolder(val binding: ItemTabMainCategoryItemBinding...TabMainCategoryAdapter: last Id 0 current id 10 可以发现,每次刷新前后,复用的holder都不是原来的holder,都需要重新设置图片跟文案,所以产生了闪烁

    77330

    recycleview的优化_recyclerview原理

    1.4 调用notifyDataSetChanged过程: 如果调用notifyDataSetChanged,每个itemView没有稳定的id的话,RecyclerView不知道接下来会发生什么,也不知道哪些改变...这个机制会导致一个问题,启动应用之后,在屏幕可见范围内,如果只有一张卡片可见,当滚动的时 候,RecyclerView找不到可以重用的view了,它将创建一个新的,因此在滑动到第二个feed的时候就会有一定的延时...notifyDataSetChanged会触发所有item的detached回调再触发onAttached回调。...通过setHasStableIds可以使itemView的焦点固定,从而解决RecyclerView的notify方法使得图片加载时闪烁问题。...具体案例可参考:RecyclerView notifyDataSetChanged 导致图片闪烁的真凶 9、更多高级用法 9.1 SnapHelper实现卡片效果或ViewPager效果 SnapHelper

    4.1K21

    Recyclerview 刷新「建议收藏」

    前言:recyclerview比起listview功能上更加丰富外(如横向列表),在Item复用上也更加灵活,比如listview的某个Item数据需要更新,要通过notifyDataSetChanged...notifyItemChanged(position) 只刷新该position的Item,即只是该Item调用onBindViewHolder,因此如果对数据源进行插、移除操作不能改方法只刷新操作的Item,毕竟该Item之后的...ContentViewHolder viewHolder, int position, List payloads)中根据payloads.get(position)值只对需要刷新的控件进行操作 (3)notifyDataSetChanged...() 全部Item进行刷新 (4)notifyItemRangeChanged(position, itemCount) 刷新position及之后ItemCount个Item (5)notifyItemInserted...(RecyclerView.java:3875) at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java

    1.1K30

    android RecycleView Adapter简单封装

    这个优势就体现出来了,自从Android 5.0后系统提供的,先不说效率如何,这个既然是Google为我们提供的,我们姑且用之,不过说实话,对于它的写法不习惯他的人看着很是麻烦,其实这个类无外乎继承自RecyclerView.Adapter...如下: public class DetailParamAdapter extends RecyclerView.Adapter { private List...public int getItemCount() { return list.size(); } } class ParamHolderView extends RecyclerView.ViewHolder...其实分析下,adapter对我们有用的就两个方法,一个是获取adapter的View,然后是绑定数据OnBindData,至于数据的来源,我们可以借鉴RecyclerView.Adapter做一个泛型。...其完整的代码如下: public abstract class BaseRecycleAdapter extends RecyclerView.Adapter

    88780

    Android ViewPager2 真的香么?

    优势 支持 RTL 布局,稍后介绍; 支持垂直方向切换; 支持 Fragment 集合刷新,即 notifyDataSetChanged; ?...和尚当前 SDK 已是最新版本,首先按照提示在 AndroidManifest->application 添加错误中要求的,但是并不能解决问题,之后查阅了很多资料,发现 Androidx 与 Android...尝试 和尚尝试绑定不同背景色和文字内容;与 ViewPager 不同的是,适配器需要使用 RecyclerView.Adapte,这也意味着绑定数据的方式更灵活,和尚为了测试 ViewPager2...新特性,设置了点击事件; 借助 setOrientation() 方法可以动态改变切换方向,水平或竖直; 借助 notifyDataSetChanged() 方法可以实时更新数据; 借助 setLayoutDirection...break; case 1: list.set(position, Color.GREEN); adapter.notifyDataSetChanged

    2.1K31
    领券