2

I want to implement an onClickListener for a RecyclerViewItem in my App. My problem is, that the onclick listener isn't being called. Not even in the adapter. I'm trying to get this to work for 5 hours now and I'm really frustrated and don't know how to fix this/proceed. I hope you can help me.

ItemListAdapter.class

public class ItemListAdapter extends RecyclerView.Adapter<ItemListAdapter.ItemViewHolder> implements Filterable {

private ArrayList<Item> mItemList;
private ArrayList<Item> mItemListFiltered;

private ItemsListAdapterListener mItemsListAdapterListener;


public ItemListAdapter(ArrayList<Item> itemArrayList, ItemsListAdapterListener itemsListAdapterListener) {

    mItemList = itemArrayList;
    mItemListFiltered = itemArrayList;
    this.mItemsListAdapterListener = itemsListAdapterListener;
}


public interface ItemsListAdapterListener {
    void onItemClick(int position);
}

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

    public ImageView mImageView;
    public TextView mTextView;

    ItemsListAdapterListener mItemsListAdapterListener;

    public ItemViewHolder(@NonNull View itemView, ItemsListAdapterListener itemsListAdapterListener) {
        super(itemView);

        mItemsListAdapterListener = itemsListAdapterListener;

        mImageView = itemView.findViewById(R.id.imageViewItem);
        mTextView = itemView.findViewById(R.id.textViewItem);

        itemView.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        mItemsListAdapterListener.onItemClick(getAdapterPosition());
        Log.i("test", "Adapter click");
    }
}


@NonNull
@Override
public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_view_layout, parent, false);
    ItemViewHolder itemViewHolder = new ItemViewHolder(view, mItemsListAdapterListener);
    return  itemViewHolder;

}

@Override
public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {

    Item item = mItemListFiltered.get(position);

    holder.mImageView.setImageResource(item.getImgURL());
    holder.mTextView.setText(item.getItemName());

}

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

@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence charSequence) {
            String charString = charSequence.toString();
            if (charString.isEmpty()) {
                mItemListFiltered = mItemList;
            } else {
                ArrayList<Item> filteredList = new ArrayList<>();
                for (Item row: mItemList) {

                    // name match condition. this might differ depending on your requirement
                    // here we are looking for name or phone number match
                    if (row.getItemName().toLowerCase().contains(charString.toLowerCase()) || row.getItemCategory().toLowerCase().contains(charString.toLowerCase())) {

                        filteredList.add(row);

                    }
                }

                mItemListFiltered = (ArrayList<Item>) filteredList;
            }

            FilterResults filterResults = new FilterResults();
            filterResults.values = mItemListFiltered;
            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
            mItemListFiltered = (ArrayList<Item>) filterResults.values;
            notifyDataSetChanged();
        }
    };
}
}

ItemsFragment.class

public class ItemsFragment extends Fragment implements TextWatcher, ItemListAdapter.ItemsListAdapterListener{

private ItemsViewModel itemsViewModel;

private RecyclerView mRecyclerView;
private ItemListAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;

public View onCreateView(@NonNull final LayoutInflater inflater,
                         ViewGroup container, Bundle savedInstanceState) {
    itemsViewModel =
            ViewModelProviders.of(this).get(ItemsViewModel.class);
    View root = inflater.inflate(R.layout.fragment_items, container, false);


    final EditText editTextItemSearch;
    editTextItemSearch = (EditText) root.findViewById(R.id.editTextItemSearch);
    editTextItemSearch.addTextChangedListener(this);


    final ArrayList<Item> itemArrayList = new ArrayList<>();

    itemArrayList.add(new Item("TestItem1", R.drawable.unbenannt, getString(R.string.item_parts)));
    itemArrayList.add(new Item("TestItem2", R.drawable.ic_home_black_24dp, getString(R.string.item_tools)));
    itemArrayList.add(new Item("TestItem3", R.drawable.ic_dashboard_black_24dp, getString(R.string.item_consumable)));
    itemArrayList.add(new Item("test123", R.drawable.ic_notifications_black_24dp, getString(R.string.item_interactive)));
    itemArrayList.add(new Item("test12567687863", R.drawable.ic_notifications_black_24dp,getString(R.string.item_blocks)));

    Log.i("test", "items added");

    mRecyclerView = root.findViewById(R.id.recylcerViewItems);
    mRecyclerView.setHasFixedSize(true);
    mLayoutManager = new LinearLayoutManager(getContext());
    mAdapter = new ItemListAdapter(itemArrayList, this);

    mRecyclerView.setLayoutManager(mLayoutManager);
    mRecyclerView.setAdapter(mAdapter);

    return root;
}



@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {

    mAdapter.getFilter().filter(s);
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override
public void afterTextChanged(Editable s) {

}

@Override
public void onItemClick(int position) {
    Log.i("test", "item clicked");
}

}

adapter_view_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp">

<androidx.cardview.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:layout_margin="8dp"
    android:backgroundTint="@color/colorBackroundBright"
    android:clickable="true"
    android:foreground="?attr/selectableItemBackground"
    app:cardCornerRadius="15dp"
    tools:layout_editor_absoluteX="144dp"
    tools:layout_editor_absoluteY="42dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/imageViewItem"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_margin="16dp"
            android:layout_marginStart="16dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/textViewItem"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="32dp"
            android:fontFamily="@font/nunito_regular"
            android:text="ItemName"
            android:textColor="#959595"
            app:layout_constraintBottom_toBottomOf="@+id/imageViewItem"
            app:layout_constraintStart_toEndOf="@+id/imageViewItem"
            app:layout_constraintTop_toTopOf="@+id/imageViewItem" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>

</androidx.constraintlayout.widget.ConstraintLayout>
BlazeCodeDev
  • 631
  • 1
  • 7
  • 27

2 Answers2

1

Try this:

In ItemViewHolder add a View object and set it to itemView:

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

    public ImageView mImageView;
    public TextView mTextView;
    //add here
    public View view;

    ItemsListAdapterListener mItemsListAdapterListener;

    public ItemViewHolder(@NonNull View itemView, ItemsListAdapterListener itemsListAdapterListener) {
        super(itemView);

        //set here
        view = itemView;
        .........
        .........

Now set the onClickListener in onBindViewHolder:

@Override
public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {

    Item item = mItemListFiltered.get(position);

    holder.mImageView.setImageResource(item.getImgURL());
    holder.mTextView.setText(item.getItemName());

    //here
    holder.view.setOnClickListener(new View.OnClickListener(){

     @Override
     public void onClick(View view){

      mItemsListAdapterListener.onItemClick(position);

     }

    });

}

UPDATE:

Remove this from cardView xml:

android:clickable="true"
Hasan Bou Taam
  • 4,017
  • 2
  • 12
  • 22
1

Try removing android:clickable="true" from your CardView.

I think what is happening is you are clicking on the CardView, which is stealing the click so the root view does not get it.

PhillyTheThrilly
  • 1,562
  • 2
  • 16
  • 21