Room(三)
使用RecycleView显示数据
使用recyclerView的最核心步骤就是写出adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
List<Word> allWords=new ArrayList<>();
public void setAllWords(List<Word> allWords) {
this.allWords = allWords;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater=LayoutInflater.from(parent.getContext());
View itemView=layoutInflater.inflate(R.layout.cell_normal,parent,false);
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
Word word=allWords.get(position);
holder.textViewNumber.setText(String.valueOf(position+1));
holder.textViewEnglish.setText(word.getWord());
holder.textViewChinese.setText(word.getChineseMeaning());
}
@Override
public int getItemCount() {
return allWords.size();
}
static class MyViewHolder extends RecyclerView.ViewHolder{
TextView textViewNumber,textViewEnglish,textViewChinese;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
textViewNumber=itemView.findViewById(R.id.textViewNumber);
textViewEnglish=itemView.findViewById(R.id.textViewEnglish);
textViewChinese=itemView.findViewById(R.id.textViewChinese);
}
}
}
然后,需要将这个adapter绑定到recyclerView中去。recyclerView还需要设置布局。
recyclerView=findViewById(R.id.recyclerView);
myAdapter=new MyAdapter();
recyclerView.setLayoutManager(new LinearLayoutManager(this));//设置
recyclerView.setAdapter(myAdapter);
由于数据使用liveData存储的,只需要在观察者中维护adpater的数据就可以了。
wordViewModel.getAllWordsLive().observe(this, new Observer<List<Word>>() {
@Override
public void onChanged(List<Word> words) {
myAdapter.setAllWords(words);
myAdapter.notifyDataSetChanged();//通知数据更新
}
});
使用cardView
使用cardView可以使得能够将所有的view都放在一张张卡片(直观的)中,cardView也是一个容器类,也需要调整内部的布局方式和设置边界。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="1dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
app:layout_constraintBottom_toTopOf="@+id/textViewChinese"
app:layout_constraintEnd_toStartOf="@+id/guideline5"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/guideline4"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textViewChinese"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/textViewEnglish"
app:layout_constraintTop_toBottomOf="@+id/textViewEnglish" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
效果如下:
为recyclerView设置两套adapter
创建两个adapter,这两个adapter是并行的、等价的,他们同时接受数据的更新,只不过其用的ViewHolder的视图资源并不相同。可以用一个switch来对其使用进行切换。
aSwitch=findViewById(R.id.switch1);
aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b){
recyclerView.setAdapter(myAdapter2);
}else {
recyclerView.setAdapter(myAdapter1);
}
}
});
recyclerView=findViewById(R.id.recyclerView);
myAdapter1=new MyAdapter(false);
myAdapter2=new MyAdapter(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));//设置
recyclerView.setAdapter(myAdapter1);
为itemView设置点击时的回馈
在视图资源的根节点为其设置clickable为true,
相当于代码中增加了
android:clickable="true"
这句话。
再设置background:
android:background="?attr/selectableItemBackground"
在有cardView的视图资源中,如果还是从顶层容器设置背景的话,反馈的波纹会被cardView遮挡住,此时需要在cardView中设置前景。
android:foreground="?attr/selectableItemBackground"
效果图: