我有一个名为
Note
的实体,及其包含 SQL 特定逻辑的数据访问对象 (NoteDAO
)。还有一个扩展 NoteDatabase
的 RoomDatabase
类和同时使用 NoteRepository
和 NoteDAO
的 NoteDatabase
。 NoteViewModel
通过NoteRepository与数据库交互。
在片段中,我使用
NoteViewModel
检索 onCreateView
中的所有笔记。观察这些注释后,我使用 RecyclerView
设置 adapter.submitList
项目。
但是,当合并
SearchView
时,我遇到了一个问题。虽然我可以从 SearchView
检索查询文本,但我尝试过滤底层 allNotes
(NoteViewModel 中类型为 LiveData<List<Note>>
的成员变量)并没有按预期通知观察者。
在了解了
MutableLiveData
和LiveData
之间的区别后,我考虑将allNotes
中的NoteViewModel
成员更改为MutableLiveData
。理论上,这应该允许我在 setValue
函数中使用 postValue
或 filterNotes(String searchTerm)
方法,从而通知观察者。但这不起作用 – 我什至无法使用 MutableLiveData
检索未过滤的笔记列表。
第一个片段
@Override
public View onCreateView(
.......
) {
........
RecyclerView recyclerView = binding.recyclerView;
final NoteListAdapter adapter = new NoteListAdapter(new NoteListAdapter.WordDiff());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mNoteViewModel = new ViewModelProvider(requireActivity()).get(NoteViewModel.class);
mNoteViewModel.getAllNotes().observe(getViewLifecycleOwner(), new Observer<List<Note>>() {
@Override
public void onChanged(List<Note> notes) {
Log.d("MainPage", "onChanged: " + notes);
adapter.submitList(notes);
}
});
........
}
NoteViewModel
public class NoteViewModel extends AndroidViewModel {
private final NoteRepository mRepository;
private final LiveData<List<Note>> mAllNotes;
public NoteViewModel(@NonNull Application application) {
super(application);
mRepository = new NoteRepository(application);
mAllNotes = mRepository.getAllNotes();
}
LiveData<List<Note>> getAllNotes() {
return mAllNotes;
}
public void insert (Note note) { mRepository.insert(note); }
}
笔记存储库
public class NoteRepository {
private final NoteDAO mNoteDAO;
@NotNull
private final LiveData<List<Note>> mAllNotes;
NoteRepository(Application application) {
NoteRoomDatabase db = NoteRoomDatabase.getDatabase(application);
mNoteDAO = db.noteDAO();
mAllNotes = mNoteDAO.getAllNotes();
}
public LiveData<List<Note>> getAllNotes() {
return mAllNotes;
}
public void insert(Note note) {
NoteRoomDatabase.databaseWriteExecutor.execute(() -> {
mNoteDAO.insert(note);
});
}
}
NoteDAO
@Dao
public interface NoteDAO {
@Insert
void insert(Note note);
@Query("SELECT * FROM notes ORDER BY id DESC")
LiveData<List<Note>> getAllNotes();
@Query("SELECT * FROM notes where title = :title ORDER BY id DESC")
LiveData<List<Note>> getNotesByTitle(String title);
@Query("SELECT * FROM notes where id = :id ORDER BY id DESC")
LiveData<Note> getNoteById(long id);
@Query("SELECT * FROM notes where color = :color ORDER BY id DESC")
LiveData<List<Note>> getNotesByColor(String color);
}
我有两种方法
class NoteViewModel():AndroidViewModel{
private val noteItemsFlow = combine(mAllNotes, searchQueryFlow){ items, query ->
items.filter{
it.noteName.contains(query) // Here you can write a logic to filter according to search query
}
}
}
// In Fragment
noteItemsFlow.collectLatest{
adapter.submitList(it)
}
class NoteListAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>(), Filterable {
val notes = ArrayList<Note>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return NoteVieHolder()
}
override fun getItemCount(): Int {
return notes.size
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
// Replace your onBindViewHolder code here
}
inner class NoteVieHolder: RecyclerView.ViewHolder(){
// Replace your view holder code here
}
fun submitList(latestNotes:List<Note>){
notes.clear()
notes.addAll(latestNotes)
notifyDataSetChanged()
}
override fun getFilter(): Filter {
return object : Filter() {
override fun performFiltering(constraint: CharSequence?): FilterResults {
val results = FilterResults()
if (!constraint.isNullOrEmpty()){
val filterNotes = notes.filter {
it.title.contains(constraint)
}
results.count = filterNotes.size
results.values = filterNotes
}else{
results.count = notes.size
results.values = notes
}
return results
}
override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
if (results?.values != null) {
submitList(results.values as List<Note>)
}
}
}
}
}
希望这有帮助