Android 使用谷歌设计库如何在向下滚动时隐藏FAB按钮?

Android 使用谷歌设计库如何在向下滚动时隐藏FAB按钮?,android,material-design,android-design-library,floating-action-button,Android,Material Design,Android Design Library,Floating Action Button,谷歌已经发布了设计库,我正在使用 compile 'com.android.support:design:22.2.1' 但是,我看不到任何关于如何使用此库以及如何在滚动条上设置FAB条动画的代码示例。我想我可以在ListView上监听滚动事件,然后自己制作按钮的动画,但这是否没有被烘焙到API中(这不是此支持库的重点) 有这样的例子吗?让组件对滚动事件做出反应最容易通过自定义来完成,因为它们在您重写时会自动接收滚动事件 一个隐藏和显示此卷中的FAB on scroll的示例行为,构建在以下

谷歌已经发布了设计库,我正在使用

 compile 'com.android.support:design:22.2.1'
但是,我看不到任何关于如何使用此库以及如何在滚动条上设置
FAB
条动画的代码示例。我想我可以在
ListView
上监听滚动事件,然后自己制作按钮的动画,但这是否没有被烘焙到API中(这不是此支持库的重点)


有这样的例子吗?

让组件对滚动事件做出反应最容易通过自定义来完成,因为它们在您重写时会自动接收滚动事件

一个隐藏和显示此卷中的FAB on scroll的示例行为,构建在以下内容之上:

公共类FABAwareScrollingViewBehavior
扩展AppBarLayout.ScrollingViewBehavior{
公共FABAwareScrollingViewBehavior(上下文、属性集属性){
超级(上下文,attrs);
}
@凌驾
公共布尔layoutDependsOn(协调布局父对象,
查看子项,查看依赖项){
返回super.layoutDependsOn(父、子、依赖项)||
FloatingActionButton的依赖实例;
}
@凌驾
公共布尔值onStartNestedScroll(
最终坐标布局坐标布局,最终视图子对象,
最终视图directTargetChild,最终视图目标,
最终整数嵌套滚动轴){
//确保我们对垂直滚动做出反应
返回NestedScrollAxis==ViewCompat.SCROLL\u AXIS\u VERTICAL
||super.OnStartedScroll(坐标布局,孩子,
directTargetChild、target、nestedScrollAxes);
}
@凌驾
公共图书馆(
最终坐标布局坐标布局,最终视图子对象,
最终视图目标,最终消耗的整数dx,最终消耗的整数dy,
最终整数dx未使用,最终整数dy未使用){
super.onNestedScroll(协调人布局、儿童、目标、,
dxConsumed,dyConsumed,dxUnconsumed,dyUnconsumed);
如果(动态消耗>0){
//用户向下滚动->隐藏晶圆厂
List dependencies=coordinatorLayout.getDependencies(子级);
对于(视图:依赖项){
if(查看浮动操作按钮的实例){
((FloatingActionButton)视图).hide();
}
}
}否则如果(消耗的能量小于0){
//用户向上滚动->显示晶圆厂
List dependencies=coordinatorLayout.getDependencies(子级);
对于(视图:依赖项){
if(查看浮动操作按钮的实例){
((FloatingActionButton)视图).show();
}
}
}
}
}
您的滚动视图将具有
app:layout\u behavior=“com.support.android.designlibdemo.FABAwareScrollingViewBehavior”
而不是
app:layout\u behavior=“@string/appbar\u scrolling\u view\u behavior”

但是,如果需要,可以使用任何操作替换
hide()
show()
。有关如何执行此操作的详细信息,请参见和


请注意,这与设计库的所有滚动行为一样,要求您的视图支持嵌套滚动,这目前将您限制为,-
ListView
ScrollView
仅在API21+设备上工作。

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


如果您使用的是
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();
        }
    });
recyclerView.addOnScrollListener(新的recyclerView.OnScrollListener(){
@凌驾
已填空的公共空间(RecyclerView RecyclerView、int dx、int dy){
如果(dy>0)
fabAddNew.hide();
else if(dy<0)
fabAddNew.show();
}
});

通过将
0
替换为常数,您可以调整触发的灵敏度,提供更平滑的体验@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();
                }
            }
        }
    }
}
公共类FabaWarRescrollingViewBehavior扩展了AppBarLayout.ScrollingViewBehavior{
公共FabAwareScrollingViewBehavior(上下文、属性集属性){
超级(上下文,attrs);
}
@凌驾
公共布尔布局依赖项(协调布局父项、视图子项、视图依赖项){
返回super.layoutDependsOn(父、子、依赖项)||
FloatingActionButton的依赖实例;
}
@凌驾
公共布尔值onStartNestedScroll(@NonNull CoordinatorLayout CoordinatorLayout,
@非Null视图子级@NonNull视图directTargetChild,
@非空视图目标,整数轴,整数类型){
//确保我们对垂直滚动做出反应
返回轴==viewcompt.SCROLL\u轴\u垂直||
super.onStartNestedScroll(坐标布局、子对象、directTargetChild、目标、轴、类型);
}
@凌驾
公共无效onNestedPreScroll(@NonNull CoordinatorLayout CoordinatorLayout,
@非空视图子级,@NonNull视图目标,int-dx,int-dy,
@非空int[]已使用,int类型){
super.onNestedPreScroll(协调布局、子项、目标、dx、dy、消耗、类型);
如果(dy>0){
//用户向下滚动->隐藏晶圆厂
List dependencies=coordinatorLayout.getDependencies(子级);
对于(视图:依赖项){
if(查看浮动操作按钮的实例){
((FloatingActionButton)视图).hide();
}
}
}else if(dy<0){
//用户向上滚动->显示晶圆厂
List dependencies=coordinatorLayout.getDependencies(子级);
对于(视图:depende
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();
                }
            }
        }
    }
}
mScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {
            if (mScrollView.getScrollY() > oldScrollYPostion) {
                fab.hide();
            } else if (mScrollView.getScrollY() < oldScrollYPostion || mScrollView.getScrollY() <= 0) {
                fab.show();
            }
            oldScrollYPostion = mScrollView.getScrollY();
        }
    });
private int oldScrollYPostion = 0;
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;
    }
});
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);
        }
          @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);
          }
      });
app:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"
app:layout_anchor="@id/recyclerList"
app:layout_anchorGravity="bottom"