浮动操作按钮滚动奇怪的行为

Posted

技术标签:

【中文标题】浮动操作按钮滚动奇怪的行为【英文标题】:Floating Action Button Scroll weird behavior 【发布时间】:2016-12-05 23:18:19 【问题描述】:

我有一个FloatingActionButton,它实现了一种在向下滚动时隐藏它并在向上滚动时显示它的行为。

但是,有时当我向上滚动时,它会自行隐藏,然后再次出现。根据我的代码,这是无法理解的,因为它应该只在向下滚动时隐藏。

也许它与我也在滚动的CollapsingToolbar 相关联?

这是我的布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 
   xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:layout_gravity="right"
    android:focusableInTouchMode="true"
    android:clickable="true"
    android:layoutDirection="rtl"
    android:fitsSystemWindows="true"
    android:id="@+id/drawer_layout">
  <android.support.design.widget.CoordinatorLayout
      android:id="@+id/mainCoordinatorLayout"
      android:layout_
      android:layout_
      android:fitsSystemWindows="true"
      android:layoutDirection="rtl"
      android:background="#EEEEEE"
      android:clickable="true">
    <android.support.design.widget.AppBarLayout
        android:layout_
        android:layout_
        android:fitsSystemWindows="true"
        android:id="@+id/toolbar_layout">
      <android.support.design.widget.CollapsingToolbarLayout
          android:id="@+id/collapsing_toolbar"
          android:layout_
          android:layout_
          android:fitsSystemWindows="true"
          app:layout_scrollFlags="scroll|exitUntilCollapsed"
          app:contentScrim="?attr/colorPrimary"
          app:collapsedTitleGravity="right|top"
          app:expandedTitleGravity="bottom|right"
          app:expandedTitleMarginBottom="64dp"
          app:collapsedTitleTextAppearance="@style/CollapsedTitleTextAppearance"
          app:expandedTitleTextAppearance="@style/ExpandedTitleTextAppearance"
          app:expandedTitleMarginEnd="0dp"
          app:expandedTitleMarginStart="30dp">
        <ImageView
            android:id="@+id/headerImage"
            android:layout_
            android:layout_
            android:fitsSystemWindows="true"
            android:scaleType="centerCrop"
            app:layout_collapseMode="parallax"
            android:background="@drawable/soldier" />
        <View
            android:fitsSystemWindows="true"
            android:layout_
            android:layout_
            android:background="@drawable/scrim_top"
            app:layout_collapseMode="pin" />
        <View
            android:fitsSystemWindows="true"
            android:layout_
            android:layout_
            android:layout_gravity="bottom"
            android:layout_alignBottom="@+id/headerImage"
            android:background="@drawable/scrim_bottom" />
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_
            android:layout_
            android:gravity="top"
            app:titleTextColor="@color/White"
            android:layout_gravity="right"
            android:layoutDirection="rtl"
             app:layout_scrollFlags="scroll|enterAlways"
            app:layout_collapseMode="pin"
            app:contentScrim="?attr/colorPrimary"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:titleMarginTop="15dp" />
        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_
            android:layout_
            android:layout_gravity="bottom"
            app:tabIndicatorHeight="3dp"
            android:layoutDirection="ltr"
            app:tabIndicatorColor="@android:color/white"
            app:tabSelectedTextColor="@color/White"
            app:tabTextColor="@color/Black"
            style="@style/MyCustomTabLayout"
            app:tabMode="fixed"
            app:tabGravity="fill">
          <android.support.design.widget.TabItem
              android:icon="@drawable/ic_book_white_24px"
              android:text="ספרים" />
          <android.support.design.widget.TabItem
              android:icon="@drawable/soldierWhite"
              android:text="הלכות" />
          <android.support.design.widget.TabItem
              android:icon="@drawable/ic_home_white_24px"
              android:text="בית" />
        </android.support.design.widget.TabLayout>

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

    </android.support.design.widget.AppBarLayout>    
    <FrameLayout
        android:layout_
        android:layout_
        android:id="@+id/content_frame"
        android:visibility="gone"
        android:animateLayoutChanges="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:behavior_overlapTop="0dp">
    </FrameLayout>
    <android.support.v4.view.ViewPager
        android:id="@+id/mainPager"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:layout_
        android:layout_
        app:behavior_overlapTop="0dp"
        />
    <android.support.design.widget.FloatingActionButton
        android:id="@+id/mainFab"
        android:layout_
        android:layout_
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_gravity="bottom|end"
        android:layout_marginLeft="16dp"
        android:layout_marginBottom="16dp"
        android:layout_marginTop="5dp"
        android:elevation="8dp"
        app:layout_behavior="@string/fab_scroll_translation_autohide_behavior"
        app:pressedTranslationZ="12dp"
        app:backgroundTint="?android:colorAccent"
        android:src="@drawable/ic_perm_phone_msg_white_24px" />
    <LinearLayout
        android:id="@+id/miniFabFrame"
        android:focusableInTouchMode="true"
        android:orientation="vertical"
        android:layout_
        android:layout_
        android:visibility="invisible"
        android:layout_alignParentLeft="true"
        android:layout_gravity="bottom|end"
        android:layout_marginLeft="20dp"
        android:layout_marginBottom="80dp"
        android:padding="0dp">
      <android.support.design.widget.FloatingActionButton
          android:id="@+id/messageFab"
          android:layout_
          android:layout_
          android:layout_alignParentBottom="true"
          android:layout_alignParentLeft="true"
          android:elevation="8dp"
          android:layout_marginTop="5dp"
          android:layout_marginRight="0dp"
          android:layout_marginBottom="5dp"
          android:layout_marginLeft="5dp"
          app:pressedTranslationZ="12dp"
          app:backgroundTint="?android:colorPrimary"
          app:fabSize="mini"
          android:src="@drawable/ic_textSMS_white_24px" />
      <android.support.design.widget.FloatingActionButton
          android:id="@+id/callFab"
          android:layout_
          android:layout_
          android:layout_alignParentBottom="true"
          android:layout_alignParentLeft="true"
          android:layout_marginTop="5dp"
          android:layout_marginRight="0dp"
          android:layout_marginBottom="5dp"
          android:layout_marginLeft="5dp"
          android:elevation="8dp"
          app:pressedTranslationZ="12dp"
          app:backgroundTint="?android:colorPrimary"
          app:fabSize="mini"
          android:src="@drawable/ic_call_white_24px" />
    </LinearLayout>
  </android.support.design.widget.CoordinatorLayout>
  <android.support.design.widget.NavigationView
      android:layout_
      android:layout_
      android:layout_gravity="right"
      android:id="@+id/nav_view"
      android:layoutDirection="rtl"
      app:headerLayout="@layout/header"
      app:menu="@menu/nav_menu" />
</android.support.v4.widget.DrawerLayout>

这是我的行为:

[Register("ToratHamachane.ScrollAwareFABBehavior")]
public class ScrollAwareFABBehavior : CoordinatorLayout.Behavior

    public ScrollAwareFABBehavior(Context context, IAttributeSet attrs) : base(context, attrs)
    
    

    public override bool OnStartNestedScroll(CoordinatorLayout coordinatorLayout, Java.Lang.Object child, View directTargetChild, View target, int nestedScrollAxes)
    
        return nestedScrollAxes == ViewCompat.ScrollAxisVertical ||
                 base.OnStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
    

    public override void OnNestedScroll(CoordinatorLayout coordinatorLayout, Java.Lang.Object child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed)
    
        base.OnNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);

        var floatingActionButtonChild = child.JavaCast<FloatingActionButton>();

        if (dyConsumed > 0 && floatingActionButtonChild.Visibility == ViewStates.Visible)
            floatingActionButtonChild.Hide();
        else if (dyConsumed < 0 && floatingActionButtonChild.Visibility != ViewStates.Visible)
            floatingActionButtonChild.Show();

    

任何想法为什么会发生这种情况? 我会很感激任何帮助。

谢谢。

【问题讨论】:

【参考方案1】:

使用此调用设置浮动操作按钮的滚动行为。

public class ScrollAwareFabBehaviour extends FloatingActionButton.Behavior 

    public ScrollAwareFabBehaviour(Context context, AttributeSet attrs) 
        super();
    

    @Override
    public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,
                                       final View directTargetChild, final View target, final 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(final CoordinatorLayout coordinatorLayout, final FloatingActionButton child,
                               final View target, final int dxConsumed, final int dyConsumed,
                               final int dxUnconsumed, final int dyUnconsumed) 
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
        if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE) 
            // User scrolled down and the FAB is currently visible -> hide the FAB
            child.hide();
         else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE) 
            // User scrolled up and the FAB is currently not visible -> show the FAB
            child.show();
        
    


在您设计 FAB 的 xml 中设置其行为

<android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_add_note"
        android:layout_
        android:layout_
        android:layout_gravity="bottom|right"
        android:layout_margin="@dimen/fab_margin"
        android:clickable="true"
        android:src="@drawable/ic_add_white_24dp"
        app:backgroundTint="@color/blue_grey_accent_color"
        app:layout_anchor="@id/recycler_notes"
        app:layout_anchorGravity="bottom|right|end"
        app:layout_behavior="@string/fab_behaviour"
        app:rippleColor="#FFF" />

在 strings.xml 中像这样定义你的行为类

<string name="fab_behaviour">com.suman.swets.example.uiviews.ScrollAwareFabBehaviour</string>

【讨论】:

很抱歉,但这对我没有帮助。也许这在 Java 中有效,但我将 Xamarin 与 C# 一起使用,并且我上面发布的代码对我有用,尽管存在错误。【参考方案2】:

呼叫超级。

public ScrollAwareFABBehavior(Context context, IAttributeSet attrs) : base(context, attrs)
super();

如果这不能解决您的问题,请将行为添加到您的折叠工具栏。

你为什么这样做?

var floatingActionButtonChild = child.JavaCast<FloatingActionButton>();

您可以只使用子元素而不是 floatingActionButtonChild。

【讨论】:

对不起。但这不起作用。我正在使用 Xamarin,并且没有超级方法。等效的“基础”不起作用。将行为添加到折叠工具栏也不起作用。

以上是关于浮动操作按钮滚动奇怪的行为的主要内容,如果未能解决你的问题,请参考以下文章

奇怪的 chrome 媒体查询行为

如果浮动大小,奇怪的 UICollectionViewCell 行为

UIScrollView setContentOffset:动画:奇怪的行为

滚动 UITableView 的奇怪行为

UITableView 滚动时奇怪的布局行为变化

嵌套的scrollview + recyclerview,奇怪的自动滚动行为[重复]