用户登录
用户注册

分享至

AppBarLayout原理分析

  • 作者: 闲的蛋掉毛
  • 来源: 51数据库
  • 2021-08-19

一、AppBarLayout为什么可以滑动

AppBarLayout滑动分为两种情况:

  1. 滑动AppBarLayout引起的滑动
  2. 滑动底部的列表引起的滑动

1、滑动AppBarLayout引起的滑动

我们分别继承了MyCoordinatorLayout、MyAppbarLayout、MyAppbarBehavior以及MyAppbarScrollingViewBehavior,在onInterceptTouchEvent和onTouchEvent中打印日志。MyCoordinatorLayout重写如下,其他类类似。

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.e(TAG, "------------------------------------------------");
        Log.e(TAG, "onInterceptTouchEvent>>start");
        boolean result = super.onInterceptTouchEvent(ev);
        Log.e(TAG, "onInterceptTouchEvent>>result:" + result);
        Log.e(TAG, "------------------------------------------------");
        return result;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        Log.e(TAG, "------------------------------------------------");
        Log.e(TAG, "onTouchEvent>>start");
        boolean result = super.onTouchEvent(ev);
        Log.e(TAG, "onTouchEvent>>result:" + result);
        Log.e(TAG, "------------------------------------------------");
        return result;
    }

当我们滑动AppBarLayout时打印日志如下:

com.demo.app E/MyCoordinatorLayout: ------------------------------------------------
com.demo.app E/MyCoordinatorLayout: onInterceptTouchEvent>>start
com.demo.app E/MyAppbarBehavior: onInterceptTouchEvent>>start
com.demo.app E/MyAppbarBehavior: onInterceptTouchEvent>>result:false
com.demo.app E/MyAppbarScrollingViewBehavior: onInterceptTouchEvent>>result:false
com.demo.app E/MyAppbarBehavior: onInterceptTouchEvent>>start
com.demo.app E/MyAppbarBehavior: onInterceptTouchEvent>>result:false
com.demo.app E/MyAppbarScrollingViewBehavior: onInterceptTouchEvent>>result:false
com.demo.app E/MyCoordinatorLayout: onInterceptTouchEvent>>result:false
com.demo.app E/MyCoordinatorLayout: ------------------------------------------------

com.demo.app E/MyAppbarLayout: ------------------------------------------------
com.demo.app E/MyAppbarLayout: onInterceptTouchEvent>>start
com.demo.app E/MyAppbarLayout: onInterceptTouchEvent>>result:false
com.demo.app E/MyAppbarLayout: ------------------------------------------------

com.demo.app E/MyAppbarLayout: ------------------------------------------------
com.demo.app E/MyAppbarLayout: onTouchEvent>>start
com.demo.app E/MyAppbarLayout: onTouchEvent>>result:false
com.demo.app E/MyAppbarLayout: ------------------------------------------------

com.demo.app E/MyCoordinatorLayout: ------------------------------------------------
com.demo.app E/MyCoordinatorLayout: onTouchEvent>>start
com.demo.app E/MyAppbarBehavior: onTouchEvent>>start
com.demo.app E/MyAppbarBehavior: onTouchEvent>>result:true
com.demo.app E/MyAppbarBehavior: onTouchEvent>>start
com.demo.app E/MyAppbarBehavior: onTouchEvent>>result:true
com.demo.app E/MyCoordinatorLayout: onTouchEvent>>result:true
com.demo.app E/MyCoordinatorLayout: ------------------------------------------------

com.demo.app E/MyCoordinatorLayout: ------------------------------------------------
com.demo.app E/MyCoordinatorLayout: onTouchEvent>>start
com.demo.app E/MyAppbarBehavior: onTouchEvent>>start
com.demo.app E/MyAppbarBehavior: onTouchEvent>>result:true
com.demo.app E/MyCoordinatorLayout: onTouchEvent>>result:true
com.demo.app E/MyCoordinatorLayout: ------------------------------------------------

通过上面的日志我们可以看出整个事件处理的流程。事件最先到CoordinatorLayout的onInterceptTouchEvent,CoordinatorLayout会调用Behavior的onInterceptTouchEvent,Behavior返回false不处理事件,即CoordinatorLayout的onInterceptTouchEvent返回false。
然后事件传递到AppbarLayout的onInterceptTouchEvent,AppbarLayout返回false不拦截事件。即所有控件都没有拦截事件。
然后事件传递到AppbarLayout的onTouchEvent,AppbarLayout不处理事件返回false。
然后事件向上传递到CoordinatorLayout的onTouchEvent,CoordinatorLayout会调用Behavior的onTouchEvent处理事件,Behavior的onTouchEvent处理了事件返回true,因此CoordinatorLayout的onTouchEvent也会返回true。这代表事件最终由CoordinatorLayout处理,CoordinatorLayout又会在onTouchEvent中调用Behavior的onTouchEvent,即最终事件的处理是在Behavior的onTouchEvent中。

软件
前端设计
程序设计
Java相关