【RecyclerView】 十三、RecyclerView 数据更新 ( 移动数据 | 数据改变 )

【RecyclerView】 十三、RecyclerView 数据更新 ( 移动数据 | 数据改变 )一、移动数据、二、数据改变、三、完整代码示例、四、RecyclerView相关资料

一、移动数据


移动数据 : 调用 RecyclerView.Adapter 的 void notifyItemMoved(int fromPosition, int toPosition) 方法 , 传入的参数是移动前的位置和移动后的位置 ;

该方法的作用是通知任何被注册的观察者 , fromPosition 位置的 item 元素移动到了 toPosition 位置 ;

参数说明 :

int fromPosition 参数 : 元素移动前的位置 ;

int toPosition 参数 : 元素移动后的新位置 ;

注意 : 这是一个结构性的变化事件 ;

表示在数据集中的其它元素仍然被认为是最新的数据 , 这些数据不会被重新绑定 , 尽管它们的位置已经发生了变化 ;

也就是说 RecyclerView 只刷新涉及到的 fromPosition 和 toPosition 这 2 个元素 , 其它元素不变 ;

代码示例 : 先移除第 0 0 0 个元素 , 然后在第 7 7 7 位置插入相同的数据 , 相当于将第 0 0 0 个数据移动到了第 7 7 7 位置 ;

                // 先移除第 0 个
                names.remove(0);
                // 然后在第 7 个位置插入, 此时变为第 7 个元素
                names.add(7, "宋江");

                // 通知适配器
                adapter.notifyItemMoved(0, 7);

RecyclerView.Adapter.notifyItemMoved(int fromPosition, int toPosition) 函数原型 : 该函数定义在 RecyclerView 的内部类 Adapter 中 ;

public class RecyclerView extends ViewGroup implements ScrollingView,
        NestedScrollingChild2, NestedScrollingChild3 { 
   
    public abstract static class Adapter<VH extends ViewHolder> { 
   
        /** * 通知任何被注册的观察者 , fromPosition 位置的 item 元素移动到了 toPosition 位置 ; * * 这是一个结构性的变化事件 ; * 表示在数据集中的其它元素仍然被认为是最新的数据 , 这些数据不会被重新绑定 , * 尽管它们的位置已经发生了变化 ; * 也就是说 RecyclerView 只刷新涉及到的 fromPosition 和 toPosition 这 2 个元素 , * 其它元素不变 ; * * @param fromPosition 元素移动前的位置 ; * @param toPosition 元素移动后的新位置 ; */
        public final void notifyItemMoved(int fromPosition, int toPosition) { 
   
            mObservable.notifyItemMoved(fromPosition, toPosition);
        }
	}
}

运行效果 : 动画效果是系统自带的 , 可以自己实现 ;

在这里插入图片描述

二、数据改变


批量修改数据 : 调用 RecyclerView.Adapter 的 void notifyDataSetChanged( ) 方法 , 通知数据发生了改变 ;

该方法的作用是通知任何被注册的观察者 , 数据集发生了改变 ;

调用该方法刷新数据 , 比调用其它方法更有效 , 但是没有动画效果 ;

数据改变事件类型 : 有两种不同的类型 , item 元素改变 和 结构性改变 ;

① item 元素改变 : 指的是单个的 item 的数据更新 , 但是位置没有改变 ;

② 结构性改变 : 指的是有新的数据被插入 , 删除 , 移动 , 位置发生了改变 ;

参数说明 :

int positionStart 参数 : 被修改的元素在原数据集中首个元素的位置索引 ;

int itemCount 参数 : 数据集中被修改元素个数 ;

注意 :

该方法不指定数据集发生了哪些变化 , 强制要求任何观察者对象去呈现所有存在的 item 条目和结构 , 这些数据可能已经失效 ;

布局管理器 LayoutManager 会强制所有数据重新绑定 , 并重新读取所有可视组件的布局 ;

如果适配器调用了本方法 , 通知数据发生了改变 , RecyclerView 会尝试去 为适配器 同步可见的结构性改变事件 ;

这样有助于动画和可视化对象的持续 , 但是单独的 item 元素组件需要重新被绑定 ;

代码示例 : 先移动数据 , 再删除三个数据 ;

                // 先移除第 0 个
                names.remove(0);
                // 然后在第 7 个位置插入, 此时变为第 7 个元素
                names.add(7, "宋江");

                // 删除第 0 ~ 2 个元素
                names.remove(0);
                names.remove(0);
                names.remove(0);

                adapter.notifyDataSetChanged();

RecyclerView.Adapter.notifyItemInserted(int position) 函数原型 : 该函数定义在 RecyclerView 的内部类 Adapter 中 ;

public class RecyclerView extends ViewGroup implements ScrollingView,
        NestedScrollingChild2, NestedScrollingChild3 { 
   
    public abstract static class Adapter<VH extends ViewHolder> { 
   
        /** * 通知任何被注册的观察者 , 数据集发生了改变 ; * * 数据改变事件 , 有两种不同的类型 , item 元素改变 和 结构性改变 ; * item 元素改变时单个的 item 的数据更新 , 但是位置没有改变 ; * 结构性改变指的是有新的数据被插入 , 删除 , 移动 , 位置发生了改变 ; * * 该事件不指定数据集发生了哪些变化 , 强制要求任何观察者对象去呈现所有存在的 item 条目和结构 , 这些数据可能已经失效 ; * 布局管理器 LayoutManager 会强制所有数据重新绑定 , 并重新读取所有可视组件的布局 ; * * 如果适配器调用了本方法 , 通知数据发生了改变 , RecyclerView 会尝试去 为适配器 同步可见的结构性改变事件 ; * 这样有助于动画和可视化对象的持续 , 但是单独的 item 元素组件需要重新被绑定 ; * * 如果你正在写一个适配器 , 使用该方法 , 比使用多个指定的变化方法 , 更加有效 ; * * @see #notifyItemChanged(int) * @see #notifyItemInserted(int) * @see #notifyItemRemoved(int) * @see #notifyItemRangeChanged(int, int) * @see #notifyItemRangeInserted(int, int) * @see #notifyItemRangeRemoved(int, int) */
        public final void notifyDataSetChanged() { 
   
            mObservable.notifyChanged();
        }
	}
}

运行效果 : 该操作没有动画效果 , 只是刷新数据显示 ;

在这里插入图片描述

三、完整代码示例


完整代码示例 仅做参考 :

package kim.hsl.recyclerview;

import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity { 
   

    /** * 数据源 */
    private ArrayList<String> names = new ArrayList<String>();

    /** * 适配器 */
    private Adapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) { 
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化数据
        initData();

        //1 . 从布局中获取 RecyclerView
        RecyclerView recycler_view = findViewById(R.id.recycler_view);

        //2 . 创建并设置布局管理器
        //创建布局管理器

        StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(
                4,
                RecyclerView.VERTICAL);

        //设置布局管理器
        recycler_view.setLayoutManager(layoutManager);

        // 设置边距
        recycler_view.addItemDecoration(new ItemDecoration());

        //3 . 创建并设置列表适配器
        adapter = new Adapter();
        recycler_view.setAdapter(adapter);

        // 初始化点击事件
        initClick();
    }

    /** * 初始化数据 */
    private void initData(){ 
   
        names.add("宋江");
        names.add("卢俊义");
        names.add("吴用");
        names.add("公孙胜");
        names.add("关胜");
        names.add("林冲");
        names.add("秦明");
        names.add("呼延灼");
        names.add("花荣");
        names.add("柴进");
        names.add("李应");
        names.add("朱仝");
        names.add("鲁智深");
        names.add("武松");
        names.add("董平");
        names.add("张清");
        names.add("杨志");
        names.add("徐宁");
        names.add("索超");
    }

    void initClick(){ 
   

        // 增加单个数据
        findViewById(R.id.insert_single).setOnClickListener(new View.OnClickListener() { 
   
            @Override
            public void onClick(View v) { 
   
                // 在集合开始添加一个元素
                names.add(0, "戴宗");

                // 通知适配器新元素添加
                adapter.notifyItemInserted(0);
            }
        });

        // 增加多个数据
        findViewById(R.id.insert_multi).setOnClickListener(new View.OnClickListener() { 
   
            @Override
            public void onClick(View v) { 
   
                // 在集合开始添加多个元素
                names.add(0, "戴宗");
                names.add(0, "刘唐");
                names.add(0, "李逵");

                // 通知适配器多个新元素添加
                adapter.notifyItemRangeInserted(0, 3);
            }
        });

        // 删除单个数据
        findViewById(R.id.delete_single).setOnClickListener(new View.OnClickListener() { 
   
            @Override
            public void onClick(View v) { 
   
                // 删除第 0 个元素
                names.remove(0);

                // 通知适配器
                adapter.notifyItemRemoved(0);
            }
        });

        // 删除多个数据
        findViewById(R.id.delete_multi).setOnClickListener(new View.OnClickListener() { 
   
            @Override
            public void onClick(View v) { 
   
                // 删除第 0 ~ 2 个元素
                names.remove(0);
                names.remove(0);
                names.remove(0);

                // 通知适配器
                adapter.notifyItemRangeRemoved(0, 3);
            }
        });


        // 修改单个数据
        findViewById(R.id.modify_single).setOnClickListener(new View.OnClickListener() { 
   
            @Override
            public void onClick(View v) { 
   
                // 替换第 0 个元素
                names.set(0, "宋江江");

                // 通知适配器
                adapter.notifyItemChanged(0);
            }
        });

        // 修改多个数据
        findViewById(R.id.modify_multi).setOnClickListener(new View.OnClickListener() { 
   
            @Override
            public void onClick(View v) { 
   
                // 替换第 0, 1, 2 个元素
                names.set(0, "宋江江");
                names.set(1, "卢俊俊");
                names.set(2, "吴用用");

                // 通知适配器
                adapter.notifyItemRangeChanged(0, 3);
            }
        });

        // 移动数据
        findViewById(R.id.move_single).setOnClickListener(new View.OnClickListener() { 
   
            @Override
            public void onClick(View v) { 
   
                // 先移除第 0 个
                names.remove(0);
                // 然后在第 7 个位置插入, 此时变为第 7 个元素
                names.add(7, "宋江");

                // 通知适配器
                adapter.notifyItemMoved(0, 7);
            }
        });

        // 数据改变
        findViewById(R.id.data_change).setOnClickListener(new View.OnClickListener() { 
   
            @Override
            public void onClick(View v) { 
   
                // 先移除第 0 个
                names.remove(0);
                // 然后在第 7 个位置插入, 此时变为第 7 个元素
                names.add(7, "宋江");

                // 删除第 0 ~ 2 个元素
                names.remove(0);
                names.remove(0);
                names.remove(0);

                adapter.notifyDataSetChanged();
            }
        });


    }

    /** * RecyclerView 适配器 */
    public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> { 
   

        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 
   
            View root_view = LayoutInflater.from(MainActivity.this)
                    .inflate(R.layout.item_recyclerview, parent, false);
            return new ViewHolder(root_view);
        }

        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) { 
   
            holder.text.setText("" + names.get(position));
        }

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

        public class ViewHolder extends RecyclerView.ViewHolder { 
   
            TextView text;
            public ViewHolder(@NonNull View itemView) { 
   
                super(itemView);
                text = itemView.findViewById(R.id.text);
            }
        }
    }


}

四、RecyclerView 相关资料


官方文档 :

使用 RecyclerView 创建动态列表 : https://developer.android.google.cn/guide/topics/ui/layout/recyclerview

高级 RecyclerView 自定义 : https://developer.android.google.cn/guide/topics/ui/layout/recyclerview-custom

RecyclerView 官方文档 : https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView

RecyclerView.Adapter 官方文档 : https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView.Adapter

RecyclerView.ViewHolder 官方文档 : https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView.ViewHolder

RecyclerView.ItemDecoration 官方文档 : https://developer.android.google.cn/reference/androidx/recyclerview/widget/RecyclerView.ItemDecoration

代码示例 :

GitHub 源码地址 : https://github.com/han1202012/001_RecyclerView

博客源码快照 : https://download.csdn.net/download/han1202012/14984775

( 使用 Android Studio 打开 )

今天的文章【RecyclerView】 十三、RecyclerView 数据更新 ( 移动数据 | 数据改变 )分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/32079.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注