再说Android RecyclerView局部刷新那个坑

本文介绍了如何使用RecyclerView的notifyItemChanged方法进行局部刷新,并通过payload参数实现更高效的更新机制。文中详细解释了payload的作用及其实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关键:public final void notifyItemChanged(int position, Object payload)

RecyclerView局部刷新大家都遇到过,有时候还说会遇见图片闪烁的问题。

优化之前的效果:

这里写图片描述

优化之后的效果:

这里写图片描述

如果想单独更新一个item,我们通常会这样做,代码如下:

mLRecyclerViewAdapter.notifyItemChanged(position);

这个也能达到更新的效果,但是有时候却美中不足。那么有没有更好的办法呢?通过查看api,我们发现了另一个方法:

/**
         * Notify any registered observers that the item at <code>position</code> has changed with an
         * optional payload object.
         *
         * <p>This is an item change event, not a structural change event. It indicates that any
         * reflection of the data at <code>position</code> is out of date and should be updated.
         * The item at <code>position</code> retains the same identity.
         * </p>
         *
         * <p>
         * Client can optionally pass a payload for partial change. These payloads will be merged
         * and may be passed to adapter's {@link #onBindViewHolder(ViewHolder, int, List)} if the
         * item is already represented by a ViewHolder and it will be rebound to the same
         * ViewHolder. A notifyItemRangeChanged() with null payload will clear all existing
         * payloads on that item and prevent future payload until
         * {@link #onBindViewHolder(ViewHolder, int, List)} is called. Adapter should not assume
         * that the payload will always be passed to onBindViewHolder(), e.g. when the view is not
         * attached, the payload will be simply dropped.
         *
         * @param position Position of the item that has changed
         * @param payload Optional parameter, use null to identify a "full" update
         *
         * @see #notifyItemRangeChanged(int, int)
         */
        public final void notifyItemChanged(int position, Object payload) {
            mObservable.notifyItemRangeChanged(position, 1, payload);
        }

重点看payload参数介绍:

payload Optional parameter, use null to identify a "full" update

翻译过来就是如果payload参数是null,那么就会来一个“完整的”更新,也就是说会全部更新。

下面我们说一下具体怎么使用。

模拟更新一条数据:

int position = 1;//指定列表中的第2个item

            ItemModel itemModel = mDataAdapter.getDataList().get(position);
            itemModel.id = 100;
            itemModel.title = "refresh item " + itemModel.id;
            itemModel.imgUrl = "http://avatar.youkuaiyun.com/2/9/C/1_jdsjlzx.jpg";
            mDataAdapter.getDataList().set(position,itemModel);

            //RecyclerView局部刷新  详见:https://github.com/jdsjlzx/LRecyclerView/issues/45
            // notifyItemChanged(int position, Object payload) 其中的payload相当于一个标记,类型不限
            mLRecyclerViewAdapter.notifyItemChanged(mLRecyclerViewAdapter.getAdapterPosition(false,position) , position);

adapter中的onBindViewHolder方法:

@Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            bind(holder,position);
        }

        //局部刷新关键:带payload的这个onBindViewHolder方法必须实现
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position, List payloads) {
            TLog.error("onBindViewHolder payloads.isEmpty() ?  " + payloads.isEmpty() );
            if (payloads.isEmpty()) {
                onBindViewHolder(holder,position);
            } else {//需要更新的数据
                TLog.error("onBindViewHolder payloads.size() =  " + payloads.size());

                //notifyItemChanged(int position, Object payload) 要与payload的类型保持一致
                if (payloads.get(0) instanceof Integer) {
                    bind(holder,position);
                }

            }
        }

上面代码说结合LRecyclerView框架来测试的,想要体验完整demo,请参考:https://github.com/jdsjlzx/LRecyclerView

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值