之前使用ListView
和数据观察者来显示数据,但是这样会占用过多的资源,现在引入了RecyclerView
这一组件,配合ViewModel
动态的显示数据,结构上和之前非常相似,4个步骤:
RecyclerView
和显示单元Adapter
Activity
中使用LiveData
创建观察者RecyclerView
和显示单元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
新建一个布局文件作为在RecyclerView
中显示的单元,按照需要显示的数据进行布局
这里以可视化的方式布局,还是显示上份笔记中的People对象
新建一个适配器对象使用RecyclerView.Adapter
的接口,在适配器中创建内部ViewHolder
声明组件,并在参数中传入内部的ViewHolder,将各个组件与数据进行绑定
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);
}
}
复写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();
}
}
复写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);
}
});
}
RecyclerView recyclerView = findViewById(R.id.body);
这里使用系统自带的管理,如果不添加这一行代码RecyclerView不会显示
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//实例化适配器
PeoAdapter adapter = new PeoAdapter();
//添加适配器
recyclerView.setAdapter(adapter);
这里承接之前第一份笔记,使用ViewModel
和LiveData
来动态的存储数据,这里在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动态显示数据库内容就完毕了,看一下效果:
在适配器中将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);