效果
首先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()
}
}
}