How to handle click-event in RecyclerView.ItemDecoration?

I have a RecyclerView (with LinearLayoutManager) and a custom RecyclerView.ItemDecoration for it.

Let’s say, I want to have buttons in the decoration view (for some reason..).

  • How to manage multiple Async Tasks efficiently in Android
  • How to display a one time welcome screen?
  • Camera on Android Example
  • Custom Android calendarView
  • Resource structure in Apache Cordova (PhoneGap) and loading the files from the filesystem
  • android - Call requires API level 9 (current min is 8): android.os.StrictMode#setThreadPolicy
  • I inflate the layout with button, it draws properly. But I can’t make the button clickable. If I press on it, nothing happening(it stays the same, no pressing effect) and onClick event is not firing.

    The structure of ItemDecoration layout is

    <LinearLayout>
      <TextView/>
      <Button/>
    </LinearLayout>
    

    And I’m trying to set listener in ViewHolder of the decoration

    class ItemDecorationHolder extends RecyclerView.ViewHolder {
        public TextView header;
        public Button button;
    
        public HeaderHolder(View itemView) {
            super(itemView);
    
            header = (TextView)itemView.findViewById(R.id.header);
            button = (Button)itemView.findViewById(R.id.button);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //.. Show toast, etc.
                }
            });
        }
    }
    

    And i’m drawing the decoration in onDrawOver method. (actually, I’m modifying this codebase: https://github.com/edubarr/header-decor )

    Any ideas? Is it doable?

    Thanks!

    Related posts:

    Android HTTPUrlConnection : how to set post data in http body?
    Android ListView addHeaderView() nullPointerException for predefined Views defined in XML
    Android Floating Action Button options Menu
    How to Read MMS Data in Android?
    HTC M8 Unsatisfied Link Error after 5.0.1 update
    Android ListView with fast scroll and alphabetical section index
  • How ListView's recycling mechanism works
  • Android Responsive design
  • How can I make several clickable parts of text in TextView
  • Secure HTTP Post in Android
  • Put an indeterminate progressbar as footer in a RecyclerView grid
  • Mobile webkit memory consumption
  • 3 Solutions collect form web for “How to handle click-event in RecyclerView.ItemDecoration?”

    While the real header is scroll off the screen, the visible one is drawing on canvas directly ,not like a normal interactive widget.

    You have these options

    1. Override RecyclerView.onInterceptTouchEvent(), though with some invasiveness so I prefer the next one.
    2. Make use of RecyclerView.addOnItemTouchListener(), remember the motion event argument has been translated into RecyclerView’s coordinate system.
    3. Use a real header view, but that will go a little far I think.

    If you take option 1/2, Button.setPressed(true) and redraw the header will have a visual press effect.

    In addition to what Neil said,
    the answer here might help.
    Passing MotionEvents from RecyclerView.OnItemTouchListener to GestureDetectorCompat

    And then you just need to calculate the height of the header and see if the click falls onto that header view and handle the event yourself.

    private class RecyclerViewOnGestureListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            float touchY = e.getY();
    
    
    
            ALLog.i(this, "Recyclerview single tap confirmed y: " + touchY);
            //mGroupHeaderHeight is the height of the header which is used to determine whether the click is inside of the view, hopefully it's a fixed size it would make things easier here 
            if(touchY < mGroupHeaderHeight) {
                int itemAdapterPosition = mRecyclerView.getLayoutManager().getPosition(mRecyclerView.findChildViewUnder(0, mGroupHeaderHeight));
    
                //Do stuff here no you have the position of the item that's been clicked
                return true;
            }
            return super.onSingleTapConfirmed(e);
    
        }
    
        @Override
        public boolean onDown(MotionEvent e) {
            float touchY = e.getY();
    
            if(touchY < mGroupHeaderHeight) {
                return true;
            }
            return super.onDown(e);
        }
    
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            float touchY = e.getY();
    
            if(touchY < mGroupHeaderHeight) {
                return true;
            }
            return super.onSingleTapUp(e);
        }
    }
    

    As Neil is pointing out, things are getting more complicated than that. However by definition you can’t.

    So, why not including good libraries that do that and more?
    I propose my hard work for clickable sticky header in my FlexibleAdapter project, which uses a real view (not decorators) to handle click events on headers when sticky.

    There’s also a working demo and a Wiki page on that part (and not only).

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.