【FirstKotlinApp】自定义Behavior实现布局协同

来源:互联网 发布:雅思8.5 知乎 编辑:程序博客网 时间:2024/06/11 07:42

自Google推出CoordinatorLayout,其中最经典的设计Behavior就被广大开发者频频称道,其主要功能就是使布局中的指定控件(使用behavior属性)可以跟随其它组件进行协同操作,例如滑动隐藏Toolbar、动态改变FloatingActionButton的高度等。用好Behavior,可使界面控件的动作配合更加协调

Android本身自带了一个Behavior的实现,如下:

  • appbar_scrolling_view_behavior

该Behavior可以实现Appbar在视图滑动时进行隐藏等效果,如果你的需求符合该定义,则直接通过

  • app:layout_behavior=”appbar_scrolling_view_behavior”

使用即可(注意命名空间引入)。

言归正传,下面说一下自定义Behavior该如何实现

自定义Behavior有两种方式:

  1. 通过定义的View监听CoordinatorLayout里的滑动状态
    对于该方法,我们主要关注onStartNestedScroll和onNestedPreScroll方法

  2. 通过定义的View监听另一个View的状态变化
    对于该方法,我们需要注意layoutDependsOn和onDependViewChanged方法

当然,上述方法的基础是,要自定义一个类并继承CoordinatorLayout.Behavior,并重写相应的方法进行事件监听,然后将该Behavior的全路径,通过app:layout_behavior方法设置给相应控件

此处以我的毕业设计中商品详情页为例:

这里写图片描述

此处实现了底部价格和购买按钮的跟随滑动,上部Toolbar的滑动由内置的Behavior完成,具体实现代码如下:

Tips:我使用了第一种方法进行实现,因为其可定制性较高。第二种方法是注释的代码,效果和第一种略有不同,看需求。

class FooterBehavior(private val context: Context, private val attributeSet: AttributeSet) : CoordinatorLayout.Behavior<View>(context, attributeSet) {//    override fun layoutDependsOn(parent: CoordinatorLayout?, child: View?, dependency: View?): Boolean {//        return dependency is AppBarLayout//    }////    override fun onDependentViewChanged(parent: CoordinatorLayout?, child: View?, dependency: View?): Boolean {//        val translationY = Math.abs(dependency!!.y)//        child?.translationY = translationY////        log(LogType.DEBUG, "behavior", dependency!!.y.toString())//        return true//    }    override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout?, child: View?, directTargetChild: View?, target: View?, nestedScrollAxes: Int): Boolean {        return (nestedScrollAxes shl ViewCompat.SCROLL_AXIS_VERTICAL) != 0    }    private var transY = 0f    override fun onNestedPreScroll(coordinatorLayout: CoordinatorLayout?, child: View?, target: View?, dx: Int, dy: Int, consumed: IntArray?) {        val h: Float = (child!!.height + 100).toFloat()        if (dy > 0 && transY <= h) {            transY += dy            if (transY > h) transY            child!!.translationY = transY        } else if (dy < 0) {            transY += dy            if (transY < 0) transY = 0f            child!!.translationY = transY        }        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed)    }}

第一种方法的实现思路(仅是Kotlin代码,Java通用)

  1. onStartNestedScroll:该方法用来确定关心的滑动方向,主要关注最后一个参数,其回调传入的值为具体的滑动方向,可以通过相应运算确定是否捕获。其余参数的意义通过参数名即可清楚
  2. onNestedPreScroll:该方法内传入的参数为被监听的View以及需要操作的View,和相应的滑动参数。在方法内通过对滑动参数的运算,动态操作child,即可实现控件协同操作

第二种方法的实现思路(仅是Kotlin代码,Java通用)

  1. layoutDependsOn:该方法确定关注哪个控件的滑动事件,主要注意dependency参数,其代表滑动的控件,返回值为真则监听该控件事件
  2. onDependentViewChanged:在方法内,通过对被监听对象的位置运算,实现控件的同步操作。该方法与第一种方法相比,参数更为简单,实现起来方便,但限制也是明显的,所以适合页面需求较为单一的滑动监听。例如同步收放等。

使用Behavior最重要的一点就是,控件的跟布局一定是CoordinatorLayout,而且一定要指定好控件,否则是没有效果的。

本章参考了《Android进阶之光》一书,其中原理多数来自该书第二章2.2.6节,此处通过自我实践与书中理论相结合,分享给大家,希望对你有帮助。
写于:2017年9月17日 18:26

阅读全文
0 0
原创粉丝点击