Anga
Anga

Reputation: 2641

Using multiple RecyclerView with one Adapter class

I have 3 RecyclerView to display most visited market, close by markets and favorite markets.

I have created 3 difference instance of MarketAdapter class for the three RecyclerView

Everything works fine, but my Activity implements one OnClickListener and I cant figure out which adapter was clicked. Is it possible to programmatically determine the Adapter that was clicked from the OnClickListener?

Here is my MarketAdapter Class

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

ArrayList<Markets> mMarket = new ArrayList<>();
Context mContext;
private final MarketsItemsClickListener mItemsClickListener;
private final MarketLongClickListener mLongClickListener;
private final MarketClickListener mClickListener;

public MarketAdapter(Context context, MarketsItemsClickListener itemsClickListener, MarketClickListener clickListener, MarketLongClickListener longClickListener){
    mContext = context;
    mItemsClickListener = itemsClickListener;
    mLongClickListener = longClickListener;
    mClickListener = clickListener;
}

public interface MarketLongClickListener{
    void onLongClick(int position);
}

public interface MarketClickListener{
    void onClick(int position);
}

public interface MarketsItemsClickListener{
    void imageViewOnClickListener(View view, int position);
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    Context context = viewGroup.getContext();
    int layoutForListItem = R.layout.list_market;
    LayoutInflater inflater = LayoutInflater.from(context);
    boolean shouldAttachToParentImmediately = false;

    View view = inflater.inflate(layoutForListItem, viewGroup, shouldAttachToParentImmediately);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
    viewHolder.bindView(i);
}

@Override
public int getItemCount() {
    if(mMarket != null) return mMarket.size();
    return 0;
}

public void setData(ArrayList<Markets> markets){
    mMarket = markets;
    notifyDataSetChanged();
}

public void addData(Markets market, int position){
    mMarket.add(0, market);
    notifyDataSetChanged();
}

public Markets getItem(int position){return mMarket.get(position);}

class ViewHolder extends RecyclerView.ViewHolder implements View.OnLongClickListener, View.OnClickListener{

    ImageView mImageView;
    TextView mNameTextView, mCityTextView;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);

        mImageView = itemView.findViewById(R.id.image_view);
        mNameTextView = itemView.findViewById(R.id.name_text_view);
        mCityTextView = itemView.findViewById(R.id.city_text_view);

        itemView.setOnLongClickListener(this);
        itemView.setOnClickListener(this);
    }

    void bindView(int position){
        Markets market = getItem(position);

        mCityTextView.setText(market.getCity());
        mNameTextView.setText(market.getName());
    }

    @Override
    public void onClick(View v) {
        //Get position of Adapter
        int position = getAdapterPosition();
        //Handle the click
        mClickListener.onClick(position);
    }

    @Override
    public boolean onLongClick(View v) {
        return false;
    }
}

}

and OnClickListener from Activity

@Override
public void onClick(int position) {}

Upvotes: 8

Views: 8141

Answers (3)

Giovanne
Giovanne

Reputation: 152

You can add an attribute inside MarketAdapter so that you can tell what instance is that.

Change your custom click listener to receive the adapter type:

public interface MarketClickListener {
    //You can change this to receive any data you want from the adapter
    void onClick(int position, int adapterType);
}

Add the constants, the identifier attribute and change the listener in your adatper:

public class MarketAdapter extends RecyclerView.Adapter<MarketAdapter.ViewHolder> {
    //The constants types
    public static int MOST_VISITED_MARKETS = 1;
    public static int CLOSE_BY_MARKETS = 2;
    public static int FAVORITE_MARKETS = 3;
    //New attribute
    private int adapterType;

    ...
    //Keep the listener
    private final MarketClickListener mClickListener;

        public MarketAdapter(Context context, MarketsItemsClickListener itemsClickListener, MarketClickListener clickListener, MarketLongClickListener longClickListener, int adapterType){
            ...
            //Set the type
            adapterType = adapterType;
        }

        ...

}

In your activity:

mostVisitedRecyclerView.setAdapter(new MarketAdapter(this,itemsClickListener,clickListener,longClickListener,MarketAdapter.MOST_VISITED_MARKETS ));
closeByRecyclerView.setAdapter(new MarketAdapter(this,itemsClickListener,clickListener,longClickListener,MarketAdapter.CLOSE_BY_MARKETS));
favoritesRecyclerView.setAdapter(new MarketAdapter(this,itemsClickListener,clickListener,longClickListener,MarketAdapter.FAVORITE_MARKETS));

In your view holder, change the onClick:

@Override
    public void onClick(View v) {
        //Get position of Adapter
        int position = getAdapterPosition();
        //Handle the click
        mClickListener.onClick(position,adapterType);
    }

I didn't test this but I think it will do the trick. Try it out.

Upvotes: 2

Pavneet_Singh
Pavneet_Singh

Reputation: 37404

You can pass a tag in the constructor and get that tag back via a click listener to identify the click as

private final MarketsItemsClickListener mItemsClickListener;
private final MarketLongClickListener mLongClickListener;
private final MarketClickListener mClickListener;
private final String mTag;

public MarketAdapter(Context context, MarketsItemsClickListener itemsClickListener, MarketClickListener clickListener, MarketLongClickListener longClickListener, String tag){
    mTag = tag
    mContext = context;
    mItemsClickListener = itemsClickListener;
    mLongClickListener = longClickListener;
    mClickListener = clickListener;
}

Modify the listener as

public interface MarketClickListener{
    void onClick(int position, String tag);
}

and the listener code in activity as

@Override
public void onClick(int position, String tag) {
    switch(tag){
        case "adapter1":
        break;
        case "adapter2":
        break;
        case "adapter3":
        break;
    }
}

and create adapter object as

 MarketAdapter adapter = new MarketAdapter("adapter1"....); 
 MarketAdapter adapter1 = new MarketAdapter("adapter2"....); 
 MarketAdapter adapter2 = new MarketAdapter("adapter3"....); 

and use

mClickListener.onClick(position, mTag);

Note: You can use enums as well

Upvotes: 9

Joshua Best
Joshua Best

Reputation: 246

If you want to do it this way, I would add a new variable to the adapters constructor, and then use a case/if statement to determine what you want to do in your onbindviewholder.

Upvotes: 1

Related Questions