更新Google支持后,浮动操作按钮在滚动时不可见设计图书馆

时间:2016-12-14 22:52:26

标签: android android-appcompat

我尝试将com.android.support:appcompatcom.android.support:design从25.0.1更新为25.1.0,如下所示:

compile 'com.android.support:appcompat-v7:25.0.1'
compile 'com.android.support:design:25.0.1'

为:

compile 'com.android.support:appcompat-v7:25.1.0'
compile 'com.android.support:design:25.1.0'

但是我发现当活动滚动时我的浮动操作按钮不再出现。我的FAB行为由以下定义:

public class MyFabBehavior extends FloatingActionButton.Behavior {

    public MyFabBehavior(Context context, AttributeSet attrs) {
        super();
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout,
                                       FloatingActionButton child, View directTargetChild, View target, int nestedScrollAxes) {

        // Ensure we react to vertical scrolling
        return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
                || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);

    }

    @Override
    public void onNestedScroll(CoordinatorLayout coordinatorLayout, FloatingActionButton child,
                               View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {

        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
        if (dyConsumed < 0) {
            // User scrolled up -> hide the FAB
            animateFab(child, View.GONE);
        } else if (dyConsumed > 0) {
            // User scrolled down -> show the FAB
            animateFab(child, View.VISIBLE);
        }
    }

    static public void animateFab(FloatingActionButton fab, int visibility) {
        // ignore visibility passed in, and just make fab visible regardless
        if (fab.getVisibility() != View.VISIBLE) {
            fab.show();
        }
    }
}

我的布局如下:

<android.support.design.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"  >

    <android.support.v4.widget.NestedScrollView
        android:id="@+id/main_scrollview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="8dp" >

        ...

    </android.support.v4.widget.NestedScrollView>

    <android.support.design.widget.FloatingActionButton
        app:layout_behavior="com.example.MyFabBehavior"
        android:id="@+id/fab"
        app:fabSize="normal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_marginBottom="@dimen/fab_margin"
        android:layout_marginRight="@dimen/fab_margin"
        android:onClick="saveButton"
        app:elevation="6dp"
        app:pressedTranslationZ="12dp"
        app:backgroundTint="@color/colorPrimary"
        android:src="@drawable/ic_done_white_24dp" />

</android.support.design.widget.CoordinatorLayout>

3 个答案:

答案 0 :(得分:57)

从支持列表25.0.1更新为25.1.0会更改onNestedScroll的{​​{1}}方法,因为对于其可见性设置为CoordinatorLayout的视图,会跳过该调用

在浮动操作按钮上调用View.GONE可将视图的可见性设置为child.hide(),这意味着现在(截至25.1.0),View.GONE方法调用将是将来跳过浮动操作按钮(因为它会跳过所有可见性为onNestedScroll的视图。)

解决此问题的方法是在隐藏视图时将视图的可见性设置为GONE。这样,INVISIBLE下次执行嵌套滚动时不会跳过视图。

为了实现这一目标,您可以致电

onNestedScroll

child.hide(new FloatingActionButton.OnVisibilityChangedListener() { /** * Called when a FloatingActionButton has been hidden * * @param fab the FloatingActionButton that was hidden. */ @Override public void onHidden(FloatingActionButton fab) { super.onShown(fab); fab.setVisibility(View.INVISIBLE); } }); 方法中。

编辑:此问题已在https://code.google.com/p/android/issues/detail?id=230298

提交给AOSP问题跟踪器

答案 1 :(得分:1)

在CoordinatorLayout 25.1.0(

   for (int i = 0; i < childCount; i++) {
            final View view = getChildAt(i);
            if (view.getVisibility() == GONE) {
                // If the child is GONE, skip...
                continue;
            }

在25.0.1

for (int i = 0; i < childCount; i++) {
            final View view = getChildAt(i);
            final LayoutParams lp = (LayoutParams) view.getLayoutParams();
            if (!lp.isNestedScrollAccepted()) {
                continue;
            }

            final Behavior viewBehavior = lp.getBehavior();
            if (viewBehavior != null) {
                viewBehavior.onNestedScroll(this, view, target, dxConsumed, dyConsumed,
                        dxUnconsumed, dyUnconsumed);
                accepted = true;

        }

答案 2 :(得分:0)

自支持lib版本25.1.0以来,行为已发生变化。

必须是RecyclerView(行为)才能触发FAB可见性更改。

换句话说,它不再是想要对行为做出反应的对象的责任,而是对要移动以了解屏幕上所有内容的对象的责任。

以下是diff的链接,其中显示了执行升级所需的更改:

https://github.com/chrisbanes/cheesesquare/compare/master...ianhanniballake:scroll_aware_fab