解决 RecyclerView 使用 paddingTop & clipToPadding = false 时,上方透明区域 Touch 事件无法下传

本文转载自:https://drakeet.me/fix-recyclerview-use-paddingtop-cliptopadding-false-touch-event


解决办法相对比较简单,正好今天有人问到这个问题,所以把我的做法分享出来,即做一下手势分发即可,对此我继承 RecyclerView 做了 dispatchTouchEvent() 方法的重写,我使用了 Kotlin 编程语言,阅读起来应该不是什么问题,读者有需要的话,我已经增加了 Java 版本了,其他的可以自行修改。

原理就是当检测到有设置 clipToPadding = false 的时候,进行触摸点位置判断,在 dispatchTouchEvent() 方法返回 false 即表示对当前触摸事件不感兴趣,事件可将手势往下层传递,全部的代码下面会附上。

这篇文章可以说,让 RecyclerView 离无所不能真正又近了一步,从此可以不再搞什么 add header view 来设置头部内容了。当你突发奇想像我那么做(可以结合 CollapsingToolbarLayout 效果更好)的时候,遇到我所遇到的问题,这篇文章应该能够受益匪浅:D

public class GenerousRecyclerView extends RecyclerView {
 
     public int mScrollY = 0 ;
     private boolean mEating = false ;
 
 
     public GenerousRecyclerView(Context context) {
         this (context, null );
     }
 
 
     public GenerousRecyclerView(Context context, AttributeSet attrs) {
         this (context, attrs, 0 );
     }
 
 
     public GenerousRecyclerView(Context context, AttributeSet attrs, int defStyle) {
         super (context, attrs, defStyle);
         addOnScrollListener( new OnScrollListener() {
             @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                 super .onScrollStateChanged(recyclerView, newState);
                 switch (newState) {
                     case SCROLL_STATE_IDLE:
                         mEating = false ;
                         break ;
                     case SCROLL_STATE_DRAGGING:
                         mEating = true ;
                         break ;
                 }
             }
 
 
             @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                 super .onScrolled(recyclerView, dx, dy);
                 mScrollY += dy;
             }
         });
     }
 
 
     @Override public boolean dispatchTouchEvent(MotionEvent ev) {
         if (!mEating && !getClipToPaddingCompat() && ev.getY() + mScrollY < getPaddingTop()
                 && ev.getY() < getPaddingTop()) {
             return false ;
         }
         else {
             return super .dispatchTouchEvent(ev);
         }
     }
 
 
     /**
      * @return false, if sdk_int < 21. else return getClipToPadding();
      */
     private boolean getClipToPaddingCompat() {
         if (Build.VERSION.SDK_INT < 21 ) {
             return getLayoutManager() != null && getLayoutManager().getClipToPadding();
         }
         else {
             return getClipToPadding();
         }
     }
}



GitHUB源代码:https://github.com/drakeet/GenerousRecyclerView


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值