【问题标题】:Update RecyclerView with search results from SQLite使用 SQLite 的搜索结果更新 RecyclerView
【发布时间】:2020-08-18 06:25:35
【问题描述】:

我在使用 SearchView 结果更新 RecyclerView 时遇到了问题。 进行实际搜索似乎工作正常,因为我已经在“performFiltering”中逐步完成了代码,并且“publishResults”具有正确的列表。但我似乎无法弄清楚如何更新 RecyclerView。我已经盯着这段代码 3 天了,这可能是一个我忽略的简单解决方案。

我的电影片段

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();
        }
    };
}

}

【问题讨论】:

    标签: android sqlite android-fragments android-recyclerview searchview


    【解决方案1】:

    如果 _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;
            }
    

    希望有帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多