使用SQLite的搜索结果更新RecyclerView
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用SQLite的搜索结果更新RecyclerView相关的知识,希望对你有一定的参考价值。
我在用Fragment中的SearchView结果更新RecyclerView时遇到问题。在我逐步浏览了“ performFiltering”处的代码并且“ publishResults”具有正确的列表后,进行实际搜索似乎正常。但是我似乎无法弄清楚如何更新RecyclerView。我已经盯着这段代码三天了,可能是我忽略的一个简单解决方案。
MyMoviesFragment
public class MyMoviesFragment extends Fragment {
private SearchView searchView = null;
private SearchView.OnQueryTextListener queryTextListener;
private static final boolean DEFAULT_SORT_ORDER_IS_ASC = false;
private static final int MY_MOVIES_LOADER_ID = 173201;
private ArrayList<Movie> _movies = new ArrayList();
private ArrayList<Movie> _moviesRaw = new ArrayList();
private Button _btnMoviesNotFound;
private DBHandler _repository;
private MyMoviesAdapter _myMoviesAdapter;
private ProgressBar _progressBar;
private RecyclerView _rvMovies;
private SharedPreferences _preferences;
private View _view;
public MyMoviesFragment() {
// Required empty public constructor
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// inflater.inflate(R.menu.main, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
if (searchItem != null) {
searchView = (SearchView) searchItem.getActionView();
}
if (searchView != null) {
searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
queryTextListener = new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextChange(String newText) {
Log.i("onQueryTextChange", newText);
_myMoviesAdapter.getFilter().filter(newText);
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
Log.i("onQueryTextSubmit", query);
return true;
}
};
searchView.setOnQueryTextListener(queryTextListener);
}
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
this._view = inflater.inflate(R.layout.fragment_my_movies, container, DEFAULT_SORT_ORDER_IS_ASC);
getActivity().setTitle(R.string.movies_fragment_title);
this._repository = DBHandler.getInstance(getActivity());
this._progressBar = (ProgressBar) this._view.findViewById(R.id.progressBar2);
this._progressBar.setVisibility(View.VISIBLE);
this._rvMovies = (RecyclerView) this._view.findViewById(R.id.rvMovies);
this._rvMovies.setLayoutManager(new LinearLayoutManager(getActivity()));
this._myMoviesAdapter = new MyMoviesAdapter(this._movies, this);
this._rvMovies.setAdapter(this._myMoviesAdapter);
this._btnMoviesNotFound = (Button) this._view.findViewById(R.id.btnMoviesNotFound);
if (savedInstanceState == null) {
loadMyMoviesList();
}
return this._view;
}
public void loadMyMoviesList() {
getLoaderManager().initLoader(MY_MOVIES_LOADER_ID, null, new LoaderManager.LoaderCallbacks<ArrayList<Movie>>() {
@NonNull
@Override
public Loader<ArrayList<Movie>> onCreateLoader(int id, Bundle args) {
return new MyMoviesLoader(MyMoviesFragment.this.getContext());
}
public void onLoadFinished(Loader<ArrayList<Movie>> loader, ArrayList<Movie> movies) {
if (movies != null) {
MyMoviesFragment.this._movies.clear();
Iterator it = movies.iterator();
while (it.hasNext()) {
MyMoviesFragment.this._movies.add((Movie) it.next());
}
MyMoviesFragment.this._moviesRaw = new ArrayList(MyMoviesFragment.this._movies);
MyMoviesFragment.this._myMoviesAdapter.notifyDataSetChanged();
MyMoviesFragment.this.displayListState();
}
}
public void onLoaderReset(Loader<ArrayList<Movie>> loader) {
}
}).forceLoad();
}
public void displayListState() {
this._progressBar.setVisibility(View.GONE);
if (this._movies.size() < 1) {
this._rvMovies.setVisibility(View.GONE);
this._btnMoviesNotFound.setVisibility(View.VISIBLE);
return;
}
this._btnMoviesNotFound.setVisibility(View.GONE);
this._rvMovies.setVisibility(View.VISIBLE);
}
}
MyMoviesAdapter
public class MyMoviesAdapter extends RecyclerView.Adapter<MyMoviesAdapter.ViewHolder> implements Filterable {
private Activity _activity;
private ArrayList<Movie> _movieListFull;
private ArrayList<Movie> _movieListFiltered;
private DBHandler _repository = DBHandler.getInstance(this._activity);
private Fragment _fragment;
public MyMoviesAdapter(ArrayList<Movie> movies, Fragment fragment) {
this._activity = fragment.getActivity();
this._fragment = fragment;
this._movieListFull = movies;
}
protected class ViewHolder extends RecyclerView.ViewHolder {
private CardView cardMovie;
private TextView lblMovieTitle;
public ViewHolder(View itemView) {
super(itemView);
this.cardMovie = (CardView) itemView.findViewById(R.id.cardMovie);
this.lblMovieTitle = (TextView) itemView.findViewById(R.id.lblMovieTitle);
}
}
// Create new views (invoked by the layout manager)
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_movie, parent, false));
}
// Replace the contents of a view (invoked by the layout manager)
// Binds the data to the Views in each row
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
// Get the data model based on position
Movie movie = _movieListFull.get(position);
viewHolder.lblMovieTitle.setText(String.valueOf(movie.getTitle()));
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return this._movieListFull.size();
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
_movieListFiltered = _movieListFull;
} else {
ArrayList<Movie> filteredList = new ArrayList<>();
for (Movie movie : _movieListFull) {
if (movie.getTitle().toLowerCase().contains(charString)) {
filteredList.add(movie);
}
}
_movieListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = _movieListFiltered;
filterResults.count = _movieListFiltered.size();
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
_movieListFiltered = (ArrayList<Movie>) filterResults.values;
notifyDataSetChanged();
}
};
}
}
答案
_ movieListFull已设置完整数据,则应使用_ movieListFiltered进行显示。因此getItemCount()和onBindViewHolder()应该引用_ movieListFiltered。
尝试以下更改:public MyMoviesAdapter(ArrayList<Movie> movies, Fragment fragment) {
this._activity = fragment.getActivity();
this._fragment = fragment;
this._movieListFiltered = movies;
_movieListFull = new ArrayList<>();
_movieListFull.addAll(movies);
}
// Replace the contents of a view (invoked by the layout manager)
// Binds the data to the Views in each row
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
// Get the data model based on position
Movie movie = _movieListFiltered.get(position);
viewHolder.lblMovieTitle.setText(String.valueOf(movie.getTitle()));
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return this._movieListFiltered.size();
}
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
//_movieListFiltered = _movieListFull;
_movieListFiltered.addAll(_movieListFull);
} else {
ArrayList<Movie> filteredList = new ArrayList<>();
for (Movie movie : _movieListFull) {
if (movie.getTitle().toLowerCase().contains(charString)) {
filteredList.add(movie);
}
}
_movieListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = _movieListFiltered;
filterResults.count = _movieListFiltered.size();
return filterResults;
}
希望有帮助!
以上是关于使用SQLite的搜索结果更新RecyclerView的主要内容,如果未能解决你的问题,请参考以下文章
Apollo GraphQL 突变结果不使用 PostgreSQL 更新,但适用于 SQLite