我正在使用带有房间数据库的searchView来过滤片段内recyclerView的结果。
当我单击recyclerView的任何项目时,它将使用导航组件库导航到detailsFragment。
直到这里一切正常,问题是当我从detailsFragment按下返回按钮回到BooksFragment时,recyclerView消失了。
仅当我实现了searchView功能之后,它才能向前和向后导航而没有任何问题,才会出现此问题。
我的代码有什么问题以及如何解决。
我的适配器
public class BookAdapter extends RecyclerView.Adapter<BookAdapter.BookViewHolder> implements Filterable {
private final LayoutInflater mInflater;
private List<Book> mBookList;
private List<Book> mBookListFiltered;
private BookViewModel bookViewModel;
private Context context;
public BookAdapter(Context context, BookViewModel bookViewModel) {
this.context = context;
mInflater = LayoutInflater.from(context);
this.bookViewModel = bookViewModel;
}
@NonNull
@Override
public BookViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(R.layout.item_main, parent, false);
return new BookViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull BookViewHolder holder, int position) {
if (mBookList != null) {
int listNumber = position + 1;
Book current = mBookList.get(position);
holder.title.setText(current.getBookTitle());
holder.number.setText(String.valueOf(listNumber));
// on item clicked
holder.itemView.setOnClickListener(view -> Navigation.findNavController(view).navigate(R.id.action_BookFragment_to_detailsFragment));
}
}
@Override
public int getItemCount() {
if (mBookList != null)
return mBookList.size();
else return 0;
}
public void setBooks(List<Book> bookList) {
mBookList = bookList;
mBookListFiltered = bookList;
notifyDataSetChanged();
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults filterResults = new FilterResults();
if (charSequence == null || charSequence.length() == 0) {
filterResults.count = mBookListFiltered.size();
filterResults.values = mBookListFiltered;
} else {
String searchChr = charSequence.toString().toLowerCase();
List<Book> resultData = new ArrayList<>();
for (Book book : mBookListFiltered) {
if (book.getBookTitle().toLowerCase().contains(searchChr)) {
resultData.add(book);
}
}
filterResults.count = resultData.size();
filterResults.values = resultData;
}
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mBookList = (List<Book>) filterResults.values;
notifyDataSetChanged();
}
};
}
class BookViewHolder extends RecyclerView.ViewHolder {
private final AppCompatTextView title, number;
private AppCompatImageView imgSave;
private BookViewHolder(View itemView) {
super(itemView);
title = itemView.findViewById(R.id.tv_title);
number = itemView.findViewById(R.id.tv__title_number);
}
}
}
书本片段
public class BookFragment extends Fragment {
private FragmentBookBinding mBinding;
private BookViewModel mBookViewModel;
private BookAdapter adapter;
public BookFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_book, container, false);
mBookViewModel = new ViewModelProvider(this).get(BookViewModel.class);
adapter = new BookAdapter(getContext(), mBookViewModel);
mBinding.recycler.setAdapter(adapter);
mBinding.recycler.setLayoutManager(new LinearLayoutManager(getContext()));
mBookViewModel.getAllBooks().observe(this, books -> adapter.setBooks(books));
// to make all searchView box clickable
mBinding.searchView.setOnClickListener(v -> mBinding.searchView.setIconified(false));
mBinding.searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return true;
}
});
return mBinding.getRoot();
}
}
使用
mBookList.addAll((List<Book>) filterResults.values);
而不是
mBookList = (List<Book>) filterResults.values;
如果问题仍然存在,则必须阅读有关ArrayList克隆的内容,ArrayList clone()方法用于创建列表的浅表副本。在新列表中,仅复制对象引用。如果我们在第一个arraylist中更改对象状态,则更改后的对象状态也将反映在克隆的arraylist中。