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

5 篇文章 0 订阅
4 篇文章 0 订阅

自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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值