这几天一直做这个实战,学习到了很多东西,并且自己加上了注释
MainActivity
package com.example.roombasic; import androidx.appcompat.app.AppCompatActivity; import androidx.navigation.NavController; import androidx.navigation.fragment.NavHostFragment; import androidx.navigation.ui.NavigationUI; import android.os.Bundle; public class MainActivity extends AppCompatActivity { NavController controller; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); NavHostFragment navHostFragment= (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragmentContainerView3); controller=navHostFragment.getNavController(); NavigationUI.setupActionBarWithNavController(this, controller);//创建上面的箭头 } @Override public boolean onSupportNavigateUp() {//使得上面的箭头可以用来返回 controller.navigateUp(); return super.onSupportNavigateUp(); } }
Word
package com.example.roombasic; import androidx.room.ColumnInfo; import androidx.room.Entity; import androidx.room.PrimaryKey; @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; public boolean isChineseInvisible() { return chineseInvisible; } public void setChineseInvisible(boolean chineseInvisible) { this.chineseInvisible = chineseInvisible; } 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; } }
WordViewModel
package com.example.roombasic; import android.app.Application; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import java.util.List; public class WordViewModel extends AndroidViewModel { private final WordRepository wordRepository; public WordViewModel(@NonNull Application application) { super(application); wordRepository = new WordRepository(application); } LiveData<List<Word>> getAllWordsLive() { return wordRepository.getAllWordsLive(); } LiveData<List<Word>> findWordsWithPattern(String pattern){ return wordRepository.findWordsWithPattern(pattern); } 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(); } }
WordRepository
package com.example.roombasic; import android.app.Application; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import java.util.List; public class WordViewModel extends AndroidViewModel { private final WordRepository wordRepository; public WordViewModel(@NonNull Application application) { super(application); wordRepository = new WordRepository(application); } LiveData<List<Word>> getAllWordsLive() { return wordRepository.getAllWordsLive(); } LiveData<List<Word>> findWordsWithPattern(String pattern){ return wordRepository.findWordsWithPattern(pattern); } 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(); } }
WordDao
package com.example.roombasic; import androidx.lifecycle.LiveData; import androidx.room.Dao; import androidx.room.Delete; import androidx.room.Insert; import androidx.room.Query; import androidx.room.Update; import java.util.List; //dao层,增删改查数据 @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<List<Word>>getAllWordsLive(); @Query("SELECT * FROM WORD WHERE english_word LIKE :pattern ORDER BY ID DESC") LiveData<List<Word>>findWordWithPattern(String pattern); }
WordDataBase
package com.example.roombasic; import android.content.Context; import androidx.room.Database; import androidx.room.Room; import androidx.room.RoomDatabase; //singleton @Database(entities = {Word.class}, version = 1, exportSchema = false) public abstract class WordDatabase extends RoomDatabase { private static WordDatabase INSTANCE; 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(); }
MyAdapter
package com.example.roombasic; import android.annotation.SuppressLint; import android.content.Intent; import android.net.Uri; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.CompoundButton; import android.widget.Switch; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import java.util.List; public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { private List<Word> allWords = new ArrayList<>(); private boolean useCardView; private WordViewModel wordViewModel; MyAdapter(boolean useCardView, WordViewModel wordViewModel) {//构造函数 this.useCardView = useCardView; this.wordViewModel = wordViewModel; } 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; if (useCardView) {//分别将两种界面赋值给itView itemView = layoutInflater.inflate(R.layout.cell_card_2,parent,false); } else { itemView = layoutInflater.inflate(R.layout.cell_normal,parent,false); } MyViewHolder holder=new MyViewHolder(itemView);//实例化MyViewHolder holder.itemView.setOnClickListener(new View.OnClickListener() {//点击itView触发事件 @Override public void onClick(View view) { Uri uri = Uri.parse("https://m.youdao.com/dict?le=eng&q=" + holder.textViewEnglish.getText()); 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 b) { Word word=(Word)holder.itemView.getTag(R.id.word_foe_view_holder); if (b) { holder.textViewChinese.setVisibility(View.GONE);//当开关触发时,使得textViewChinese完全消失 word.setChineseInvisible(true);//更改数据 wordViewModel.updateWords(word);//将数据同步到数据库 } else { holder.textViewChinese.setVisibility(View.VISIBLE); word.setChineseInvisible(false); wordViewModel.updateWords(word); } } }); return holder; } @Override public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) { final Word word = allWords.get(position);//从头逐个获取word holder.itemView.setTag(R.id.word_foe_view_holder,word); holder.textViewNumber.setText(String.valueOf(position + 1)); holder.textViewEnglish.setText(word.getWord()); holder.textViewChinese.setText(word.getChineseMeaning()); if (word.isChineseInvisible()) {// 根据数据库中数据的值,来确定要不要保留中文 holder.textViewChinese.setVisibility(View.GONE); holder.aSwitchChineseInvisible.setChecked(true); } else { holder.textViewChinese.setVisibility(View.VISIBLE); holder.aSwitchChineseInvisible.setChecked(false); } } @Override public int getItemCount() { return allWords.size(); } static class MyViewHolder extends RecyclerView.ViewHolder {//绑定各个控件 TextView textViewNumber,textViewEnglish,textViewChinese; Switch aSwitchChineseInvisible; MyViewHolder(@NonNull View itemView) { super(itemView); textViewNumber = itemView.findViewById(R.id.textViewNumber); textViewEnglish = itemView.findViewById(R.id.textViewEnglish); textViewChinese = itemView.findViewById(R.id.textViewChinese); aSwitchChineseInvisible = itemView.findViewById(R.id.switchChineseInvisible); } } }
WordFragment
package com.example.roombasic; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.SearchView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.LiveData; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModelProvider; import androidx.navigation.NavController; import androidx.navigation.Navigation; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; import java.util.List; /** * A simple {@link Fragment} subclass. */ public class WordFragment extends Fragment { private WordViewModel wordViewModel; private RecyclerView recyclerView; private MyAdapter myAdapter1, myAdapter2; private LiveData<List<Word>> filteredWords; private static final String VIEW_TYPE_SHP = "view_type"; private static final String IS_USING_CARD_VIEW = "is_using"; private List<Word> allWords; public WordFragment() { // Required empty public constructor setHasOptionsMenu(true); } @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { //右上角的三个点对应的菜单 switch (item.getItemId()) { case R.id.cleardata://清空数据 AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());//创建对话框,用于清除数据是否确认 builder.setTitle("是否清空数据"); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {//确认按钮键 @Override public void onClick(DialogInterface dialogInterface, int i) { wordViewModel.deleteAllWords(); } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {//取消按钮键 @Override public void onClick(DialogInterface dialogInterface, int i) { } }); builder.create();//创建 builder.show();//展示 break;//跳出switch case R.id.switchview://切换视图 SharedPreferences shp = requireActivity().getSharedPreferences(VIEW_TYPE_SHP, Context.MODE_PRIVATE);//键值保存 boolean viewType = shp.getBoolean(IS_USING_CARD_VIEW, false); SharedPreferences.Editor editor = shp.edit(); if (viewType) { recyclerView.setAdapter(myAdapter1); editor.putBoolean(IS_USING_CARD_VIEW, false); } else { recyclerView.setAdapter(myAdapter2); editor.putBoolean(IS_USING_CARD_VIEW, true); } editor.apply(); } return super.onOptionsItemSelected(item); } @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {//在WordFragment上绑定新建的菜单资源 super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.mai_menu, menu); SearchView searchView = (SearchView) menu.findItem(R.id.app_bar_search).getActionView();//绑定搜索键 searchView.setMaxWidth(600); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {//添加搜索键功能 @Override public boolean onQueryTextSubmit(String s) { return false; } @Override public boolean onQueryTextChange(String s) { String pattern = s.trim();//去除多余空格 filteredWords.removeObservers(requireActivity());//在使用模糊查询之前,要先把之前的观察者移除掉,把96行的观察者移除掉 filteredWords = wordViewModel.findWordsWithPattern(pattern);//获取返回的模糊查询的数据列表 filteredWords.observe(requireActivity(), new Observer<List<Word>>() { @Override public void onChanged(List<Word> words) { int temp = myAdapter1.getItemCount(); allWords = words; myAdapter1.setAllWords(words); myAdapter2.setAllWords(words); if (temp != words.size()) { myAdapter1.notifyDataSetChanged(); myAdapter2.notifyDataSetChanged(); } } }); return true; } }); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_word, container, false); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); wordViewModel = new ViewModelProvider(requireActivity(), ViewModelProvider.AndroidViewModelFactory.getInstance(getActivity().getApplication())).get(WordViewModel.class); recyclerView = requireActivity().findViewById(R.id.word_recycle); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));//设置数据垂直放置 myAdapter1 = new MyAdapter(false, wordViewModel); myAdapter2 = new MyAdapter(true, wordViewModel); SharedPreferences shp = requireActivity().getSharedPreferences(VIEW_TYPE_SHP, Context.MODE_PRIVATE); boolean viewType = shp.getBoolean(IS_USING_CARD_VIEW, false); if (viewType) { recyclerView.setAdapter(myAdapter2); } else { recyclerView.setAdapter(myAdapter1); } filteredWords = wordViewModel.getAllWordsLive(); filteredWords.observe(requireActivity(), new Observer<List<Word>>() { @Override public void onChanged(List<Word> words) { int temp = myAdapter1.getItemCount(); allWords = words; myAdapter1.setAllWords(words); myAdapter2.setAllWords(words); if (temp != words.size()) { myAdapter1.notifyDataSetChanged(); myAdapter2.notifyDataSetChanged(); } } }); new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.START | ItemTouchHelper.END) {//使得view可以左滑,右滑;还可以上滑下滑 @Override public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { return false; } @Override public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { Word word = allWords.get(viewHolder.getAdapterPosition()); wordViewModel.deleteWords(word); Snackbar.make(requireActivity().findViewById(R.id.wordsFragmentView), "删除了一个词汇", Snackbar.LENGTH_SHORT)//弹出一个小窗口,可以做出操作 .setAction("撤销", new View.OnClickListener() {//设置小窗口上的操作 @Override public void onClick(View view) { wordViewModel.insertWords(word); } }).show(); } }).attachToRecyclerView(recyclerView);//让上述写的东西连接上recycleView。 FloatingActionButton floatingActionButton = requireActivity().findViewById(R.id.floatingActionButton);//绑定悬浮按钮 floatingActionButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { NavController controller = Navigation.findNavController(view);//点击跳转界面 controller.navigate(R.id.action_wordFragment_to_addFragment); } }); } }
AddFragment
package com.example.roombasic; import android.content.Context; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import androidx.navigation.NavController; import androidx.navigation.Navigation; import android.text.Editable; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.Button; import android.widget.EditText; /** * A simple {@link Fragment} subclass. */ public class AddFragment extends Fragment { private Button buttonSubmit; private EditText editTextEnglish,editTextChinese; private WordViewModel wordViewModel; public AddFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_add, container, false); } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); wordViewModel=new ViewModelProvider(requireActivity(),ViewModelProvider.AndroidViewModelFactory.getInstance(requireActivity().getApplication())).get(WordViewModel.class); buttonSubmit=requireActivity().findViewById(R.id.buttonsubmit); editTextEnglish=requireActivity().findViewById(R.id.editTextTextEnglish); editTextChinese=requireActivity().findViewById(R.id.editTextTextChinese); buttonSubmit.setEnabled(false);//使得一开始按钮不可用 editTextEnglish.requestFocus();//获取焦点 InputMethodManager imm= (InputMethodManager) requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(editTextEnglish,0);//设置键盘在editTextEnglish时自动弹出 TextWatcher textWatcher=new TextWatcher() {//监视文本变化 @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { String english=editTextEnglish.getText().toString().trim(); String chinese=editTextChinese.getText().toString().trim(); buttonSubmit.setEnabled(!english.isEmpty()&&!chinese.isEmpty());//当文本框都不为空的时候,按键可用 } @Override public void afterTextChanged(Editable editable) { } }; editTextEnglish.addTextChangedListener(textWatcher);//将设置的监视文本变化添加到editTextEnglish editTextChinese.addTextChangedListener(textWatcher);//将设置的监视文本变化添加到editTextChinese buttonSubmit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) {//将要添加的单词进行处理 String english=editTextEnglish.getText().toString().trim(); String chinese=editTextChinese.getText().toString().trim(); Word word=new Word(english,chinese); wordViewModel.insertWords(word); NavController controller= Navigation.findNavController(view);//跳转 controller.navigateUp(); } }); } }
activity_main.xml
fragment_word.xml
fragment_add.xml
cell_normal.xml
cell_card_2.xml
mai_menu.xml
navigation.xml