前言

之前使用ListView和数据观察者来显示数据,但是这样会占用过多的资源,现在引入了RecyclerView这一组件,配合ViewModel动态的显示数据,结构上和之前非常相似,4个步骤:

  • 创建RecyclerView和显示单元
  • 创建适配器Adapter
  • Activity中使用
  • LiveData创建观察者

创建创建RecyclerView和显示单元

1、在Activity中添加RecyclerView

下载相关依赖控件(使用会自动下载),添加如下布局

<androidx.recyclerview.widget.RecyclerView
        android:id="@+id/body"
        android:layout_width="0dp"
        android:layout_height="0dp"
      app:layout_constraintBottom_toTopOf="@+id/guideline"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

注意设置ID,后续要用到

也可以可视化布局,在Containers中选中RecyclerView

android recyclerview 增加 item时的动画 recyclerview动态添加item_移动开发

2、布局显示单元

新建一个布局文件作为在RecyclerView中显示的单元,按照需要显示的数据进行布局

这里以可视化的方式布局,还是显示上份笔记中的People对象

android recyclerview 增加 item时的动画 recyclerview动态添加item_java_02

创建适配器

新建一个适配器对象使用RecyclerView.Adapter的接口,在适配器中创建内部ViewHolder声明组件,并在参数中传入内部的ViewHolder,将各个组件与数据进行绑定

1、创建内部ViewHolder

使用RecyclerView.ViewHolder接口,可以在绑定时候直接使用

//创建内部ViewHolder
    static class peoViewHolder extends RecyclerView.ViewHolder {
        TextView id, name, college;

        public peoViewHolder(@NonNull View itemView) {
            super(itemView);
            id = itemView.findViewById(R.id.cell_id);
            name = itemView.findViewById(R.id.cell_name);
            college = itemView.findViewById(R.id.cell_college);
        }
    }

2、构造组件

复写onCreateViewHolder方法构造组件,复写getItemCount告知卡片数

public class PeoAdapter extends RecyclerView.Adapter<PeoAdapter.peoViewHolder> {
 List<People> allpeos = new ArrayList<>();
 public void setPeos(List<People> allpeos) {
        this.allpeos = allpeos;
    }
    //构造组件
    @NonNull
    @Override
    public peoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //定义一个构造
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        //创建卡片  参数——————  布局,组件组,是否是根节点
        View itemView;
            itemView = layoutInflater.inflate(R.layout.cell_card, parent, false);
        //返回组件卡片
        return new peoViewHolder(itemView);
    }
    //返回组件个数
    @Override
    public int getItemCount() {
        return allpeos.size();
    }
    }

3、绑定组件

复写onBindViewHolder方法将数据与组件进行绑定,并可以在此添加事件监听

//绑定组件
    @Override
    public void onBindViewHolder(@NonNull final peoViewHolder holder, int position) {
        People people = allpeos.get(position);
        holder.id.setText(String.valueOf(position + 1));
        holder.name.setText(people.getName());
        holder.college.setText(people.getCollege());
        //添加点击事件
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Uri uri = Uri.parse("https://www.baidu.com/s?wd=" + holder.name.getText().toString());
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setData(uri);
                holder.itemView.getContext().startActivity(intent);
            }
        });
    }

在Activity中使用

1、绑定XML布局中的组件

RecyclerView recyclerView = findViewById(R.id.body);

2、设置组件管理者

这里使用系统自带的管理,如果不添加这一行代码RecyclerView不会显示

recyclerView.setLayoutManager(new LinearLayoutManager(this));

3、添加适配器

//实例化适配器
PeoAdapter adapter = new PeoAdapter();
//添加适配器
recyclerView.setAdapter(adapter);

为LiveData创建观察者

这里承接之前第一份笔记,使用ViewModelLiveData来动态的存储数据,这里在Activity中添加ViewModel并为其绑定观察者:
实例化ViewModel

注意!需要在Gradle添加如下依赖:
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

PeopleViewModel peopleViewModel = new ViewModelProvider(this).get(PeopleViewModel.class);

给ViewModel中的数据添加观察者
这里直接调用一个匿名内部类处理,当数据改变时,刷新适配器

peopleViewModel.getAllPeos().observe(this, new Observer<List<People>>() {
            @Override
            public void onChanged(List<People> people) {
                adapter.setPeos(people);
                //数据改变刷新视图
                adapter.notifyDataSetChanged();
            }
        });

至此使用RecyclerView配合LiveData动态显示数据库内容就完毕了,看一下效果:

android recyclerview 增加 item时的动画 recyclerview动态添加item_java_03

性能优化

在适配器中将onBindViewHolder中的监听移动到onCreateViewHolder,可以保证只创建一次监听者而不是每次回收都重新创建,可以减少内存占用
(一次new 和多次 new 区别)
修改onBindViewHolder中代码如下,并删除onCreateViewHolder相应部分

final peoViewHolder holder=new peoViewHolder(itemView);
        //添加点击事件
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Uri uri = Uri.parse("https://www.baidu.com/s?wd=" + holder.name.getText().toString());
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setData(uri);
                holder.itemView.getContext().startActivity(intent);
            }
        });


        return holder;

同上可以利用holder.itemView.setTag();以及holder.itemView.getTag();在卡片中放入参数,提高效率
用法如下:

holder.itemView.setTag(id,object);
 holder.itemView.getTag(id);