使用Google Design Library如何在向下滚动时隐藏FAB按钮?

时间:2015-08-16 18:09:01

标签: android material-design android-design-library floating-action-button

Google发布了设计库,我正在使用

 compile 'com.android.support:design:22.2.1'

但是,我无法看到如何使用此库的任何代码示例以及如何在滚动时为FAB栏设置动画。我想我可以在ListView上监听滚动事件,然后自己动画按钮,但是这不是API(这不是这个支持库的重点)。

有这方面的例子吗?

9 个答案:

答案 0 :(得分:92)

如果你正在使用RecyclerView而你正在寻找简单的东西,你可以试试这个:

    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy){
            if (dy > 0)
                fabAddNew.hide();
            else if (dy < 0)
                fabAddNew.show();
        }
    });

通过用常量替换0,您可以调整触发的灵敏度,提供更流畅的体验

答案 1 :(得分:45)

使用自定义CoordinatorLayout.Behavior可以轻松完成组件对滚动事件的反应,因为当您覆盖onStartNestedScroll()时,它们会自动接收滚动事件。

隐藏并显示此FABAwareScrollingViewBehavior中找到的FAB的行为示例,构建于cheesesquare之上:

public class FABAwareScrollingViewBehavior
    extends AppBarLayout.ScrollingViewBehavior {
  public FABAwareScrollingViewBehavior(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  @Override
  public boolean layoutDependsOn(CoordinatorLayout parent,
      View child, View dependency) {
    return super.layoutDependsOn(parent, child, dependency) ||
            dependency instanceof FloatingActionButton;
  }

  @Override
  public boolean onStartNestedScroll(
      final CoordinatorLayout coordinatorLayout, final View 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 View 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) {
      // User scrolled down -> hide the FAB
      List<View> dependencies = coordinatorLayout.getDependencies(child);
      for (View view : dependencies) {
        if (view instanceof FloatingActionButton) {
          ((FloatingActionButton) view).hide();
        }
      }
    } else if (dyConsumed < 0) {
      // User scrolled up -> show the FAB
      List<View> dependencies = coordinatorLayout.getDependencies(child);
      for (View view : dependencies) {
        if (view instanceof FloatingActionButton) {
          ((FloatingActionButton) view).show();
        }
      }
    }
  }
}

滚动视图的位置为app:layout_behavior="com.support.android.designlibdemo.FABAwareScrollingViewBehavior",而不是app:layout_behavior="@string/appbar_scrolling_view_behavior"

但是,如果您愿意,可以将hide()show()替换为任何操作。有关如何完成此操作的详细信息,请参阅this post以及follow up post for v22.2.1follow up post for v25.1.0

请注意,与设计库的所有滚动行为一样,此视图要求您的视图支持嵌套滚动,目前限制为NestedScrollViewRecyclerView - ListView和{{1仅适用于API21 +设备。

答案 2 :(得分:7)

如果你使用RecycleView(也就是常规的 ScrollView ),这将解决问题:

var qty = document.getElementById("quantity_value").textContent;

不要忘记宣布:

shuf -i 1-80000 -n 1
在你的课堂里。

答案 3 :(得分:2)

使用CoordinatorLayout是最好的方法。 但是,如果您想将侦听器附加到ListView或RecyclerView,您也可以这样做。 我认为更可定制。 这是我在git hub上的例子。

Github Project: Hide FAB(material Library) with listview

enter image description here

答案 4 :(得分:2)

recyclerView.setOnFlingListener(new RecyclerView.OnFlingListener() {
    @Override
    public boolean onFling(int velocityX, int velocityY) {
        if (velocityY < 0)
            mScrollCallbacks.showUI();
            //Code to hide the UI, I have  a custom one that slides down the nav  bar and the fab
        else if (velocityY > 0)
            mScrollCallbacks.hideUI();
            //Code to show the UI

        return false;
    }
});

这非常有效

答案 5 :(得分:2)

minDate

这对我来说很有效,FAB 和 RecyclerView 都是 Coordinator 上的直接子节点。

答案 6 :(得分:1)

@ianhanniballake工作正常但方法onStartNestedScroll()onNestedScroll()已被弃用。这是更新版本:

public class FabAwareScrollingViewBehavior extends AppBarLayout.ScrollingViewBehavior {

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

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) {
        return super.layoutDependsOn(parent, child, dependency) ||
                dependency instanceof FloatingActionButton;
    }

    @Override
    public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,
                                       @NonNull View 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, type);
    }

    @Override
    public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout,
                                  @NonNull View child, @NonNull View target, int dx, int dy,
                                  @NonNull int[] consumed, int type) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);

        if (dy > 0) {
            // User scrolled down -> hide the FAB
            List<View> dependencies = coordinatorLayout.getDependencies(child);
            for (View view : dependencies) {
                if (view instanceof FloatingActionButton) {
                    ((FloatingActionButton) view).hide();
                }
            }
        } else if (dy < 0) {
            // User scrolled up -> show the FAB
            List<View> dependencies = coordinatorLayout.getDependencies(child);
            for (View view : dependencies) {
                if (view instanceof FloatingActionButton) {
                    ((FloatingActionButton) view).show();
                }
            }
        }
    }
}

@ianhanniballake也有一篇关于这个主题的非常好的帖子:Intercepting everything with CoordinatorLayout Behaviors

答案 7 :(得分:1)

onScrollStateChanged而不是onScrolled上尝试:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        }

        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            if (newState == RecyclerView.SCROLL_STATE_IDLE)
                fab.show();
            else
                fab.hide();
            super.onScrollStateChanged(recyclerView, newState);
        }

答案 8 :(得分:0)

我所做的是:

mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener(){

          @Override
          public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
              if (dy>0){
                fab.hide();
              }else if (dy == 0){

                  fab.show();
              }else{
                  fab.show();
              }
          }

          @Override
          public void onScrollStateChanged(RecyclerView recyclerView, int newState) {

              super.onScrollStateChanged(recyclerView, newState);
          }
      });

让我知道它是否也适用于您。