Room(五)
将数据修改应用到UI
数据库中已经增加一条chinese_invisible的字段,用于记录中文意思是否显示。在ui中用一个switch来操作这一个数据段。
在recyclerView中,会给每一个switch绑定一个监听器,并且也会根据数据库中的字段来设置这个switch的初始状态。由于recyclerView是循环使用的,所以这个初始化操作可能会触发监听器,以改变数据库内容,为了解决这个bug,可以在初始化之前先将监听器设置为null:
@Override
public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {
final Word word=allWords.get(position);
holder.textViewNumber.setText(String.valueOf(position+1));
holder.textViewEnglish.setText(word.getWord());
holder.textViewChinese.setText(word.getChineseMeaning());
holder.aSwitchChineseInvisible.setOnCheckedChangeListener(null);//!!防止回收的recyclerView会触发listener
if (word.isChineseInvisible()){
holder.textViewChinese.setVisibility(View.GONE);
holder.aSwitchChineseInvisible.setChecked(true);
}else {
holder.textViewChinese.setVisibility(View.VISIBLE);
holder.aSwitchChineseInvisible.setChecked(false);
}
holder.aSwitchChineseInvisible.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b){
holder.textViewChinese.setVisibility(View.GONE);
word.setChineseInvisible(true);
}else {
holder.textViewChinese.setVisibility(View.VISIBLE);
word.setChineseInvisible(false);
}
wordViewModel.updateWords(word);
}
});
}
由于ViewModel是利用LiveData来存储数据的,修改chineseInvisible的值,会导致LiveData的Observer被触发、更新UI,这样会在一个时间内进行两次UI的更新,会导致应用卡顿。很明显修改chineseInvisible不会导致数据元组数量改变,因此不需要去更新Apapter,可以在LiveData的Observe方法中取消修改操作会导致的UI更新。
//MainActivity
wordViewModel.getAllWordsLive().observe(this, new Observer<List<Word>>() {
@Override
public void onChanged(List<Word> words) {
//在adapter中修改switch时也会触发这里更新视图,可以跳过修改操作
int temp=myAdapter1.getItemCount();
myAdapter1.setAllWords(words);
myAdapter2.setAllWords(words);
if (temp!=words.size()){
myAdapter2.notifyDataSetChanged();//通知数据更新
myAdapter1.notifyDataSetChanged();//通知数据更新
}
}
});
扩大Switch的响应范围
可以设置switch的高度为match_constraint,宽度用padding来设置(宽度用match_constraint会导致switch右侧靠拢)。
添加分割线
使用Android自带的widgets中的Vertical DIvider,参数如下
<View
android:id="@+id/divider"
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/listDivider"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/constraintLayout"
app:layout_constraintStart_toStartOf="@+id/guideline6"
app:layout_constraintTop_toTopOf="parent" />