I tried implementing choiceMode in RecyclerView. What I want is whenever any grid item is clicked,its background color changes & looks like it is selected.
I have used a library: https://github.com/bignerdranch/recyclerview-multiselect
but when I implemented it more than one items are getting selected.
I wanted to change background color of only items which are selected recently & leaving the other items with default background.
GitHub Repo: https://github.com/abhinituk/PopularMovies
CustomMovieAdapter.java
private final String LOG_TAG = getClass().getSimpleName();
private Cursor mCursor;
final private Context mContext;
final private CustomMovieAdapterOnClickHandler mCustomMovieAdapterOnClickHandler;
private MultiSelector mSingleSelector;
@Override
public int getItemCount() {
if (null == mCursor)
retu 0;
else
retu mCursor.getCount();
}
public CustomMovieAdapter(Context context, CustomMovieAdapterOnClickHandler ch, MultiSelector mSingleSelector) {
this.mContext = context;
this.mCustomMovieAdapterOnClickHandler = ch;
this.mSingleSelector = mSingleSelector;
}
public void swapCursor(Cursor data) {
mCursor = data;
notifyDataSetChanged();
}
public Cursor getCursor() {
retu mCursor;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
final View mView;
final CardView cardView;
final TextView titleTextView;
final ImageView poster;
ViewHolder(View view) {
super(view);
mView = view;
cardView = (CardView) view.findViewById(R.id.grid_item_cardView);
poster = (ImageView) view.findViewById(R.id.grid_item_imageview);
titleTextView = (TextView) view.findViewById(R.id.grid_item_title_textView);
view.setOnClickListener(this);
}
@Override
public void onClick(View v) {
Log.v(LOG_TAG, "On Click Called");
int adapterPosition = getAdapterPosition();
mCursor.moveToPosition(adapterPosition);
int movieId = mCursor.getInt(mCursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_MOVIE_ID));
mCustomMovieAdapterOnClickHandler.onClick(movieId, this);
mSingleSelector.setSelectable(true);
mView.setBackgroundColor(mContext.getResources().getColor(R.color.gridSelectedColor));
}
}
public interface CustomMovieAdapterOnClickHandler {
void onClick(int movieId, ViewHolder vh);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.grid_item_movies, parent, false);
retu new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Log.v(LOG_TAG,"ON BindViewHolder");
mCursor.moveToPosition(position);
String path = mCursor.getString(mCursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_MOVIE_POSTER_PATH));
String title=mCursor.getString(mCursor.getColumnIndex(MovieContract.MovieEntry.COLUMN_MOVIE_TITLE));
Picasso.with(mContext)
.load(new File(path))
.placeholder(R.drawable.placeholder)
.error(R.drawable.placeholder_error)
.into(holder.poster);
holder.titleTextView.setText(title);
}
}
MovieFragment.java
private final String LOG_TAG = getClass().getSimpleName();
private CustomMovieAdapter mCustomMovieAdapter;
private static final int LOADER_ID = 0;
private static RecyclerView mRecycledGridView;
private int mPosition = RecyclerView.NO_POSITION;
private RecyclerView.LayoutManager mLayoutManager;
private static final String[] MOVIE_COLUMN = {MovieContract.MovieEntry._ID
, MovieContract.MovieEntry.COLUMN_MOVIE_POSTER_PATH
, MovieContract.MovieEntry.COLUMN_MOVIE_ID,
MovieContract.MovieEntry.COLUMN_FLAG,
MovieContract.MovieEntry.COLUMN_FAVOURITE,
MovieContract.MovieEntry.COLUMN_MOVIE_TITLE};
public interface Callback {
/**
* DetailFragmentCallback for when an item has been selected.
*/
public void onItemSelected(Uri movieUri);
}
/*
Implementing the MultiSelector for RecyclerViews
*/
MultiSelector mSingleSelector= new SingleSelector();
//onCreate is used to create the fragment. In this put components which has to be retained when fragment is paused or stopped & then resumed.
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.moviefragment, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.refresh) {
movieDataUpdate();
retu true;
}
retu super.onOptionsItemSelected(item);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
public void onResume() {
Log.v(LOG_TAG, "On Resume Called");
super.onResume();
getLoaderManager().restartLoader(LOADER_ID, null, this);
}
private void movieDataUpdate() {
Log.v(LOG_TAG, "Update Movie data");
FetchMovieTask fetchMovieTask = new FetchMovieTask(getActivity());
String pref = PreferenceManager.getDefaultSharedPreferences(getActivity()).getString("sort_by", "popular");
if (!pref.equals("favourite"))
fetchMovieTask.execute(pref);
}
//In this fragment draws its UI for the first time
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.v(LOG_TAG, "On CreateView Called");
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
//Implementing the toolbar
final Toolbar toolbar = (Toolbar) rootView.findViewById(R.id.toolbar);
Log.v(LOG_TAG, String.valueOf((getActivity()) instanceof DetailActivity));
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
mRecycledGridView = (RecyclerView) rootView.findViewById(R.id.recycled_grid_view);
mRecycledGridView.setHasFixedSize(true);
mLayoutManager = new GridLayoutManager(getContext(), 2);
mRecycledGridView.setLayoutManager(mLayoutManager);
mCustomMovieAdapter = new CustomMovieAdapter(getActivity(), new CustomMovieAdapter.CustomMovieAdapterOnClickHandler() {
@Override
public void onClick(int movieId, CustomMovieAdapter.ViewHolder vh) {
( (Callback)getActivity()).onItemSelected(MovieContract.MovieEntry.buildMovieWithMovieIdUri(movieId));
mPosition= vh.getAdapterPosition();
}
},mSingleSelector);
mRecycledGridView.setAdapter(mCustomMovieAdapter);
retu rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
getLoaderManager().initLoader(LOADER_ID, null, this);
super.onActivityCreated(savedInstanceState);
}
@TargetApi(Build.VERSION_CODES.M)
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
//movie.flag=?
final String movieWithFlag = MovieContract.MovieEntry.COLUMN_FLAG + "=?";
String pref = PreferenceManager.getDefaultSharedPreferences(getActivity()).getString("sort_by", "popular");
if (!pref.equals("favourite"))
retu new CursorLoader(getActivity(), MovieContract.MovieEntry.CONTENT_URI,
MOVIE_COLUMN,
movieWithFlag,
new String[]{pref},
null);
else retu null;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mCustomMovieAdapter.swapCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mCustomMovieAdapter.swapCursor(null);
}
Please help me out in implementing this.


