效果

首先ExtendedFloatingActionButton有默认的Behavior : ExtendedFloatingActionButtonBehavior,这个类是为了ExtendedFloatingActionButton不被SnakBar所遮挡,并且这个类它是protected,所以为了保留原有的设计,自定义的Behavior不能在外部定义,必须自定义一个ExtendedFloatingActionButton子类,然后在子类中实现一个ExtendedFloatingActionButtonBehavior类即可,并且自定义的ExtendedFloatingActionButton子类必须是非final的。
ExtendedFloatingActionButton实现了CoordinatorLayout.AttachedBehavior接口,默认Behavior

这个接口是一个单一抽象接口(SAM接口),用于设置该View的默认Behavior,此方法在CoordinatorLayout#getResolvedLayoutParams(View)中被调用:

可以看到这个接口是给View实现的,所以ExtendedFloatingActionButton自然是实现了该接口并返回ExtendedFloatingActionButtonBehavior实例:

自定义Behavior
创建一个ExtendedFloatingActionButton子类并在其中创建一个自定义的Behavior,并从getBehavior()方法中返回
open class ExtendedFAB @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
) : ExtendedFloatingActionButton(context, attributeSet) {
private val fabBehavior = ExtendedFABBehavior(context, attributeSet)
override fun getBehavior(): CoordinatorLayout.Behavior<ExtendedFloatingActionButton> {
return fabBehavior
}
protected class ExtendedFABBehavior(
context: Context,
attributeSet: AttributeSet?
) : ExtendedFloatingActionButtonBehavior<ExtendedFloatingActionButton>(context, attributeSet) {
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: ExtendedFloatingActionButton,
directTargetChild: View,
target: View,
axes: Int,
type: Int
): Boolean {
return axes == ViewCompat.SCROLL_AXIS_VERTICAL
}
override fun onNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: ExtendedFloatingActionButton,
target: View,
dxConsumed: Int,
dyConsumed: Int,
dxUnconsumed: Int,
dyUnconsumed: Int,
type: Int,
consumed: IntArray
) {
if (dyConsumed > 0) {
shrink(child)
} else {
extend(child)
}
}
private fun extend(child: ExtendedFloatingActionButton) {
child.extend()
}
private fun shrink(child: ExtendedFloatingActionButton) {
child.shrink()
}
}
}

















