【问题标题】:How to maintain RecyclerView filter list and main list after filtered list changes?过滤列表更改后如何维护 RecyclerView 过滤列表和主列表?
【发布时间】:2018-09-06 21:39:48
【问题描述】:

我有一个ArrayList 填充在其中

1) Mainactivity 我的主要数据列表

2) 内部 recyclerview 适配器

3) 过滤列表

我有一个问题,当我搜索一些字符串时,它会返回过滤后的数据。我实施以更新该数据,但是当我更新该数据并刷新时,我得到了新的更新数据。但随后我从字符串中删除一个字符并显示旧数据。

就像我搜索“app”一样,我过滤的数据在 RecyclerView 数据中显示“application”和“apple”。

我将“apple”更新为“applered
在支持我的 RecyclerVeiw 后显示“aaplication”和“aaplered” 没关系。
在我从字符串“ap”中删除一个字符之后,我的RecyclerView 向我展示了旧的“application”和“apple”。 p>

这意味着我的数据没有更新所有列表?我怎样才能将我的数据更新更新到所有三个列表?

【问题讨论】:

  • 你可能搞砸了参考。将有两个不同的列表,第一个是完整的,第二个是过滤的。如果您需要任何帮助,请添加您的代码。
  • 发布您的适配器代码

标签: android filter android-recyclerview


【解决方案1】:

其他人可能会给你更好的建议,但我认为你应该通过你的 viewmodel 类扩展 ViewModel(或者如果需要上下文,AndroidViewModel)。在本课程中,您可以编写搜索算法。

您可以为此使用LiveDataMutableLiveData。列出所有项目,并将与搜索匹配的项目添加到您的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 中运行与上下文相关的内容。

如果您遇到困难或成功,请告诉我。

【讨论】:

    猜你喜欢
    • 2020-12-02
    • 2022-08-14
    • 2013-09-29
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2015-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多