0

OnClick doesn't triggers when I click on RecyclerView's list item.

I have created a fragment that contains a RecyclerView. In the Adapter class I register an OnItemClickListener for every ViewHolder.

MyDictionaryFragment.java

public class MyDictionaryFragment extends Fragment {
    private static final String TAG = "MyDictionaryFragment";
    private RecyclerView mWordsList;
    private DictionaryAdapter mAdapter;
    private static List<CardEntry> cards;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_dictionary, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        setupViewModel();
        //Recycler View
        mWordsList = view.findViewById(R.id.rv_my_dictionary);
        mWordsList.setLayoutManager(new LinearLayoutManager(getContext()));
        mWordsList.setHasFixedSize(true);

        //
        super.onViewCreated(view, savedInstanceState);
    }

    private void setupViewModel() {
        LearnWordsViewModel viewModel = ViewModelProviders.of(this).get(LearnWordsViewModel.class);
        viewModel.getCards().observe(this, (cardEntries) -> {
            if (cardEntries.isEmpty()) {
                Log.d(TAG, "There is no cards retrieved from the DataBase");
                return;
            }
            cards = cardEntries;
            mAdapter = new DictionaryAdapter(cards);
            mWordsList.setAdapter(mAdapter);
        });
    }
}

DictionaryAdapter.java

public class DictionaryAdapter extends RecyclerView.Adapter<DictionaryAdapter.CardViewHolder> {
    private static final String TAG = "DictionaryAdapter";

    private static List<CardEntry> mCards;

    public DictionaryAdapter(List<CardEntry> cards) {
        mCards = cards;
    }


    @NonNull
    @Override
    public CardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        int dictItemLayoutId = R.layout.word_listitem;
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(dictItemLayoutId, parent, false);

        return new CardViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull CardViewHolder holder, int position) {
        if(position >= mCards.size()) {
            return;
        }
        holder.word.setText(mCards.get(position).getWord());
    }

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

    class CardViewHolder extends RecyclerView.ViewHolder {
        private static final String TAG = "CardViewHolder";
        TextView word;
        CardView cardView;

        private CardViewHolder(@NonNull View itemView) {
            super(itemView);
            cardView = itemView.findViewById(R.id.dict_cardview);
            word = itemView.findViewById(R.id.word_listitem);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(itemView.getContext(), "Test", Toast.LENGTH_SHORT).show();
                }
            });
        }
    }
}

I expect that when I click on a list item from my RecyclerView, the event will trigger, but nothing happens. Why?

alfalfa
  • 87
  • 8

1 Answers1

0

You have to implement button onClick() method in onBindViewHolder() like this

 public void onBindViewHolder(@NonNull CardViewHolder holder, int position) {
    if(position >= mCards.size()) {
        return;
    }
    holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(itemView.getContext(), "Test", Toast.LENGTH_SHORT).show();
            }
        });
    holder.word.setText(mCards.get(position).getWord());
 }

Also from what I saw in you post you want to add clickListener to view itself? So you have to declare it you CardViewHolder constructor, I will give you and example for a button:

class CardViewHolder{
Button btn;
private CardViewHolder(View itemView){
...
btn = itemView.findViewById(R.id.btn);

}

And then in onBindViewHolder you can refer to btn as viewholder.btn

Gabriel Costin
  • 112
  • 3
  • 13
  • Are you sure that you are referring to the right widget or view? and you want to add `clickListener` to the whole layout with `id` `word_listitem` ? Also try to declare a field `Context context` and initialize it in `constructor` and instead of making a variable `context` everywhere refer to that field. Maybe that helps too. – Gabriel Costin Jan 16 '19 at 21:34
  • I have updated and recheck my code to reflect your recommendations, but the event still doesn't trigger. I have been looking for a solution to this problem for two days, but nothing works. I'm desperate... – Jenifer Alderson Jan 16 '19 at 21:52
  • I can post you a full implementation of this a recyclerView but it is pretty much what I told you. You still didn't answered to my questions though – Gabriel Costin Jan 16 '19 at 21:56
  • Can I refer to the wrong widget or view if my data shows correctly in view holders? – Jenifer Alderson Jan 16 '19 at 21:59
  • Well I don't know, if you would use in `onBindViewHolder` a widget that is not correctly initialized in `viewHolder` constructor app will trigger exception – Gabriel Costin Jan 16 '19 at 22:01
  • I have changed my code and now it refers to CardView: `holder.cardView.setOnClickListener`, but that also didn't help – Jenifer Alderson Jan 16 '19 at 22:04
  • That is strange, could you place a button onto card view and add implement `onClickListener` to him instead and see what happens – Gabriel Costin Jan 16 '19 at 22:07
  • That works! And If I attach the listener to the `TextView` that works too. Thank you! But how can I attach the listener to the whole `ViewHolder`? – Jenifer Alderson Jan 16 '19 at 22:25
  • I am not that experienced so I don't know if you can attach listener to the whole `itemView` . When I did some research about `recyclerView` and `cardView` I saw information about `cardView` implementing `onClickListener` so tehnically speaking it should work, google about how to add `onClickListener` to `cardView`. There is no way you can add a method to a widget or a view in `onBindViewHolder` and get no exception if you didn't type the id of view or widget correctly – Gabriel Costin Jan 16 '19 at 22:37
  • Check this link I think this is related to you problem and you might find the whole answer there https://stackoverflow.com/questions/27081787/onclicklistener-for-cardview – Gabriel Costin Jan 16 '19 at 22:49