AnoopDV
AnoopDV

Reputation: 305

Use same Recycler Adapter for inflating different activities

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.

Upvotes: 2

Views: 4042

Answers (5)

Gorcyn
Gorcyn

Reputation: 2817

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

Upvotes: 0

Kevin B
Kevin B

Reputation: 41

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

Upvotes: 2

Beloo
Beloo

Reputation: 9925

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

Upvotes: 0

Jofre Mateu
Jofre Mateu

Reputation: 2430

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.

Upvotes: 0

ligi
ligi

Reputation: 39539

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

Upvotes: 0

Related Questions