代码之家  ›  专栏  ›  技术社区  ›  user4546546

滚动时在NestedScrollView中隐藏FAB

  •  16
  • user4546546  · 技术社区  · 10 年前

    我有一个嵌套的滚动视图,内容像一些线性布局和文本视图。 我使用浮动操作按钮库也是出于一些原因。所以我不能用任何行为来解释。 我不知道应该如何处理scrollview中的scrollchangelistener,以便像行为一样动态地隐藏和显示fab。

    有什么建议可以在滚动时隐藏和显示fab?

    5 回复  |  直到 9 年前
        1
  •  39
  •   Henrique Monte    8 年前

    简单地将以下代码添加到NestedScrollView ScrollChangeListener中:

    NestedScrollView nsv = v.findViewById(R.id.nsv);
        nsv.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
            @Override
            public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
                if (scrollY > oldScrollY) {
                    fab.hide();
                } else {
                    fab.show();
                }
            }
        });
    
        2
  •  12
  •   Tigran Sarkisian    10 年前

    创建FabScrollBehavior类

    public class FabScrollBehavior extends CoordinatorLayout.Behavior<FloatingActionButton> {
        private int toolbarHeight;
    
        public FabScrollBehavior(Context context, AttributeSet attrs) {
            super(context, attrs);
            this.toolbarHeight = AppUtil.getToolbarHeight(context);
        }
    
        @Override
        public boolean layoutDependsOn(CoordinatorLayout parent, FloatingActionButton fab, View dependency) {
            return dependency instanceof AppBarLayout;
        }
    
        @Override
        public boolean onDependentViewChanged(CoordinatorLayout parent, FloatingActionButton fab, View dependency) {
            if (dependency instanceof AppBarLayout) {
                CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams();
                int fabBottomMargin = lp.bottomMargin;
                int distanceToScroll = fab.getHeight() + fabBottomMargin;
                float ratio = (float)dependency.getY()/(float)toolbarHeight;
                fab.setTranslationY(-distanceToScroll * ratio);
            }
            return true;
        }
    }
    

    其中AppUtil。getToolbarHeight(上下文)为-

    public static int getToolbarHeight(Context context) {
            final TypedArray styledAttributes = context.getTheme().obtainStyledAttributes(
                    new int[]{R.attr.actionBarSize});
            int toolbarHeight = (int) styledAttributes.getDimension(0, 0);
            styledAttributes.recycle();
    
            return toolbarHeight;
        }
    

    然后在布局中添加FloatingActionButton layout_behavior:

       <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab_task_accept"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end|bottom"
            android:layout_margin="@dimen/fab_margin"
            android:src="@drawable/ic_accepted"
            app:layout_behavior="pass.to.your.FabScrollBehavior.Class"
            app:theme="@style/Widget.AppTheme.Fab"/>
    

    整个布局看起来像

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true"
        android:orientation="vertical">
    
        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/Widget.AppTheme.AppBarOverlay">
    
            <include
                layout="@layout/include_layout_toolbar_scroll"/>
    
        </android.support.design.widget.AppBarLayout>
    
    
        <include layout="@layout/include_layout_content_with_nestedscroll"/>
    
        <android.support.design.widget.FloatingActionButton
            android:id="@+id/fab_task_accept"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="end|bottom"
            android:layout_margin="@dimen/fab_margin"
            android:src="@drawable/ic_accepted"
            app:layout_behavior="pass.to.FabScrollBehavior.Class"
            app:theme="@style/Widget.AppTheme.Fab"/>
    
    
    </android.support.design.widget.CoordinatorLayout>
    

    实施日期: https://mzgreen.github.io/2015/02/15/How-to-hideshow-Toolbar-when-list-is-scroling(part1)/

        3
  •  3
  •   yousef    8 年前

    在“活动”或片段中定义变量类型int,以从ScrollView设置上一个Scroll,然后使用此方法在ScrollViewClass中侦听更改滚动

     scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
            @Override
            public void onScrollChanged() {
    
        // previousScrollY this variable is define in your Activity or Fragment
                if (scrollView.getScrollY() > previousScrollY && floatingActionButton.getVisibility() == View.VISIBLE) {
                    floatingActionButton.hide();
                } else if (scrollView.getScrollY() < previousScrollY && floatingActionButton.getVisibility() != View.VISIBLE) {
                    floatingActionButton.show();
                }
                previousScrollY = scrollView.getScrollY();
            }
        });
    

    将完成所有版本的android

        4
  •  2
  •   Jay Thummar    6 年前

    花了这么长时间后,我找到了解决办法。 它可能适用于所有情况。虽然这是一个黑客不是正确的解决方案,但你可以应用它来让这件事发生。

    正如我们所知 setOnScrollChangeListener 只有当最小api为23时才有效,所以如果我的最小api级别小于23怎么办。

    所以我从堆栈溢出中找到了我们可以使用的解决方案 getViewTreeObserver().addOnScrollChangedListener 因此,这将是所有设备的兼容解决方案。

    现在,让我们转到问题的最终解决方案“嵌套滚动视图滚动时隐藏fab按钮,嵌套滚动视图处于理想状态时显示fab按钮”

    因此,我们可以使用 Handler 具有 postDelayed 解决这个问题。

    1. 在上下文中定义变量 private int previousScrollY = 0;

    2. 然后使用 getViewTreeObserver().addOnScrollChangedListener 像这样添加到嵌套滚动视图中。

    NESTEDSCROLLVIEW.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() { @Override public void onScrollChanged() { new Handler().postDelayed(new Runnable() { @Override public void run() { if (NESTEDSCROLLVIEW.getScrollY() == previousScrollY) { FABBUTTON.setVisibility(View.VISIBLE); } else { FABBUTTON.setVisibility(View.INVISIBLE); } } }, 10); previousScrollY = NESTEDSCROLLVIEW.getScrollY(); } });

    1. 现在你准备好了。。。。
        5
  •  0
  •   JAY_Panchal    4 年前

    滚动时,可以使用此侦听器来观察和隐藏FAB。

       nestedScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
                    @Override
                    public void onScrollChanged() {
                        if (nestedScrollView != null) {
                            if (nestedScrollView.getChildAt(0).getBottom() <= (nestedScrollView.getHeight() + nestedScrollView.getScrollY())) {
                                fab.setVisibility(View.INVISIBLE);
                            } else {
                                fab.setVisibility(View.VISIBLE);
                            }
                        }
                    }
                });