Clicking CardView to load a fragment

3.6k views Asked by At

I'm having trouble with implementing clickable cards with my RecyclerView. I want to get the position of which card was clicked and then load the proper fragment.

I did take a look at this post and spent almost 30 minutes trying to make sense of the code and implementing it myself but I gave up when I realized how many mistakes were in the snippet.

Here is my adapter class.

public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder> {

public static CardView cv;

public static class PersonViewHolder extends RecyclerView.ViewHolder {
    TextView chapterName;
    TextView chapterNumber;
    // ImageView chapterPhoto;

    public PersonViewHolder(View itemView) {
        super(itemView);

        cv = (CardView) itemView.findViewById(R.id.cv);
        chapterName = (TextView) itemView.findViewById(R.id.chapter_name);
        chapterNumber = (TextView) itemView.findViewById(R.id.chapter_number);
        // chapterPhoto = (ImageView) itemView.findViewById(R.id.person_photo);

    }
}

List<Chapter> chapters;

RVAdapter(List<Chapter> chapters) {
    this.chapters = chapters;
}

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

@Override
public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
    PersonViewHolder pvh = new PersonViewHolder(v);
    return pvh;
}

@Override
public void onBindViewHolder(PersonViewHolder personViewHolder, int i) {
    personViewHolder.chapterName.setText(chapters.get(i).chapterName);
    personViewHolder.chapterNumber.setText(chapters.get(i).chapterNumber);
    // personViewHolder.chapterPhoto.setImageResource(persons.get(i).photoId);
}

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

I've looked through every implementation on StackOverflow and either I'm having tunnel vision or none of them are actually working. I know there are plenty of posts on the side, but I did spend more than a bit of time searching for the answer before asking this question, so all of those links are purple for me.

All help is appreciated, and I would be more than happy to post any other code that may be of help!

2

There are 2 answers

7
fmt.Println.MKO On BEST ANSWER

todo this you need to add the OnClickListener to your ViewHolder with an own Clicklistener, like this:

new Interface:

public interface PersonViewHolderClickListener {

    void onItemClick(long id);
}

and change your RVAdapter class like this:

protected Context mContext;

RVAdapter(Context context, List<Chapter> chapters) {
    mContext = context;
    this.chapters = chapters;
}

public static class PersonViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView chapterName;
    TextView chapterNumber;
    // ImageView chapterPhoto;

    private long PERSONId;

    public PersonViewHolderClickListener clickListener;

    public PersonViewHolder(View itemView,PersonViewHolderClickListener clickListener) {
        super(itemView);

        cv = (CardView) itemView.findViewById(R.id.cv);
        chapterName = (TextView) itemView.findViewById(R.id.chapter_name);
        chapterNumber = (TextView) itemView.findViewById(R.id.chapter_number);
        // chapterPhoto = (ImageView) itemView.findViewById(R.id.person_photo);

        this.clickListener = clickListener;

        view.setOnClickListener(this);  
    }

    @Override
    public void onClick(View v) {
        clickListener.onItemClick(PERSONId);
    }
}

@Override
public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
    PersonViewHolder pvh = new PersonViewHolder(v, new PersonViewHolderClickListener() {

        @Override
        public void onItemClick(long id) {
            Intent intent = new Intent(mContext, YOURActivity.class);
            intent.putExtra(EXTRA_PERSON_ID, id);
            mContext.startActivity(intent);
        }
    });
    return pvh;
}

@Override
public void onBindViewHolder(PersonViewHolder personViewHolder, int i) {
    personViewHolder.chapterName.setText(chapters.get(i).chapterName);
    personViewHolder.chapterNumber.setText(chapters.get(i).chapterNumber);
    // personViewHolder.chapterPhoto.setImageResource(persons.get(i).photoId);
    personViewHolder.PERSONId = i;
    }
0
wasimsandhu On

My full working code, with thanks to @fmt.Println.MKO.

RVAdapter.java:

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

import java.util.ArrayList;
import java.util.List;

public class RVAdapter extends RecyclerView.Adapter<RVAdapter.PersonViewHolder> implements View.OnClickListener {

    Context mContext;

    RVAdapter(Context context, List<Chapter> chapters) {
        mContext = context;
        this.chapters = chapters;
    }

    public static CardView cv;
    public static int position;

    public class PersonViewHolder extends RecyclerView.ViewHolder {
        TextView chapterName;
        TextView chapterNumber;
        // ImageView chapterPhoto;

        public PersonViewHolder(View itemView) {
            super(itemView);

            cv = (CardView) itemView.findViewById(R.id.cv);
            chapterName = (TextView) itemView.findViewById(R.id.chapter_name);
            chapterNumber = (TextView) itemView.findViewById(R.id.chapter_number);
            // chapterPhoto = (ImageView) itemView.findViewById(R.id.person_photo);

            itemView.setOnClickListener(RVAdapter.this);
            position = getPosition();
        }
    }

    @Override
    public void onClick(View v) {

            Intent intent = new Intent(mContext, ChapterActivity.class);
            mContext.startActivity(intent);
    }

    List<Chapter> chapters;

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    @Override
    public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
        PersonViewHolder pvh = new PersonViewHolder(v);
        return pvh;
    }

    @Override
    public void onBindViewHolder(PersonViewHolder personViewHolder, int i) {
        personViewHolder.chapterName.setText(chapters.get(i).chapterName);
        personViewHolder.chapterNumber.setText(chapters.get(i).chapterNumber);
        // personViewHolder.chapterPhoto.setImageResource(persons.get(i).photoId);

    }

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

}

The fragment with the RecyclerView:

import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

public class UnitOneFragment extends android.support.v4.app.Fragment {

    private List<Chapter> chapters;
    private RecyclerView rv;
    private RecyclerView.LayoutManager llm;

    public UnitOneFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.fragment_unit_one, container, false);

        rv = (RecyclerView) v.findViewById(R.id.rv);
        rv.setHasFixedSize(true);

        llm = new LinearLayoutManager(getActivity());
        rv.setLayoutManager(llm);

        initializeData();
        initializeAdapter();

        return v;
    }

    private void initializeData() {
        chapters = new ArrayList<>();
        chapters.add(new Chapter("Human Prehistory to the Early Civilizations", "Chapter One"));
        chapters.add(new Chapter("Classical China", "Chapter Two"));
        chapters.add(new Chapter("Classical India", "Chapter Three"));
        chapters.add(new Chapter("Classical Greece and Rome", "Chapter Four"));
        chapters.add(new Chapter("Classical Period: Declines and Diversities", "Chapter Five"));
    }

    private void initializeAdapter() {
        RVAdapter adapter = new RVAdapter(getActivity(), chapters);
        rv.setAdapter(adapter);
    }

}

class Chapter {
    String chapterName;
    String chapterNumber;
    // int photoId;

    Chapter(String chaptername, String chapternumber) {
        this.chapterName = chaptername;
        this.chapterNumber = chapternumber;
        // this.photoId = photoId;
    }
}