【RecyclerView】 十一、RecyclerView 数据更新 ( 删除单条数据 | 批量删除数据 )

简介: 【RecyclerView】 十一、RecyclerView 数据更新 ( 删除单条数据 | 批量删除数据 )

文章目录

一、删除单条数据

二、批量删除数据

三、完整代码示例

四、RecyclerView 相关资料





一、删除单条数据


删除单条数据 : 调用 RecyclerView.Adapter 的 void notifyItemRemoved(int position) 方法 , 传入的参数是被删除元素的索引 ( 删除之前的索引值 ) ;


该方法的作用是通知任何被注册的观察者 , position 位置的 item 元素对应的数据被从数据集中删除 ;


该位置之后的元素 ( 原来的位置是 oldPosition ) 目前在 oldPosition - 1 位置 ;



int position 参数 : 当前 RecyclerView 列表中被移出的 item 元素索引 , 也就是说之前的数据集合中被移出的数据索引 ;



注意 : 调用该方法后 , 只会刷新与该位置相关的 item 元素 , 不会刷新其它元素 , 即使数据改变了 , 也不会刷新 ;



代码示例 : 删除第 0 00 个元素 , 后续元素会依次递进补充上去 , 有相应的动画触发 ;


           

// 删除第 0 个元素
                names.remove(0);
                // 通知适配器
                adapter.notifyItemRemoved(0);


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


public class RecyclerView extends ViewGroup implements ScrollingView,
        NestedScrollingChild2, NestedScrollingChild3 {
    public abstract static class Adapter<VH extends ViewHolder> {
        /**
         * 通知任何被注册的观察者 , position 位置的 item 元素对应的数据被从数据集中删除 ;
         * 该位置之后的元素 ( 原来的位置是 oldPosition ) 目前在 oldPosition - 1 位置 ; 
         *
         * 这是一个结构性的变化事件 ; 
         * 表示在数据集中的其它元素仍然被认为是最新的数据 , 这些数据不会被重新绑定 , 
         * 尽管它们的位置已经发生了变化 ;
         *
         * @param position 当前 RecyclerView 列表中被移出的 item 元素索引 ;
         *
         * @see #notifyItemRangeRemoved(int, int)
         */
        public final void notifyItemRemoved(int position) {
            mObservable.notifyItemRangeRemoved(position, 1);
        }
  }
}



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


image.png






二、批量删除数据


批量删除数据 : 调用 RecyclerView.Adapter 的 void notifyItemRangeInserted(int positionStart, int itemCount) 方法 , 传入的参数是被删除的元素的首个索引 , 以及插入元素的个数 ;


该方法的作用是通知任何被注册的观察者 , 从 positionStart 位置开始的的 itemCount 个 item 元素对应的数据被从数据集中删除 ;


该位置之后的元素 ( 原来的位置是 oldPosition ) 目前在 oldPosition - itemCount 位置 ;



参数说明 :


int positionStart 参数 : 被删除的元素在原数据集中首个元素的位置索引 ; ( 旧的数据集中的索引位置 )


int itemCount 参数 : 数据集中被删除元素个数 ;



注意 : 调用该方法后 , 只会刷新与该位置相关的 item 元素 , 不会刷新其它元素 , 即使数据改变了 , 也不会刷新 ; 也就是说 RecyclerView 只刷新涉及到的 positionStart ~ positionStart + itemCount 之间的这几个元素 , RecyclerView 中的其它 item 元素不变 ;



代码示例 : 删除前 3 33 个数据 , 通知适配器 , 原数据集中的从第 0 00 个元素开始的 3 33 个数据元素被删除了 ;


           

// 删除第 0 ~ 2 个元素
                names.remove(0);
                names.remove(0);
                names.remove(0);
                // 通知适配器
                adapter.notifyItemRangeRemoved(0, 3);


RecyclerView.Adapter.notifyItemRangeRemoved(int positionStart, int itemCount) 函数原型 : 该函数定义在 RecyclerView 的内部类 Adapter 中 ;


public class RecyclerView extends ViewGroup implements ScrollingView,
        NestedScrollingChild2, NestedScrollingChild3 {
    public abstract static class Adapter<VH extends ViewHolder> {
        /**
         * 通知任何被注册的观察者 , 从 positionStart 位置开始的的 itemCount 个 item 元素对应的数据被从数据集中删除 ;
         * 该位置之后的元素 ( 原来的位置是 oldPosition ) 目前在 oldPosition - itemCount 位置 ; 
         * 
         * 这是一个结构性的变化事件 ; 
         * 表示在数据集中的其它元素仍然被认为是最新的数据 , 这些数据不会被重新绑定 , 
         * 尽管它们的位置已经发生了变化 ;
         * 也就是说 RecyclerView 只刷新涉及到的 positionStart ~ positionStart + itemCount 之间的这几个元素 , 
         * 其它元素不变 ; 
         *
         * @param positionStart 被删除的元素在原数据集中首个元素的位置索引 ;
         * @param itemCount 数据集中被删除元素个数 ;
         */
        public final void notifyItemRangeRemoved(int positionStart, int itemCount) {
            mObservable.notifyItemRangeRemoved(positionStart, itemCount);
        }
  }
}



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


image.png






三、完整代码示例


完整代码示例 仅做参考 :


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);
            }
        });
    }
    /**
     * 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 打开 )


目录
相关文章
|
开发者 Docker Python
深入浅出:使用Docker容器化部署Python Web应用
在当今快速发展的软件开发领域,Docker作为一个开放平台,为开发者提供了将应用打包在轻量级、可移植的容器中的能力,从而简化了部署和管理应用程序的复杂性。本文将通过一个简单的Python Web应用示例,引导读者理解Docker的基本概念、容器化的优势以及如何使用Docker来容器化部署Python Web应用。我们将从零开始,逐步探索创建Dockerfile、构建镜像、运行容器等关键步骤,旨在为读者提供一个清晰、易于理解的指南,帮助他们掌握使用Docker容器化部署应用的技能。
|
安全 IDE Java
淘宝短视频流工程重构(下):实践篇-2
淘宝短视频流工程重构(下):实践篇
178 8
|
传感器 网络协议 物联网
嵌入式开发中的常用实时操作系统(RTOS)介绍
选择合适的RTOS是嵌入式开发中的关键步骤,不同的RTOS具有各自的优势和适用场景。开发者需要根据项目需求综合考虑硬件平台、实时性要求、开发资源和支持等因素,选择最合适的RTOS系统。例如,如果需要开源和灵活的解决方案,可以选择Zephyr或RT-Thread;如果需要高性能和商业支持,可以选择VxWorks或ThreadX。希望本文能帮助您更好地了解各类RTOS,并为您的嵌入式开发项目提供参考。
972 1
|
监控 测试技术 Android开发
淘宝短视频流工程重构(下):实践篇-1
淘宝短视频流工程重构(下):实践篇
176 8
|
Android开发 开发者
关于将Android AAB转化为APK
本篇文章主要讲如何将AAB转化为APK,虽然说我们上传到Google Play的AAB,是有Google Play自己去转化为APK给用户下载的,但是作为开发者的我们,也是需要知道应该如何转化的,毕竟我们还是要做测试的,当你拿到一个AAB文件的时候,你得知道如何将它转化成APK,然后安装在手机上,测试需要测试的内容。
1763 1
|
Android开发 容器
Android QS面板源码(下)
Android QS面板源码(下)
Android QS面板源码(下)
|
双11 Android开发
Android动态来改变App桌面图标
其实对于这样的一个桌面图标更换,Android中为我们提供了AndroidManifest.xml里的<activity-alias>标签实现方式。
627 0
|
Android开发 容器
|
Ubuntu JavaScript 虚拟化
鸿蒙开发板利用串口通信的基本原理与实现
大家好,今天主要来学习一下,如何使用Hi3861通过UART串口与其它开发板进行通信方法。
2709 0
鸿蒙开发板利用串口通信的基本原理与实现