這兩天重構(gòu)項(xiàng)目阎姥,遇到需要添加一個(gè)Fab的時(shí)候闭专,就隨便上網(wǎng)上copy了一段代碼,測(cè)試的時(shí)候發(fā)現(xiàn)逗余,只能執(zhí)行一次特咆,之后就不會(huì)走Behavior的onNestedScroll方法了。
在網(wǎng)上找了半天解決辦法录粱,也沒有找到腻格。最后只能看看源碼到底是因?yàn)槭裁窗苫埃苯由显创a
@Override
public boolean onStartNestedScroll(View child, View target, int axes, int type) {
boolean handled = false;
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View view = getChildAt(i);
if (view.getVisibility() == View.GONE) {
// If it's GONE, don't dispatch
continue;
}
final LayoutParams lp = (LayoutParams) view.getLayoutParams();
final Behavior viewBehavior = lp.getBehavior();
if (viewBehavior != null) {
final boolean accepted = viewBehavior.onStartNestedScroll(this, view, child,
target, axes, type);
handled |= accepted;
lp.setNestedScrollAccepted(type, accepted);
} else {
lp.setNestedScrollAccepted(type, false);
}
}
return handled;
}
自定義的Behavior中的onStartNestedScroll方法最后會(huì)走到CoordinatorLayout方法的onStartNestedScroll方法中 在里面判斷了一下childView的visibility的屬性是不是GONE 是的話就會(huì)跳過
同樣的onNestedScroll中也會(huì)判斷childView的屬性,是GONE的時(shí)候就回跳過菜职。所以在設(shè)置需要執(zhí)行Behavior的View的屬性就不要設(shè)置成GONE就可以了青抛。
@Override
public void onNestedScroll(View target, int dxConsumed, int dyConsumed,
int dxUnconsumed, int dyUnconsumed, int type) {
final int childCount = getChildCount();
boolean accepted = false;
for (int i = 0; i < childCount; i++) {
final View view = getChildAt(i);
if (view.getVisibility() == GONE) {
// If the child is GONE, skip...
continue;
}
final LayoutParams lp = (LayoutParams) view.getLayoutParams();
if (!lp.isNestedScrollAccepted(type)) {
continue;
}
final Behavior viewBehavior = lp.getBehavior();
if (viewBehavior != null) {
viewBehavior.onNestedScroll(this, view, target, dxConsumed, dyConsumed,
dxUnconsumed, dyUnconsumed, type);
accepted = true;
}
}
if (accepted) {
onChildViewsChanged(EVENT_NESTED_SCROLL);
}
}
最后附上自己寫的BaseBehavior以及一個(gè)可用的Behavior
open class BaseBehavior<T : View> constructor(context: Context,attrs:AttributeSet): CoordinatorLayout.Behavior<T>(){
private val mFastInterpolator = FastOutSlowInInterpolator()
// 顯示view
fun scaleShow(view: View,l :ListenerAnimatorEndBuild?) {
view.visibility = View.VISIBLE
ViewCompat.animate(view)
.scaleX(1.0f)
.scaleY(1.0f)
.alpha(1.0f)
.setDuration(500)
.setListener(l?.build())
.setInterpolator(mFastInterpolator)
.start()
}
// 隱藏view
fun scaleHide(view: View,l:ListenerAnimatorEndBuild?) {
ViewCompat.animate(view)
.scaleX(0.0f)
.scaleY(0.0f)
.alpha(0.0f)
.setDuration(500)
.setInterpolator(mFastInterpolator)
.setListener(l?.build())
.start()
}
class ListenerAnimatorEndBuild {
// 記錄View移出動(dòng)畫是否執(zhí)行完。
private var isOutExecute = false
private val outAnimatorListener: ViewPropertyAnimatorListener
// View移出動(dòng)畫是否執(zhí)行完酬核。
val isFinish: Boolean
get() = !isOutExecute
init {
outAnimatorListener = object : ViewPropertyAnimatorListener {
override fun onAnimationStart(view: View) {
isOutExecute = true
}
override fun onAnimationEnd(view: View) {
view.visibility = View.INVISIBLE
isOutExecute = false
}
override fun onAnimationCancel(view: View) {
isOutExecute = false
}
}
}
// 返回ViewPropertyAnimatorListener蜜另。
fun build(): ViewPropertyAnimatorListener {
return outAnimatorListener
}
}
}
class FabBehavior constructor(context: Context, attributeSet: AttributeSet) : BaseBehavior<FloatingActionButton>(context, attributeSet) {
private var listenerAnimatorEndBuild = ListenerAnimatorEndBuild()
override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout,
child: FloatingActionButton,
directTargetChild: View,
target: View, axes: Int, type: Int): Boolean {
return axes == ViewCompat.SCROLL_AXIS_VERTICAL
}
override fun onNestedScroll(coordinatorLayout: CoordinatorLayout,
child: FloatingActionButton,
target: View,
dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int,
type: Int) {
if (dyConsumed > 0 && dyUnconsumed == 0) {
KLog.d("behavior", "上滑中。愁茁。蚕钦。")
}
if (dyConsumed == 0 && dyUnconsumed > 0) {
KLog.d("behavior", "到邊界了還在上滑。鹅很。。")
}
if (dyConsumed < 0 && dyUnconsumed == 0) {
KLog.d("behavior", "下滑中罪帖。促煮。。")
}
if (dyConsumed == 0 && dyUnconsumed < 0) {
KLog.d("behavior", "到邊界了整袁,還在下滑菠齿。。坐昙。")
}
//頁(yè)面向上滑動(dòng)像素?cái)?shù)大于0 || 拉到底還在向上拉 && 退出動(dòng)畫是否正在執(zhí)行 && FAB按鈕當(dāng)前顯示中
if ((dyConsumed > 0 || dyUnconsumed > 0) && listenerAnimatorEndBuild.isFinish&& child.visibility == View.VISIBLE) {
//隱藏Fab
scaleHide(child,listenerAnimatorEndBuild)
} else if ((dyConsumed < 0 || dyUnconsumed < 0) && child.visibility != View.VISIBLE) {
//顯示Fab按鈕
scaleShow(child,null)
}
}
}
copy過去就能用了 部分動(dòng)畫代碼是上網(wǎng)上找的绳匀,畢竟我懶的寫。炸客。疾棵。
至于是kotlin寫的也沒關(guān)系,之間copy的話 as會(huì)自動(dòng)轉(zhuǎn)為java的痹仙。