Thomas Vos
Thomas Vos

Reputation: 12571

How to make a RecyclerView not clickable and pass onClick event to parent view?

Is it possible to make a RecyclerView not clickable? I want this because my RecyclerView just shows some small icons, within a clickable CardView. So if someone taps the icons, it should just click (and animate) the parent CardView instead.

I have tried the following:

  1. recyclerView.setClickable(false);
  2. recyclerView.setFocusable(false);
  3. Extend RecyclerView and make onTouchEvent(MotionEvent) return false.
  4. Use method 3 above and use itemView.setClickable(false); in the RecyclerView Adapter. This works, the click is sent to the parent. However, now the RecyclerView is not scrollable anymore.
  5. Set clickable="false", focusable="false", focusableInTouchMode="false" in inflated list item XML. (See comment @Ibrahim)
  6. Call recyclerView#setLayoutFrozen(true) and itemView.setClickable(false);. This works, but has the same issue as #4.

Any ideas how to disable and pass through the click events of the RecyclerView to the parent view? Note that the RecyclerView still needs to be scrollable (horizontal).


EDIT:
User @c.dunlap suggested to set OnClick listeners to the icons, and just "redirect" the click to the parent's click action. This would work, but there won't be a click animation on the parent view. And if someone clicks outside an itemView - but still inside the RecyclerView (e.g. ItemDecoration padding) - the click is not detected. So unfortunately this is not a solution.

Upvotes: 28

Views: 11287

Answers (3)

nsL
nsL

Reputation: 3792

You should extend the parent View and intercept the click, so the recyclerview doesn't receive it.

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return true;
}

Credits to: Solution

Upvotes: 18

c.dunlap
c.dunlap

Reputation: 600

My preferred way of handling things like this is to attach a listener from your adapter that will be called when each icon in your recycler view is clicked. Then your activity can respond in the appropriate way. For instance:

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private MyAdapterListener mListener;

    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
         holder.itemView.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
                 mListener.iconClicked();
             }
         });
    }

    public void setListener(MyAdapterListener listener) {
        mListener = listener;
    }

    public interface MyAdapterListener {
        void iconClicked();
    }

}

Then in your activity, you can simply create an instance of MyAdapterListener and set it as the listener for your Recycler View's adapter. Then when iconClicked() function is triggered, execute the code that would be executed on parent click.

Upvotes: 3

Deepak Tiwari
Deepak Tiwari

Reputation: 92

I had same issue, after i trying much more things, i used one more layout over recyclerview.

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.RecyclerView
        android:layoutwidth="match_parent"
        android:layout_height="match_parent">
    </android.support.v7.widget.RecyclerView>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</RelativeLayout>

after that you can visible and gone that "LinearLayout". This works 100%.

Upvotes: -2

Related Questions