How do you use an OnClickListener in a recycler view?

brandin picture brandin · Apr 8, 2015 · Viewed 14.8k times · Source

What i'm basically trying to do is make the objects that show up in the recycler view clickable to a certain TextView id because i'm making a program that shows an album cover and its title next to it in a list. I need to be able to click on each one of the boxes that the recycler view makes and have a TextView pop up with the other information (author, published date, hit songs, etc) when its clicked on and then a back button (if possible) to go back to the album list. I've been looking at this for hours and cant figure out how to make an OnclickListener work for it. If you know how or have any suggestions id be glad to hear them. Thank you!

package com.albumlist.albumlist;

import android.content.Context;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private AlbumData[] itemsData;

    public MyAdapter(AlbumData[] itemsData){
        this.itemsData = itemsData;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        private TextView txtViewTitle;
        private ImageView imgViewIcon;

        public ViewHolder(View itemLayoutView) {
            super(itemLayoutView);
            itemLayoutView.setOnClickListener(this);
            txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.album_title);
            imgViewIcon = (ImageView) itemLayoutView.findViewById(R.id.album_icon);
        }

        @Override
        public void onClick(View v) {

        }
    }

    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {

        View itemLayoutView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.data_layout, null);

        ViewHolder viewHolder = new ViewHolder(itemLayoutView);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int position) {

        viewHolder.txtViewTitle.setText(itemsData[position].getTitle());
        viewHolder.imgViewIcon.setImageResource(itemsData[position].getImageUrl());
    }

    @Override
    public int getItemCount() {
        return itemsData.length;
    }

}

Answer

AlleyOOP picture AlleyOOP · Jul 29, 2015

The concept is well summed up by Xaver Kapeller in the comments. If you are looking for a simple way to manage your RecyclerView interaction similar to the traditional interactions of a ListView, check out BigNerdRanch's recyclerview-multiselect library on GitHub. They have a sample app that you can explore, which implements series of OnClickListeners and OnLongClickListeners with added capabilities of multi-selection.

Here's a snippet of how BigNerdRanch implements listeners in a Fragment across an Adapter and a ViewHolder, which in this case is actually an extension of the library's own SwappingHolder.

public CrimeHolder(View itemView) {
        super(itemView, mMultiSelector);

        mTitleTextView = (TextView) itemView.findViewById(R.id.crime_list_item_titleTextView);
        mDateTextView = (TextView) itemView.findViewById(R.id.crime_list_item_dateTextView);
        mSolvedCheckBox = (CheckBox) itemView.findViewById(R.id.crime_list_item_solvedCheckBox);
        itemView.setOnClickListener(this);
        itemView.setLongClickable(true);
        itemView.setOnLongClickListener(this);
    }

    public void bindCrime(Crime crime) {
        mCrime = crime;
        mTitleTextView.setText(crime.getTitle());
        mDateTextView.setText(crime.getDate().toString());
        mSolvedCheckBox.setChecked(crime.isSolved());
    }

    @Override
    public void onClick(View v) {

        if (mCrime == null) {
            return;
        }
        if (!mMultiSelector.tapSelection(this)) {
            selectCrime(mCrime);
        }

    }


    @Override
    public boolean onLongClick(View v) {

        ((AppCompatActivity) getActivity()).startSupportActionMode(mDeleteMode);
        mMultiSelector.setSelected(this, true);
        return true;
    }


}


private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> {
    @Override
    public CrimeHolder onCreateViewHolder(ViewGroup parent, int pos) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_item_crime, parent, false);
        return new CrimeHolder(view);
    }

    @Override
    public void onBindViewHolder(CrimeHolder holder, int pos) {
        Crime crime = mCrimes.get(pos);
        holder.bindCrime(crime);
        Log.d(TAG, "binding crime" + crime + "at position" + pos);
    }

    @Override
    public int getItemCount() {
        return mCrimes.size();
    }
}