我正在使用提供的示例,并根据我的要求调整了代码。我正在学习 Rx,但并不完全熟悉它的工作原理。所以,在我的片段中,我有
private static String LIST_QUERY = "SELECT * FROM " + TodoItem.TABLE;
我的 onResume 看起来像:
@Override
public void onResume() {
super.onResume();
subscription = db.createQuery(TodoItem.TABLE, LIST_QUERY)
.mapToList(TodoItem.MAPPER)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(adapter);
}
适配器在列表视图中显示数据,它工作正常,但现在我在列表顶部添加了一个 TextView,并且希望在用户输入文本时过滤结果。我相信 RxAndroid 提供了一个 debounce 运算符来提高效率(而不是立即查询数据库),但我不确定如何结合这个订阅代码来监听 textView 的变化并根据该文本进行过滤。
我已经尝试将 LIST_QUERY 更改为"SELECT * FROM " + TodoItem.TABLE + " WHERE " + TodoItem.DESCRIPTION + " LIKE \"" + query + "\" LIMIT 5”;
然后在尝试:
etSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence searchQuery, int i, int i1, int i2) {
query = searchQuery.toString();
adapter.notifyDataSetChanged();
}
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { //ignore }
@Override
public void afterTextChanged(Editable editable) { //ignore }
});
这导致列表为空(我认为这没关系,因为初始查询是空字符串)但是当我输入一些文本时,查询根本没有更新/过滤列表。
我尝试了另一种方法,并在 mapToList 之后添加了 take(5) (因为我想要 LIMIT 5),这有效并且只显示了 5 个项目。然后我添加了 .filter(,输入 new 并让 Android Studio 生成 Func1 代码,它看起来像:
subscription = db.createQuery(ListItem.TABLE, LIST_QUERY)
.mapToList(Item.MAPPER)
.filter(new Func1<List<ListItem>, Boolean>() {
@Override
public Boolean call(List<ListItem> items) {
return null;
}
})
所以问题是它要求我过滤整个列表。我试过这个:
public Boolean call(List<ListItem> items) {
for(ListItem i: items)
if(!i.description().startsWith(query))
items.remove(i);
return true;
}
但是仍然显示整个列表,并且文本中的更改根本不会使列表发生变化。我相信我错过了一些东西,我必须订阅 EditText 但我不确定我将如何做到这一点并将其与现有的数据库订阅代码结合起来。寻找解决方案。