今天,在重写 FloatingActionButton.Behavior 的时候,遇到了问题,记录一下
第一个问题,在完成了 behavior 代码之后
public class ScrollFABBehavior extends FloatingActionButton.Behavior {
@Override
public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,
@NonNull FloatingActionButton child,
@NonNull View directTargetChild,
@NonNull View target, int axes, int type) {
// Ensure we react to vertical scrolling
return axes == ViewCompat.SCROLL_AXIS_VERTICAL
|| super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes);
}
@Override
public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,
@NonNull FloatingActionButton child,
@NonNull View target,
int dxConsumed,
int dyConsumed,
int dxUnconsumed,
int dyUnconsumed,
int type) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
child.hide();
} else if (dyConsumed <= 0 && child.getVisibility() != View.VISIBLE) {
child.show();
}
}
}
用在 FAB 上的时候 出现了 异常
Could not inflate Behavior subclass com.example.....ScrollFABBehavior
仔细一看,shit,忘记了 从 xml 加载对应的 构造函数
加上就解决了
public ScrollFABBehavior(Context context, AttributeSet attrs) {
super();
}
接下来是第二个问题
FAB 的 hide() 没有问题,可以hide 完之后 不show 了。
跟踪一下发现,onNestedScroll() 只调用了一次
/**
* Called when a nested scroll in progress has updated and the target has scrolled or
* attempted to scroll.
*
* <p>Any Behavior associated with the direct child of the CoordinatorLayout may elect
* to accept the nested scroll as part of {@link #onStartNestedScroll}. Each Behavior
* that returned true will receive subsequent nested scroll events for that nested scroll.
* </p>
*
* <p><code>onNestedScroll</code> is called each time the nested scroll is updated by the
* nested scrolling child, with both consumed and unconsumed components of the scroll
* supplied in pixels. <em>Each Behavior responding to the nested scroll will receive the
* same values.</em>
* </p>
*
* @param coordinatorLayout the CoordinatorLayout parent of the view this Behavior is
* associated with
* @param child the child view of the CoordinatorLayout this Behavior is associated with
* @param target the descendant view of the CoordinatorLayout performing the nested scroll
* @param dxConsumed horizontal pixels consumed by the target's own scrolling operation
* @param dyConsumed vertical pixels consumed by the target's own scrolling operation
* @param dxUnconsumed horizontal pixels not consumed by the target's own scrolling
* operation, but requested by the user
* @param dyUnconsumed vertical pixels not consumed by the target's own scrolling operation,
* but requested by the user
* @param type the type of input which cause this scroll event
*
* @see NestedScrollingParent2#onNestedScroll(View, int, int, int, int, int)
*/
这好像是在逗我?我也看不懂,大概意思就是 这个函数在 scroll 的时候就会更新
可是并没有
解决办法:
@Override
public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,
@NonNull FloatingActionButton child,
@NonNull View target,
int dxConsumed,
int dyConsumed,
int dxUnconsumed,
int dyUnconsumed,
int type) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type);
if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) {
child.hide(new FloatingActionButton.OnVisibilityChangedListener() {
@Override
public void onShown(FloatingActionButton fab) {
super.onShown(fab);
}
@Override
public void onHidden(FloatingActionButton fab) {
super.onHidden(fab);
fab.setVisibility(View.INVISIBLE);
}
});
} else if (dyConsumed <= 0 && child.getVisibility() != View.VISIBLE) {
child.show();
}
}
跟上面的区别就是 hide 的时候 别把 FAB visibility 变成GONE,而是变成 INVISIBLE
GONE 与 INVISIBLE 的区别就不说了。
为什么会发生这种情况呢?
道听途说:FAB都GONE 掉了,就不跟踪Scroll状态了,所以也就没有 onNestedScroll() 什么事,但是INVISIBLE 就不同了,会很勤奋地做这件事情,虽然看不见。
comments powered by Disqus