2

I have the following adapter

public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder>{

 List<String> list;
 int id;
Context context;

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view= LayoutInflater.from(parent.getContext()).inflate(id,parent,false);
   return new ViewHolder(view);

}

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
        holder.textView.setText(list.get(position));

       holder.textView.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               Handler handler=new Handler();
               handler.postDelayed(new Runnable() {
                   @Override
                   public void run() {
                       Intent intent = new Intent(context, BESyllabus.class);
                       context.startActivity(intent);
                   }
               },500);

           }
       });
}

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


public static class ViewHolder extends RecyclerView.ViewHolder{
    public TextView textView;
    public CardView cardView;
    public ViewHolder(View v){
        super(v);
        textView=(TextView)v.findViewById(R.id.text);
        cardView=(CardView)v.findViewById(R.id.card_view);
    }
}

public CardAdapter(List<String> list, int id,Context context){
    this.list=list;
    this.id=id;
    this.context=context;
}

}

I use the same layout file which has a recyclerView which uses the above adapter,id is the resource id for layout file which i use as rows for recycler view`

<?xml version="1.0" encoding="utf-8"?>

<TextView
    android:id="@+id/text"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="#000000"
    android:alpha="0.87"
    android:layout_marginLeft="8dp"
    android:layout_marginRight="8dp"
    android:layout_marginTop="8dp"
    android:textSize="35dp" />

What i want to do is inflate multiple activities using the same row structure using the same adapter. It works fine while displaying the rows but the same onClickListener is used in every activity relaunching the same activity every time i click. Is there a way to use the same adapter where i can assign listeners based on the activity.Or should i create new adapter for every activity? I am new to android development so any help will be appreciated.Thanks in advance.

AnoopDV
  • 305
  • 1
  • 3
  • 13
  • the handler usage in your onClickListener is not needed, the onClickListener code is already running on the UI thread (unless you strictly want a 0.5second delay...then nvm) – petey Feb 09 '15 at 16:17

5 Answers5

2

Use the interface :

public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder>{

    private IOnItemClickListener mListener;

    public CardAdapter(IOnItemClickListener mListener) {
        this.mListener = mListener;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view= LayoutInflater.from(parent.getContext()).inflate(id,parent,false);

        return new ViewHolder(v, new CardAdapter.ViewHolder.IMyViewHolderClicks() {
            public void onClick(View v, int position) {
                mListener.onItemClick(v, position);
            };
        });

    }

    public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView textView;
        public CardView cardView;
        public IMyViewHolderClicks mListener;

        public ViewHolder(View v, IMyViewHolderClicks listener) {
            super(itemView);
            mListener = listener;

            textView=(TextView)v.findViewById(R.id.text);
            cardView=(CardView)v.findViewById(R.id.card_view);
        }

        @Override
        public void onClick(View v) {
            mListener.onClick(v, getPosition());
        }

        public interface IMyViewHolderClicks {
            public void onClick(View v, int position);
        }
    }
}
public interface IOnItemClickListener {
    public void onItemClick(View v, int position);
}
Kevin B
  • 41
  • 6
0

You can pass the listener as a constructor argument to the Adapter

ligi
  • 39,001
  • 44
  • 144
  • 244
0

You should pass an OnClickListener to the CardAdapter (on its constructor maybe) and implement it on the activity working with this Adapter.

public class ActivityX extends Activity implements View.OnClickListener {
    CardAdapter adapter;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        adapter = new CardAdapter(this)
    }

    public void onClick(View v) {
        // Handle click here
        String string = (String) v.getTag();
    }
}

Your Adapter may then look like this:

public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> {
    View.OnClickListener onClickListener;

    public CardAdapter(View.OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        // Saving object from list at given position in View tag
        holder.setTag(list.get(position));
        holder.textView.setText(list.get(position));

        holder.textView.setOnClickListener(onClickListener);
    }
}
Gorcyn
  • 2,807
  • 1
  • 20
  • 22
0

In this answer there's an implementation of a onItemClickListener for a recycler view. You could move the code from your onClickListener to a diferent onItemClickListener for each diferent activity you need.

Community
  • 1
  • 1
Jofre Mateu
  • 2,390
  • 15
  • 26
  • It worked...thanks. But i was using a library for creating ripple effect and it stopped when i use this listener,I do not know if it is related or not, if you have any ides please do share – AnoopDV Feb 09 '15 at 19:03
0

First of all, what is a reason to use handler delay in setOnClickListener? This code will lead to an NullPointerException in cases when context was destroyed before.

On the subject of the question you could pass onClickListener via constructor as in previous answers, pass only Class variable of target activity, make broadcast event. It depends on your needs. But the most appropriate in most cases i think is not make onClickListener inside adapter, setting onItemClickListener of recycler view instead (as @tinuviel answer). In this case pressed state of recycle view item will be animated automatically

Beloo
  • 9,723
  • 7
  • 40
  • 71
  • i am using animation for click events,so for letting the animation complete i am using delay – AnoopDV Feb 09 '15 at 16:42
  • Also what would cause the NullPointer Exception, the handler or the setOnClickListener – AnoopDV Feb 09 '15 at 20:07
  • Nothing of that, null exception will be thrown if android released context before context.startActivity(intent) will be called (instance of the adapter will be deleted too) . In such case you can check that by making break point in line "Intent intent = new Intent(context, BESyllabus.class);" than press home button ( with do not keep activities dev device setting) and than return to an app. In a real app lifecycle this won't be so often, but if application has many users a chance would increase. – Beloo Feb 10 '15 at 16:34