【问题标题】:Filter RecyclerView's list with LiveData items with searchview [duplicate]使用 searchview 过滤带有 LiveData 项目的 RecyclerView 列表 [重复]
【发布时间】:2020-06-10 14:50:58
【问题描述】:

我决定优化我的代码,因此改用 liveData。我遵循了 youtube 上的教程 (youtube link),但我不太明白如何在用户输入单词时过滤我的 recyclerView,因为我的适配器中没有存储任何列表。我在 MainActivity 上使用了一个简单的 searchview 过滤器系统。


此外,我使用 DiffUtil 更新我的 recyclerView 并更新我的适配器,感谢:

noteViewModel = new ViewModelProvider.AndroidViewModelFactory(getApplication()).create(NoteViewModel.class);
noteViewModel.getAllNotes().observe(this, adapter::submitList);

我的代码与视频几乎相同,但这是其中的一部分:

视图模型:

public class NoteViewModel extends AndroidViewModel {
    private NoteRepository repository;
    private LiveData<List<Note>> allNotes;

    public NoteViewModel(@NonNull Application application) {
        super(application);
        repository = new NoteRepository(application);
        allNotes = repository.getAllNotes();
    }

    public void insert(Note note) {
        repository.insert(note);
    }

    public void update(Note note) {
        repository.update(note);
    }

    public void delete(List<Note> notes) {
        repository.delete(notes);
    }


    public LiveData<List<Note>> getAllNotes() {
        return allNotes;
    }
}

我的仓库:

public class NoteRepository {

    private NotesDAO notesDAO;
    private LiveData<List<Note>> allNotes;

    public NoteRepository(Application application) {
        NotesDB database = NotesDB.getInstance(application);
        notesDAO = database.notesDAO();
        allNotes = notesDAO.getAllNotes();
    }

    public void insert(Note note) {
        new InsertNoteAsyncTask(notesDAO).execute(note);
    }

    public void update(Note note) {
        new UpdateNoteAsyncTask(notesDAO).execute(note);
    }

    public void delete(List<Note> note) {
        new DeleteNoteAsyncTask(notesDAO).execute(note);
    }


    public LiveData<List<Note>> getAllNotes() {
        return allNotes;
    }

    private static class InsertNoteAsyncTask extends AsyncTask<Note, Void, Void> { // SOME STUFF }

    private static class UpdateNoteAsyncTask extends AsyncTask<Note, Void, Void> { // SOME STUFF }

    private static class DeleteNoteAsyncTask extends AsyncTask<List<Note>, Void, Void> { // SOME STUFF }

}

【问题讨论】:

  • 注意:new ViewModelProvider.AndroidViewModelFactory(getApplication()).create(NoteViewModel.class); 请停止这样做,这是错误的。应该是 new ViewModelProvider(this).get(NoteViewModel.class)
  • 我试过这个但我得到一个错误:java.lang.RuntimeException: Cannot create an instance of class fr.djan.fullrecyclerview.Model.NoteViewModel Caused by: java.lang.InstantiationException: java.lang.Class &lt;en. djan.fullrecyclerview.Model.NoteViewModel&gt; has no zero argument constructor
  • 这是由于您的 AndroidX 依赖项中的版本不匹配造成的。参考stackoverflow.com/questions/60451458/…
  • 我听从了您的建议,并且成功了,谢谢! (即使那不能解决我的问题)
  • 试试@Query("SELECT * FROM note_table WHERE LOWER(title) LIKE '%' || :search || '%'") LiveData&lt;List&lt;Note&gt;&gt; filter(String search);

标签: android-studio filter android-recyclerview viewmodel android-livedata


【解决方案1】:

最后,感谢@EpicPandaForce,我做到了:

我的视图模型:

public class NoteViewModel extends AndroidViewModel {

    private NoteRepository repository;
    private final LiveData<List<Note>> allNotes;
    private MutableLiveData<String> filterText = new MutableLiveData<>();

    public NoteViewModel(@NonNull Application application) {
        super(application);
        repository = new NoteRepository(application);
        allNotes = Transformations.switchMap(filterText, (input) ->
        {
            if(input == null || input.equals(""))
                return repository.getAllNotes();
            else
                return repository.filter(input);
        });
        }

        public void setFilter(String query) {
            filterText.setValue(query);
        }

        public LiveData<List<Note>> getAllNotes() {
            return allNotes;
        }
}

在我的存储库中:

public LiveData<List<Note>> filter(String input) {
        try {
            return new FilterNoteAsyncTask(notesDAO).execute(input).get();
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
        }
        return null;
    }

private static class FilterNoteAsyncTask extends AsyncTask<String, Void, LiveData<List<Note>>> {
        private NotesDAO notesDAO;

        private FilterNoteAsyncTask(NotesDAO notesDAO) {
            this.notesDAO = notesDAO;
        }

        @Override
        protected LiveData<List<Note>> doInBackground(String... strings) {
            return notesDAO.filter(strings[0]);
        }
    }

感谢我在数据库中执行请求:

@Query("SELECT * FROM note_table WHERE LOWER(title) LIKE '%' || :search || '%'")
LiveData<List<Note>> filter(String search);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-29
    • 1970-01-01
    • 2020-02-07
    • 1970-01-01
    • 2020-03-17
    • 1970-01-01
    相关资源
    最近更新 更多