Shuchi Tyagi
Shuchi Tyagi

Reputation: 21

Handling clicks for recyclerview's internal item

I have a recyclerview to show facebook like newsfeed with a comment button. I cant figure out how to show a dialog when user clicks on comment button. All the solutions I found here were to handle the entire item's click but not its internal view. I tried this soultion also. How to handle multiple layout clicks in recyclerView in Android

Here is my adapter class.

public class NewsfeedAdapter extends RecyclerView.Adapter<NewsfeedAdapter.NewsfeedViewHolder> {

private final LayoutInflater inflater;
private Context context;

ArrayList<NewsfeedItem> data=  new ArrayList<NewsfeedItem>();

public NewsfeedAdapter(Context context,ArrayList<NewsfeedItem> data){
    inflater= LayoutInflater.from(context);
    this.data=data;
    this.context = context;
}
@Override
public NewsfeedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.custom_newsfeed_row, parent, false);
    NewsfeedViewHolder holder = new NewsfeedViewHolder(view);
    return holder;
}

@Override
public void onBindViewHolder(NewsfeedViewHolder newsfeedViewHolder, int i) {
    NewsfeedItem current = data.get(i);
    newsfeedViewHolder.username.setText(current.username);
    newsfeedViewHolder.icon.setImageResource(current.iconid);
    newsfeedViewHolder.timestamp.setText((CharSequence) current.timestamp);
    newsfeedViewHolder.news.setText(current.news);
}


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


class NewsfeedViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    TextView news, username, timestamp, comment_btn, like_btn;
    ImageView icon;
    private NewsfeedClickInterface clickListener;

    public NewsfeedViewHolder(View itemView) {
        super(itemView);
        news = (TextView) itemView.findViewById(R.id.news);
        timestamp = (TextView) itemView.findViewById(R.id.timestamp);
        username = (TextView) itemView.findViewById(R.id.username);
        icon = (ImageView) itemView.findViewById(R.id.profile_img);
        comment_btn = (TextView) itemView.findViewById(R.id.comment_btn);
        comment_btn.setTag("comment");
        comment_btn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (clickListener != null) {
            clickListener.onItemClicked(getPosition(), v.getTag().toString());
        }
    }
}
public interface NewsfeedClickInterface {
    public void onItemClicked(int position, String tag);
}

}

Upvotes: 1

Views: 1618

Answers (3)

yrazlik
yrazlik

Reputation: 10777

First define an interface in your viewholder. And when button is clicked, call this interface.

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

    public interface ViewHolderClickListener {
        public void onItemClick(View caller, int position);
    }

    public ViewHolderClickListener mListener;

    public ViewHolder(View itemView, ViewHolderClickListener listener) {
        super(itemView);
        mListener = listener;
        //other initializations...
    }

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

Then create another interface in a separate file, let's say you create this interface in a class called Commons:

public class Commons {

    public interface OnRecyclerItemClickedListener{
        public void onRecyclerItemClicked(String parameter);
    }

}

Then let your fragment/activity implement that interface. And pass this interface to your adapter's constructor as a parameter.

public class MyFragment extends Fragment implements Commons.OnRecyclerItemClickedListener{

    @Override
    public void onRecyclerItemClicked(String productId) {
        //do whatever you want on click
    }
}

Pass this interface to your adapter's constructor:

//here "this" parameter is your listener since your fragment implements
//the interface you defined
MyRecyclerViewAdapter adapter = new MyRecyclerViewAdapter(items, R.layout.yourlayout, getContext(), this);

and in your adapter, create an instance of the interface you defined in Commons class and set it in your constructor. Then create your viewholder in onCreateViewHolder method. Finally, call the interface you defined in your Commons class in your Viewholder's click interface:

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

    private OnRecyclerItemClickedListener onRecyclerItemClickedListener;

    public MyRecyclerViewAdapter(List<Item> items, int rowLayout, Context context, OnRecyclerItemClickedListener onRecyclerItemClickedListener){
        this.items = items;
        this.rowLayout = rowLayout;
        this.mContext = context;
        this.onRecyclerItemClickedListener = onRecyclerItemClickedListener;
    }



    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(rowLayout, parent, false);
        ViewHolder holder = new ViewHolder(v, new ViewHolder.ViewHolderClickListener() {

        @Override
        public void onItemClick(View caller, int position) {
            onRecyclerItemClickedListener.onRecyclerItemClicked(put_parameters_if_you_want);
        }});
        return holder;
    }

}

It is a little complicated, but here is the explanation of what you do: When button is clicked, your button click listener calls another listener(which was defined in your viewholder), and that listener calls another listener which was implemented in your fragment.

That is all you need to do.

Upvotes: 1

Arun Mehra
Arun Mehra

Reputation: 559

you can check the Id's of the views and fire different click listeners according to which view was clicked. like

comment_btn.setOnClickListener(this);
anotherButton.setOnClickListener(this);

switch (v.getId())

case R.id.comment_btn:
        code goes here

case R.id.another_button:

hope this helps.

Upvotes: 0

Tushar Sheth
Tushar Sheth

Reputation: 421

Inside

 @Override
public void onClick(View v) {
    if(view.getId() == comment_btn.getId()){
        Log.d("LOGTAG","Bingo !!! Your view Clicked.");
    }
    if (clickListener != null) {
        clickListener.onItemClicked(getPosition(), v.getTag().toString());
    }
}

Upvotes: 0

Related Questions