Android 使用 View 模型和实时数据实现搜索

标签 android search observable android-livedata

我正在为 udacity 类(class)开发一个 android 项目 我目前正在尝试实现搜索功能,同时坚持 android 架构组件并使用 firestore 和 room 我对所有这些概念都很陌生,所以请指出任何看起来不对的地方。

所以我创建了一个数据库存储库来保持我的 firestore 和房间数据库同步并传送数据。然后我使用 viewmodel 和观察者模式(我认为)所以我的观察者获取数据并寻找变化将它提供给我的适配器(refreshMyList(List)),它填充一个 recyclerview 像这样:

 contactViewModel = ViewModelProviders.of(this).get(ContactsViewModel.class);
 contactViewModel.getAllContacts().observe(this, new 
 Observer<List<DatabaseContacts>>() {
        @Override
        public void onChanged(@Nullable List<DatabaseContacts> 
        databaseContacts) {
            ArrayList<DatabaseContacts> tempList = new ArrayList<>();
            tempList.addAll(databaseContacts);
            contactsAdapter.refreshMyList(tempList);
            if (tempList.size() < 1) {
                results.setVisibility(View.VISIBLE);
            } else {
                results.setVisibility(View.GONE);
            }
        }
    });

我现在想搜索数据,我的房间查询都设置好了,我的数据存储库中有方法可以根据搜索字符串获取联系人,但我似乎无法刷新我的列表 我已经读到有像 Transformations.switchMap 这样的方法吗?但我似乎无法理解它是如何工作的任何人都可以帮助我

目前我正在尝试从异步任务返回结果列表,它过去常常返回实时数据,但我将其更改为 getValue() 始终为 null ,不确定这是否正确,这是异步的:

private static class searchContactByName extends AsyncTask<String, Void, 
ArrayList<DatabaseContacts>> {

    private LiveDatabaseContactsDao mDao;

    searchContactByName(LiveDatabaseContactsDao dao){
        this.mDao = dao;
    }

    @Override
    protected ArrayList<DatabaseContacts> doInBackground(String... params) {
        ArrayList<DatabaseContacts> contactsArrayList = new ArrayList<>();
        mDao.findByName("%" + params[0] + "%");
        return contactsArrayList;
    }
}

我在自己的包装器中从我的联系人存储库中调用它:

public List<DatabaseContacts> getContactByName(String name) throws 
ExecutionException, InterruptedException {
    //return databaseContactsDao.findByName(name);
    return new searchContactByName(databaseContactsDao).execute(name).get();
}

这是从我的 View 模型中调用的,如下所示:

public List<DatabaseContacts> getContactByName(String name) throws 
ExecutionException, InterruptedException {
    return  contactRepository.getContactByName(name);
}

然后我从我的 fragment 中调用它:

private void searchDatabase(String searchString) throws ExecutionException, 
InterruptedException {
    List<DatabaseContacts> searchedContacts = 
    contactViewModel.getContactByName("%" + searchString + "%");
    ArrayList<DatabaseContacts> contactsArrayList = new ArrayList<>();
    if (searchedContacts !=  null){
        contactsArrayList.addAll(searchedContacts);
        contactsAdapter.refreshMyList(contactsArrayList);
    }
}

这是从我的 onCreateOptionsMenu 中的搜索查询文本更改方法调用的:

        @Override
        public boolean onQueryTextChange(String newText) {
            try {
                searchDatabase(newText);
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return false;
        }

但它什么也没做 我原来的 recyclerview 内容从未改变任何想法?

最佳答案

您可以使用 Transformation.switchMap 进行搜索操作。

  1. 在 View 模型中创建具有最新搜索字符串的 MutableLiveData。

  2. 内部 View 模型使用:

    LiveData<Data> data = 
    LiveDataTransformations.switchMap(searchStringLiveData, string ->  
    repo.loadData(string)))
  1. 将上述实时数据返回给 Activity ,以便它可以观察和更新 View 。

关于Android 使用 View 模型和实时数据实现搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51154786/

相关文章:

c# - 使用 Nash/Unity 将 ADF 导出到 Tango sdcard - ADF 写入权限被拒绝

java - 在 Play 商店上发布我的应用程序之前,如何在我的应用程序中提供应用程序的引用编码 "Rate my app"页面

android - Firebase google-services.json 文件

android listview nullpointer.exception 异常

string - 子序列查询的数据结构

php - 如何在 PHP 中改进搜索算法

Powershell 读取文件,搜索 $$I 并替换,写入文件?

Angular/RxJS : How to generate a sequence of delayed values?

typescript - 我怎样才能在angular2中获取所有带有可观察量的youtube视频

java - 在 Rx Observable 事务中使用 Realm 调用时,如何防止 Realm 线程问题?