Scrollview 和 内部 recycleview 高度固定时嵌套冲突的一种解决方法

了解事件分发机制就很容易了解原理,就是在子view需要处理滑动事件时,父view则不对事件进行拦截处理交由子view进行事件处理,而在父view需要处理时则进行拦截处理,不让子view处理。

1.首先自定义scrollview,onInterceptTouchEvent方法就是拦截方法,返回true则代表拦截,不让自view进行处理,返回false,代表让子view 进行处理。

public class ScrollViewWithListener extends ScrollView {
      private ScrollViewListener scrollViewListener;
      private onSrcollviewToBottoListener onSrcollviewToBottomListener;
     private boolean isBotoom=false;//是否滑动到底部
     private boolean isTop=false;//是否内部listview滑动到顶部
     public ScrollViewWithListener(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (ev.getAction()==MotionEvent.ACTION_DOWN) {
            Log.v("action_down",ev.toString());
            if(isTop&&isBotoom){
                Log.v("同时触及",isTop+""+isBotoom);
                return  false;
            }
            return super .onInterceptTouchEvent(ev);
        }else if (ev.getAction()==MotionEvent.ACTION_MOVE) {

            Log.v("截断",isTop+""+isBotoom);
            if (isTop) {
                return  super.onInterceptTouchEvent(ev);

            }else if (isBotoom) {//如果是底部交由子view处理
                return false;
            }
        } else if(ev.getAction()==MotionEvent.ACTION_UP){
            Log.v("action_up",ev.toString());
            return false;
        }

        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return super.onTouchEvent(ev);
    }
  
    public ScrollViewWithListener(Context context) {
        super(context);
    }

    public ScrollViewWithListener(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }



    public void setScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

       public   void setOnToBottomListenr(onSrcollviewToBottomListener onSrcollviewToBottomListener){
           this.onSrcollviewToBottomListener=onSrcollviewToBottomListener;

       }

    @Override
    protected void onScrollChanged(int x, int y, int oldx, int oldy) {
       View  view=getChildAt(getChildCount()-1);
        int d=view.getBottom();
        d-=getHeight()+getScrollY();
        if (d==0){//判断是否为底部
            if (onSrcollviewToBottomListener!=null){
            onSrcollviewToBottomListener.onScrollToBottom(true);}
            isBotoom=true;
        }else {
            if (oldy-y!=0){
                isBotoom=false;
            }

            super.onScrollChanged(x, y, oldx, oldy);
        }



        if (scrollViewListener != null) {
            scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
        }
    }
     public void  setIsTop(boolean istop){
      this.isTop=istop;
     }
      public interface onSrcollviewToBottomListener{
         void onScrollToBottom(boolean isBotoom );
  }

}
复制代码

2.对子view 的listview 滑动监听。并且回调结处理结果。

   private OnTopListener onTopListener;
private void setScrollViewMoveWhenListViewStopMoving(ListView lv_hot_service) {
        lv_hot_service.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                switch (scrollState){
                    case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
                       if (view.getLastVisiblePosition()==(view.getCount()-1)){
                           Log.v("到底了","到底了");
                    }
                       if (view.getFirstVisiblePosition()==0){
                           onTopListener.viewIsTop(true);
                           Log.v("vvvvvvvvvv","到顶了"+isListviewTop);
                       }else {
                           onTopListener.viewIsTop(false);
                           Log.v("vvvvvvvvvv","在中间"+isListviewTop);
                       }
                       break;
                    case  AbsListView.OnScrollListener.SCROLL_STATE_FLING:
                        onTopListener.viewIsTop(false);
                        break;
                    case  AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                        onTopListener.viewIsTop(false);
                        break;
                }
            }
            @Override
 public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

  }
    });

 public void setOnTopListener(OnTopListener onTopListener){
        this.onTopListener=onTopListener;
    }
    }
复制代码

然后将listview的滑动结果传递给父view srcollview进行处理。

scrollListener.setOnToBottomListenr(new ScrollViewWithListener.onSrcollviewToBottomListener() {
            @Override
            public void onScrollToBottom(boolean isBotoom) {
                if (isBotoom) {
                    isListviewTop = false;//记录到底而让listview 接管监听
                    onTopListener.viewIsTop(false);
                    Log.v("scrollview到底了","到底了");
                }
            }
        });
复制代码

虽然简单的解决了一下问题但还是存在一些问题 记录下自己接下来再更改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值