【问题标题】:Floating action button not visible on scrolling after updating Google Support & Design Library更新 Google 支持和设计库后,浮动操作按钮在滚动时不可见
【发布时间】:2016-12-14 22:52:25
【问题描述】:

我尝试将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>

【问题讨论】:

    标签: android android-appcompat


    【解决方案1】:

    从支持库25.0.1 更新到25.1.0 会更改CoordinatorLayoutonNestedScroll 方法,因为对于可见性设置为View.GONE 的视图会跳过调用。

    在浮动操作按钮上调用 child.hide() 会将视图的可见性设置为 View.GONE,这意味着现在(从 25.1.0 开始),将来会为浮动操作按钮跳过 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);
                }
            });
    

    在您的 onNestedScroll 方法中。

    编辑:此问题已提交至 AOSP 问题跟踪器https://code.google.com/p/android/issues/detail?id=230298

    【讨论】:

    • 先生,您救了我的工作。谢谢!
    • 哇,这太疯狂了!我们发现更新到 25.1.1' 时出现同样的问题,感谢您的建议。
    • 在覆盖方法中看起来像是一个错字。我想应该是super.onHidden(fab)
    • 它就像一个魅力。这是一个支持 Snackbar 的 C# 版本:gist.github.com/xleon/2249aba606f5258957af505153ca91f3
    • 天哪!自从我上次使用相同的代码以来,我已经浪费了几个小时思考出了什么问题,在版本升级后它就不起作用了!谢谢,像魅力一样工作!但是这个bug很烦人!
    【解决方案2】:

    在 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;
    
            }
    

    【讨论】:

    • 在我的ActivityonCreate() 中,我确实在FloatingActionButton 上调用hide(),以便它开始隐藏然后出现在滚动时(通过定义的行为)。调用hide() 是否将其可见性设置为GONE 并且您的代码 sn-p 是否暗示浮动操作按钮因此在滚动事件期间被永远忽略?确定不是?
    【解决方案3】:

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

    触发FAB可见性变化的一定是RecyclerView(行为)。

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

    下面是一个差异链接,其中显示了执行升级所需的更改:

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

    【讨论】:

      猜你喜欢
      • 2015-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-01
      • 2015-08-11
      • 2020-01-02
      相关资源
      最近更新 更多