1. 数据库添加 chinese_invisible 字段,标识显示或者隐藏View
1.1 修改 Word 类
@Entity
public class Word {
@PrimaryKey(autoGenerate = true)
private int id; //主键
@ColumnInfo(name = "english_word")
private String word;
@ColumnInfo(name = "chinese_meaning")
private String chineseMeaning;
@ColumnInfo(name = "chinese_invisible")
private boolean chineseInvisible;
// @ColumnInfo(name = "foo_data")
// private boolean foo;
// @ColumnInfo(name = "bar_data")
// private boolean bar;
public Word(String word, String chineseMeaning) {
this.word = word;
this.chineseMeaning = chineseMeaning;
}
public boolean isChineseInvisible() {
return chineseInvisible;
}
public void setChineseInvisible(boolean chineseInvisible) {
this.chineseInvisible = chineseInvisible;
}
// public boolean isBar() {
// return bar;
// }
//
// public void setBar(boolean bar) {
// this.bar = bar;
// }
//
// public boolean isFoo() {
// return foo;
// }
//
// public void setFoo(boolean foo) {
// this.foo = foo;
// }
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public String getChineseMeaning() {
return chineseMeaning;
}
public void setChineseMeaning(String chineseMeaning) {
this.chineseMeaning = chineseMeaning;
}
}
1.2 修改 WordDatabase 类,修改数据库版本和策略
//singleton 只允许生成一个实例
@Database(entities = {Word.class}, version = 5, exportSchema = false)
public abstract class WordDatabase extends RoomDatabase {
private static WordDatabase INSTANCE;
//synchronized: 解决多个线程下调用,创建多个实例问题
static synchronized WordDatabase getDatabase(Context context) {
if (INSTANCE == null) {
//fallbackToDestructiveMigration 把当前的数据清空,创建新的库
//addMigrations 添加迁移的策略
INSTANCE = Room.databaseBuilder(context.getApplicationContext(), WordDatabase.class, "word_database")
.addMigrations(migration_4_5)
.build();
}
return INSTANCE;
}
public abstract WordDao getWordDao();
static final Migration migration_4_5 = new Migration(4, 5) {
@Override
public void migrate(@NonNull SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE word ADD COLUMN chinese_invisible INTEGER NOT NULL DEFAULT 0");
}
};
}
2. 修改 RecyclerView 的 item View
2.1 添加 cell_normal_2.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="60dp"
android:foreground="?attr/selectableItemBackground">
<View
android:id="@+id/divider"
android:layout_width="1dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/listDivider"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/constraintLayout2"
app:layout_constraintStart_toStartOf="@+id/guideline7"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout2"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline7"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.15" />
<TextView
android:id="@+id/tv_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline10"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="1" />
<TextView
android:id="@+id/tv_english"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="TextView"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@+id/tv_chinese"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/guideline10"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_chinese"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/tv_english"
app:layout_constraintTop_toBottomOf="@+id/tv_english" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline7"
app:layout_constraintTop_toTopOf="parent">
<Switch
android:id="@+id/switchChineseInvisible"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:paddingStart="30dp"
android:paddingEnd="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="UseSwitchCompatOrMaterialXml" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.8" />
</androidx.constraintlayout.widget.ConstraintLayout>
2.2 添加 cell_card_2.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="70dp">
<androidx.cardview.widget.CardView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:foreground="?attr/selectableItemBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/divider2"
android:layout_width="1dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
android:background="?android:attr/listDivider"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline9"
app:layout_constraintStart_toEndOf="@+id/guideline9"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline9"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.15" />
<TextView
android:id="@+id/tv_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="16sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/guideline11"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="1" />
<TextView
android:id="@+id/tv_english"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:text="TextView"
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@+id/tv_chinese"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/guideline11"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_chinese"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="@+id/tv_english"
app:layout_constraintTop_toBottomOf="@+id/tv_english" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/constraintLayout2"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline9"
app:layout_constraintTop_toTopOf="parent">
<Switch
android:id="@+id/switchChineseInvisible"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:paddingStart="30dp"
android:paddingEnd="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.8" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
3. 修改适配器 Adapter
/内容管理器
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private List<Word> allWords = new ArrayList<>();
private boolean useCardView;
private WordViewModel viewModel;
public void setAllWords(List<Word> allWords) {
this.allWords = allWords;
}
public MyAdapter(boolean useCardView, WordViewModel viewModel) {
this.useCardView = useCardView;
this.viewModel = viewModel;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View itemView;
if (useCardView) {
itemView = layoutInflater.inflate(R.layout.cell_card_2, parent, false);
} else {
itemView = layoutInflater.inflate(R.layout.cell_normal_2, parent, false);
}
return new MyViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
Word word = allWords.get(position);
holder.tvNumber.setText(String.valueOf(position + 1));
holder.tvEnglish.setText(word.getWord());
holder.tvChinese.setText(word.getChineseMeaning());
//设置为空,防止再次调用 OnCheckedChangeListener 监听
holder.aSwitchChineseInvisible.setOnCheckedChangeListener(null);
if (word.isChineseInvisible()) {
holder.tvChinese.setVisibility(View.GONE);
holder.aSwitchChineseInvisible.setChecked(true);
} else {
holder.tvChinese.setVisibility(View.VISIBLE);
holder.aSwitchChineseInvisible.setChecked(false);
}
holder.itemView.setOnClickListener(view -> {
Uri uri = Uri.parse("https://m.youdao.com/m/result?lang=en&word=" + word.getWord());
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
holder.itemView.getContext().startActivity(intent);
});
holder.aSwitchChineseInvisible.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
if (isChecked) {
holder.tvChinese.setVisibility(View.GONE);
word.setChineseInvisible(true);
viewModel.updateWords(word);
} else {
holder.tvChinese.setVisibility(View.VISIBLE);
word.setChineseInvisible(false);
viewModel.updateWords(word);
}
}
});
}
@Override
public int getItemCount() {
return allWords.size();
}
static class MyViewHolder extends RecyclerView.ViewHolder {
TextView tvNumber, tvEnglish, tvChinese;
Switch aSwitchChineseInvisible;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
tvNumber = itemView.findViewById(R.id.tv_number);
tvEnglish = itemView.findViewById(R.id.tv_english);
tvChinese = itemView.findViewById(R.id.tv_chinese);
aSwitchChineseInvisible = itemView.findViewById(R.id.switchChineseInvisible);
}
}
}
4. 测试调用 MainActivity
public class MainActivity extends AppCompatActivity {
Button btInsert, btClear;
Switch aSwitch;
WordViewModel viewModel;
RecyclerView recyclerView;
MyAdapter myAdapter1, myAdapter2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewModel = new ViewModelProvider(this).get(WordViewModel.class);
myAdapter1 = new MyAdapter(false, viewModel);
myAdapter2 = new MyAdapter(true, viewModel);
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(myAdapter1);
aSwitch = findViewById(R.id.switch1);
aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChanged) {
if (isChanged) {
recyclerView.setAdapter(myAdapter2);
} else {
recyclerView.setAdapter(myAdapter1);
}
}
});
viewModel.getAllWordsLive().observe(this, new Observer<List<Word>>() {
@Override
public void onChanged(List<Word> words) {
int size = myAdapter1.getItemCount();
myAdapter1.setAllWords(words);
myAdapter2.setAllWords(words);
if (size != words.size()) {
myAdapter1.notifyDataSetChanged();
myAdapter2.notifyDataSetChanged();
}
}
});
View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.bt_insert:
String[] english = {
"Hello",
"World",
"Android",
"Google",
"Studio",
"Project",
"Database",
"Recycler",
"View",
"String",
"Value",
"Integer"
};
String[] chinese = {
"你好",
"世界",
"安卓",
"谷歌",
"工作室",
"项目",
"数据库",
"回收站",
"视图",
"字符串",
"值",
"整数类型"
};
for (int i = 0; i < english.length; i++) {
viewModel.insertWords(new Word(english[i], chinese[i]));
}
break;
case R.id.bt_clear:
viewModel.deleteAllWords();
break;
}
}
};
btInsert = findViewById(R.id.bt_insert);
btClear = findViewById(R.id.bt_clear);
btInsert.setOnClickListener(listener);
btClear.setOnClickListener(listener);
}
}
5. 效果图