1. 用到的组件 Room,ViewModel,LiveData,Repository,AsyncTack
2. Module 中 build.gradle 文件中添加
dependencies {
def room_version = "2.4.3"
implementation "androidx.room:room-runtime:$room_version"
annotationProcessor "androidx.room:room-compiler:$room_version"
}
3. 数据操作
3.1 Word 实体类, Word.java
@Entity
public class Word {
@PrimaryKey(autoGenerate = true)
private int id; //主键
@ColumnInfo(name = "english_word")
private String word;
@ColumnInfo(name = "chinese_meaning")
private String chineseMeaning;
public Word(String word, String chineseMeaning) {
this.word = word;
this.chineseMeaning = chineseMeaning;
}
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;
}
}
3.2 实现 Database 接口, WordDao.java
@Dao //Database access object
public interface WordDao {
@Insert
void insertWords(Word... words);
@Update
void updateWords(Word... words);
@Delete
void deleteWords(Word... words);
@Query("DELETE FROM WORD")
void deleteAllWords();
@Query("SELECT * FROM WORD ORDER BY ID DESC")
LiveData> getAllWordsLive();
//List getAllWords();
}
3.3 Database 管理操作数据库, WordDatabase.java
//singleton 只允许生成一个实例
@Database(entities = {Word.class}, version = 1, exportSchema = false)
public abstract class WordDatabase extends RoomDatabase {
private static WordDatabase INSTANCE;
//synchronized: 解决多个线程下调用,创建多个实例问题
static synchronized WordDatabase getDatabase(Context context) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(), WordDatabase.class, "word_database")
.build();
}
return INSTANCE;
}
public abstract WordDao getWordDao();
}
3.4 Repository 操作数据库, WordRepository.java
//Repository 仓库 获取数据的意思
class WordRepository {
private WordDao wordDao;
private LiveData> allWordsLive;
WordRepository(Context context) {
WordDatabase wordDatabase = WordDatabase.getDatabase(context);
wordDao = wordDatabase.getWordDao();
allWordsLive = wordDao.getAllWordsLive();
}
LiveData> getAllWordsLive() {
return allWordsLive;
}
void insertWords(Word... words) {
new InsertAsyncTask(wordDao).execute(words);
}
void updateWords(Word... words) {
new UpdateAsyncTask(wordDao).execute(words);
}
void deleteWords(Word... words) {
new DeleteAsyncTask(wordDao).execute(words);
}
void deleteAllWords() {
new DeleteAllAsyncTask(wordDao).execute();
}
static class InsertAsyncTask extends AsyncTask {
private WordDao wordDao;
InsertAsyncTask(WordDao wordDao) {
this.wordDao = wordDao;
}
@Override
protected Void doInBackground(Word... words) {
wordDao.insertWords(words);
return null;
}
}
static class UpdateAsyncTask extends AsyncTask {
private WordDao wordDao;
UpdateAsyncTask(WordDao wordDao) {
this.wordDao = wordDao;
}
@Override
protected Void doInBackground(Word... words) {
wordDao.updateWords(words);
return null;
}
}
static class DeleteAsyncTask extends AsyncTask {
private WordDao wordDao;
DeleteAsyncTask(WordDao wordDao) {
this.wordDao = wordDao;
}
@Override
protected Void doInBackground(Word... words) {
wordDao.deleteWords(words);
return null;
}
}
static class DeleteAllAsyncTask extends AsyncTask {
private WordDao wordDao;
DeleteAllAsyncTask(WordDao wordDao) {
this.wordDao = wordDao;
}
@Override
protected Void doInBackground(Void... voids) {
this.wordDao.deleteAllWords();
return null;
}
}
}
4. 实现 ViewModel, WordViewModel.java
public class WordViewModel extends AndroidViewModel {
private WordRepository wordRepository;
public WordViewModel(@NonNull Application application) {
super(application);
wordRepository = new WordRepository(application);
}
public LiveData> getAllWordsLive() {
return wordRepository.getAllWordsLive();
}
void insertWords(Word... words) {
wordRepository.insertWords(words);
}
void updateWords(Word... words) {
wordRepository.updateWords(words);
}
void deleteWords(Word... words) {
wordRepository.deleteWords(words);
}
void deleteAllWords() {
wordRepository.deleteAllWords();
}
}
5. RecyclerView 的实现
5.1 资源文件进入页面提示标志 ic_baseline_chevron_right_24.xml
5.2 列表子布局常规 item, cell_normal.xml
5.3 列表子布局 cardView item, cell_card.xml
5.4 RecyclerView 内容管理器 Adapter, MyAdapter.java
//内容管理器
public class MyAdapter extends RecyclerView.Adapter {
private List allWords = new ArrayList<>();
private boolean useCardView;
public void setAllWords(List allWords) {
this.allWords = allWords;
}
public MyAdapter(boolean useCardView) {
this.useCardView = useCardView;
}
@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, parent, false);
} else {
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.tvNumber.setText(String.valueOf(position + 1));
holder.tvEnglish.setText(word.getWord());
holder.tvChinese.setText(word.getChineseMeaning());
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);
});
}
@Override
public int getItemCount() {
return allWords.size();
}
static class MyViewHolder extends RecyclerView.ViewHolder {
TextView tvNumber, tvEnglish, tvChinese;
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);
}
}
}
6. 测试调用
6.1 布局文件,activity_main.xml
6.2 测试文件,MainActivity. java
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);
myAdapter1 = new MyAdapter(false);
myAdapter2 = new MyAdapter(true);
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 = new ViewModelProvider(this).get(WordViewModel.class);
viewModel.getAllWordsLive().observe(this, new Observer>() {
@Override
public void onChanged(List words) {
myAdapter1.setAllWords(words);
myAdapter1.notifyDataSetChanged();
myAdapter2.setAllWords(words);
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);
}
}
7.效果图