我有一个ArrayList
,其中填充了
1)主要活动我的主要数据家
2)内部的recyclerview适配器
3)过滤列表
我有一个问题,当我搜索一些字符串时返回过滤后的数据。我实现更新该数据,但是当我更新该数据并刷新时,我获得了新的更新数据。但后来我从字符串中删除了一个字符并显示旧数据。
就像我搜索“ app ”一样,我的过滤数据会在RecyclerView数据中显示“ application ”和“ apple ”。
我将“ apple ”更新为“ applered ”
反对后,我的RecyclerVeiw向我展示了“ aaplication ”和“ aaplered ”
这没关系。
从字符串“ ap ”中删除一个字符后,我的RecyclerView
显示旧的“应用程序”和“ apple ”。
那意味着我的数据没有更新所有列表?如何将数据更新更新为所有三个列表?
答案 0 :(得分:1)
其他人可能会给你更好的建议,但我认为你应该通过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);
});
你的主动活动应该延伸
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中运行与上下文相关的内容。
如果您遇到困难或成功,请告诉我。