欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RecyclerView、LIstView的局部刷新

程序员文章站 2022-06-17 13:52:06
...

最近项目中用到了点击显示下拉列表,列表呀当然要用list显示啊,当然也可以不用,有人说,可以简单粗暴的用死布局直接刚。好了,那个说直接刚的人你可以闭嘴了,数据是后台返的,是变化的,这样只能用列表来动态的显示数据,再加上后来还加入了一个点击颜色变化的需求,遂才引出这篇文章,List列表的局部更新。

一、RecyclerView局部刷新

    RecyclerView的局部刷新是有区分的,有数据的刷新和 item 结构的刷新,局部的 item 插入、删除、移动刷新方法都是结构的刷新。而 notifyItemChangednotifyItemRangeChanged 方法属于数据的刷新。

1. 数据刷新

数据刷新还分全部刷新和局部刷新,

全部刷新:**notifyDataSetChanged()**,**notifyItemChanged(int)**;
局部刷新:**notifyItemRangeChanged(int,int)**(从指定位置开始刷新指定个item),
**notifyItemChanged(int, Object)**。

这里notifyItemChanged,第二个参数控制刷新全部还是局部,如:
@Override
    public void onBindViewHolder(MyViewHolder holder, final int position, List<Object> payloads) {
        super.onBindViewHolder(holder, position, payloads);
        if (payloads.isEmpty()){  
        //全部刷新
        }else {
        //局部刷新
        }
    }

这里主要讲刷新指定item。

2. item 结构刷新

结构刷新分:插入、移动、移除一个并自动刷新

插入:notifyItemInserted(int)
用法:

    /**
     * 添加并更新数据,同时具有动画效果
     */
    public void addDataAt(int position, DataBean data) {
        mDatas.add(position, data);
        notifyItemInserted(position);//更新数据集,注意如果用adapter.notifyDataSetChanged()将没有动画效果
    }

移动:notifyItemMoved(int)

移除:notifyItemRemoved(int)
用法:

    /**
     * 移除并更新数据,同时具有动画效果
     */
    public void removeDataAt(int position) {
        mDatas.remove(position);
        notifyItemRemoved(position);
    }

二、ListView局部刷新

非notifyDataSetChanged方式。

方法一:更新对应view的内容

item点击事件{
 datas.set(position, "改变当前位置数据" + position);
      updateSingle(position);//要更新的位置
}
  /**
     *
     * @param position 要更新的位置
     */
    private void updateSingle(int position) {
        /**第一个可见的位置**/
        int firstVisiblePosition = listView.getFirstVisiblePosition();
        /**最后一个可见的位置**/
        int lastVisiblePosition = listView.getLastVisiblePosition();

        /**在看见范围内才更新,不可见的滑动后自动会调用getView方法更新**/
        if (position >= firstVisiblePosition && position <= lastVisiblePosition) {
            /**获取指定位置view对象**/
            View view = listView.getChildAt(position - firstVisiblePosition);
            TextView textView = (TextView) view.findViewById(R.id.textView);
            textView.setText(datas.get(position));
        }
    }

方法二:通过ViewHolder去设置值

    /**
     * 找出对应的ViewHolder,通过ViewHolder去设置值
     *
     * @param position 要更新的位置
     */
    private void updateOne(int position) {
        /**第一个可见的位置**/
        int firstVisiblePosition = listView.getFirstVisiblePosition();
        /**最后一个可见的位置**/
        int lastVisiblePosition = listView.getLastVisiblePosition();

        /**在看见范围内才更新,不可见的滑动后自动会调用getView方法更新**/
        if (position >= firstVisiblePosition && position <= lastVisiblePosition) {
            /**获取指定位置view对象**/
            View view = listView.getChildAt(position - firstVisiblePosition);
            /**通过ViewHolder找出缓存的对应控件**/
            TextView textView = CommonViewHolder.get(view, R.id.textView);
            textView.setText(datas.get(position));

        }
    }

方法三:调用一次getView()方法

这种方法是调用适配器对应的getView方法,用它里面的代码对界面进行刷新。这也是google在IO大会上推荐的做法

item点击事件{
 datas.set(position, "改变当前位置数据" + position);
      updateItem(position);//要更新的位置
}
 /**
     * 调用一次getView()方法;Google推荐的做法
     *
     * @param position 要更新的位置
     */
    private void updateItem(int position) {
        /**第一个可见的位置**/
        int firstVisiblePosition = listView.getFirstVisiblePosition();
        /**最后一个可见的位置**/
        int lastVisiblePosition = listView.getLastVisiblePosition();

        /**在看见范围内才更新,不可见的滑动后自动会调用getView方法更新**/
        if (position >= firstVisiblePosition && position <= lastVisiblePosition) {
            /**获取指定位置view对象**/
            View view = listView.getChildAt(position - firstVisiblePosition);
            commonAdapter.getView(position, view, listView);
        }

    }

最后,参考链接:
DylanAndroid的csdn博客