其他人可能会给你更好的建议,但我认为你应该通过你的 viewmodel 类扩展 ViewModel(或者如果需要上下文,AndroidViewModel)。在本课程中,您可以编写搜索算法。
您可以为此使用LiveData 和MutableLiveData。列出所有项目,并将与搜索匹配的项目添加到您的MutableLiveData。当您从搜索字符串中删除一个字符时,您将重新进行搜索并将所有找到的项目添加到 MutableLiveData。
最后,观察 LiveData 的变化,当它发生变化时更新你的适配器。
编辑示例:
ViewModel 类
public class MyModelSupplier extends AndroidViewModel{
//if you do not need application or context in your coustructor, class can extend ViewModel
private MutableLiveData<List<MyModel>> myModelList;
private List<myModel> nonVisibleMyModelList;
private Context context;
//Constructor
//if you do not need application or context in your coustructor, class can extend ViewModel
public MyModelSupplier(@NonNull Application application) {
super(application);
this.context = application.getApplicationContext();
updateFullList();
}
LiveData<List<MyModel>> getMyModelList() {
//this stuff is the one observed by the activity
if (MyModelList == null) {
MyModelList = new MutableLiveData<>();
updateFullList();
}
return MyModelList;
}
void searchMyModelListByName(final String itemName) {
if (itemName == null) {
MyModelList.setValue(nonVisibleMyModelList);
} else {
new ApplicationFilterQueryTask(searchString).execute();
}
}
//update
private void updateFullList() { new fullListQueryTask().execute(); }
class fullListQueryTask extends AsyncTask<Void, Void, List<MyModel> > {
@Override
protected void onPostExecute(List<MyModel> myRetrievedModelObjects) {
MyModelList.setValue(myRetrievedModelObjects);
nonVisibleMyModelList = myRetrievedModelObjects;
super.onPostExecute(myRetrievedModelObjects);
}
@Override
protected List<MyModel> doInBackground(Void... voids) {
List<MyModel> myHiddenButFoundModelObjects = new ArrayList<>();
//gather all your stuff in here (full list))
//return stuff in alphabetical order
java.util.Collections.sort(installedPackages, new MyModelNameComparator());
return installedPackages;
}
}
//so that they can be sorted
protected class MyModelNameComparator implements Comparator<MyModel> {
@Override
public int compare(MyModel o1, MyModel o2) {
//getName() should be implemented in your MyModel
return accentedToAsci(o1.getName()).compareToIgnoreCase(accentedToAsci(o2.getName()));
}
}
class ApplicationFilterQueryTask extends AsyncTask<Void, Void, List<MyModel> > {
private final String searchString;
ApplicationFilterQueryTask(String searchString) { this.searchString = searchString;}
@Override
protected void onPostExecute(List<MyModel> myFilteredModelList) {
MyModelList.setValue(myFilteredModelList);
super.onPostExecute(myFilteredModelList);
}
@Override
protected List<MyModel> doInBackground(Void... voids) {
List<MyModel> searchResult = new ArrayList<>();
//this is where the filtering occurs
for (MyModel model : nonVisibleMyModelList) {
if (accentedToAsci(model.getName().toLowerCase()).contains(accentedToAsci(searchString).toLowerCase())) {
searchResult.add(model);
}
}
return searchResult;
}
}
}
在主要活动 OnCreate 中,您执行所有常规操作,但像这样填充 recyclerView:
MyModelSupplier = ViewModelProviders.of(this).get(MyModelSupplier.class);
MyModelSupplier .getMyModelList().observe(this, packageSummaryList -> {
adapter = new MyRecyclerViewAdapter(// stuff here for the constructor, or you can update the old one as well);
recyclerView.setAdapter(adapter);
});
你的 Mainactivity 应该扩展
AppCompatActivity implements SearchView.OnQueryTextListener,
并且您应该实现这样的方法(注意,您需要菜单资源才能拥有按钮 - 如果您不知道如何添加菜单资源,请在谷歌上搜索)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_items, menu);
MenuItem menuItem = menu.findItem(R.id.menu_search);
SearchView searchView = (SearchView)menuItem.getActionView();
searchView.setQueryHint(getString(R.string.menu_search_tooltip));
searchView.setOnQueryTextListener(this);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
MyModelSupplier.searchMyModelListByName(newText);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.menu_settings) {
startActivity(new Intent(this, ActivitySettings.class));
return true;
}
return super.onOptionsItemSelected(item);
}
此外,此代码可能会警告您内存泄漏,但我还没有完全弄清楚如何在没有此警告的情况下在 asynctask 中运行与上下文相关的内容。
如果您遇到困难或成功,请告诉我。