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"