wbk727
wbk727

Reputation: 8408

RecyclerView click event not working

For some reason the click event doesn't work for my RecyclerView despite the items appearing as normal. I have used 2 different adapters based on screen size. Does anyone know why it's not working and how this can be fixed?

recyclerview_item_gridcell (for larger screens)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:padding="20dp"
    android:clickable="true"
    android:focusable="true"   
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <Button
        android:id="@+id/info_text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

recyclerview_item_textview (for smaller screens)

<?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clickable="true"
    android:focusable="true"            
    android:background="?android:attr/selectableItemBackground"
    />

Activity class

public class MainActivity extends Activity implements MyRecyclerViewAdapterGL.ItemClickListener, MyRecyclerViewAdapterLL.ItemClickListener {

    boolean themeState;
    MyRecyclerViewAdapterGL adapterGL;
    MyRecyclerViewAdapterLL adapterLL;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        boolean isScreenSmall = getResources().getBoolean(R.bool.is_screen_small);

        setContentView(R.layout.activity_main);

        String[] dataArray = {"Item A", "Item B", "Item C", "Item D" ,"Item E" ,"Item F"};

        if(isScreenSmall){
            // ItemDecoration for small devices
            RecyclerView recyclerViewLL = findViewById(R.id.recyclerView_list);
            recyclerViewLL.setLayoutManager(new LinearLayoutManager(this));
            adapterLL = new MyRecyclerViewAdapterLL(this, dataArray);
            adapterLL.setClickListener(this);
            recyclerViewLL.addItemDecoration(new DividerItemDecoration(this, LinearLayout.VERTICAL));
            recyclerViewLL.setAdapter(adapterLL);
        }
        else{
            // ItemDecoration for large devices
            RecyclerView recyclerViewGL = findViewById(R.id.recyclerView_list);
            int numberOfColumns = 2;
            recyclerViewGL.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
            adapterGL = new MyRecyclerViewAdapterGL(this, dataArray);
            adapterGL.setClickListener(this);
            recyclerViewGL.setAdapter(adapterGL);
        }
    }

    @Override
    public void onItemClick(View view, int position) {
        if (position == 0) {
            Toast.makeText(MainActivity.this, "Item A was clicked", LENGTH_SHORT).show();
        } else if (position == 1) {
            Toast.makeText(MainActivity.this, "Item B was clicked", LENGTH_SHORT).show();
        } else if (position == 2) {
            Toast.makeText(MainActivity.this, "Item C was clicked", LENGTH_SHORT).show();
        }
    }
}

RecyclerView adapter class (for smaller screens)

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

    private String[] mData;
    private LayoutInflater mInflater;
    private MyRecyclerViewAdapterLL.ItemClickListener mClickListener;

    MyRecyclerViewAdapterLL(Context context, String[] data) {
        this.mInflater = LayoutInflater.from(context);
        this.mData = data;
    }

    @Override
    @NonNull
    public MyRecyclerViewAdapterLL.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.recyclerview_item_textview, parent, false);
        return new MyRecyclerViewAdapterLL.ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyRecyclerViewAdapterLL.ViewHolder holder, int position) {
        holder.myTextView.setText(mData[position]);
    }

    @Override
    public int getItemCount() {
        return mData.length;
    }


    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView myTextView;

        ViewHolder(View itemView) {
            super(itemView);
            myTextView = itemView.findViewById(R.id.item_text);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
        }
    }

    String getItem(int id) {
        return mData[id];
    }

    void setClickListener(MyRecyclerViewAdapterLL.ItemClickListener itemClickListener) {
        this.mClickListener = itemClickListener;
    }

    public interface ItemClickListener {
        void onItemClick(View view, int position);
    }
}

RecyclerView adapter class (for larger screens)

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

    private String[] mData;
    private LayoutInflater mInflater;
    private ItemClickListener mClickListener;

    MyRecyclerViewAdapterGL(Context context, String[] data) {
        this.mInflater = LayoutInflater.from(context);
        this.mData = data;
    }

    @Override
    @NonNull
    public MyRecyclerViewAdapterGL.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.recyclerview_item_gridcell, parent, false);
        return new MyRecyclerViewAdapterGL.ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        holder.myTextView.setText(mData[position]);
    }

    @Override
    public int getItemCount() {
        return mData.length;
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView myTextView;

        ViewHolder(View itemView) {
            super(itemView);
            myTextView = itemView.findViewById(R.id.info_text);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
        }
    }

    String getItem(int id) {
        return mData[id];
    }

    void setClickListener(MyRecyclerViewAdapterGL.ItemClickListener itemClickListener) {
        this.mClickListener = itemClickListener;
    }

    // parent activity will implement this method to respond to click events
    public interface ItemClickListener {
        void onItemClick(View view, int position);
    }
}

Upvotes: 2

Views: 1723

Answers (2)

Emre Akt&#252;rk
Emre Akt&#252;rk

Reputation: 3346

Check your root views are clickable and focusable in xml cells. You should be able to see ripple on touch down.

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:padding="20dp"
android:layout_width="match_parent"
android:clickable="true"
android:focusable="true"
android:layout_height="wrap_content"> ....

and

<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/item_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"
/>

UPDATE 2

Your linearlayout has no touchable area. Thats why we couldnt trigger on click method because that button fills the root. We are unable to touch root element. So you should use button.setClickListener instead in that state.

Upvotes: 1

Ashwini Saini
Ashwini Saini

Reputation: 1374

In your adapter class (both classes) you set OnClickListener on entire itemview instead you should set OnClickListener on myTextView

so it will be like

myTextView = itemView.findViewById(R.id.info_text);
            myTextView.setOnClickListener(this);

Upvotes: 1

Related Questions