FloatingActionButton 上滚动隐藏效果

FloatingActionButton on scroll down hidden effect

我试图让 floatingActionButton 在向下滚动时隐藏并在向上滚动时再次显示,我使用 setOnScrollChangeListener 让 ScrollView 做到这一点

XML

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".DetailsActivity"
    android:orientation="vertical">

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_anchor="@id/linearLayout"
        app:layout_anchorGravity="start|bottom"
        android:layout_margin="16dp"
        android:src="@drawable/icons8_share_480"
        />

代码

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
        @Override
        public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            if (scrollY > 0 && fab.isShown()) {
                fab.setVisibility(View.GONE);
            } else if (scrollY < 0) {
                fab.setVisibility(View.VISIBLE);

            }
        }
    });
} else {
    scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {
            int mScrollY = scrollView.getScrollY();
            if (mScrollY > 0 && fab.isShown()) {
                fab.setVisibility(View.GONE);
            } else if (mScrollY < 0) {
                fab.setVisibility(View.VISIBLE);
            }
        }
    });
}

the result
似乎有效,但有时会出现两个问题,当向上滚动 fab 时不出现,其次它直接消失而没有任何效果在这个 GIF 中更加清晰 Destination

问题是因为你从顶部滚动到底部后它确实会被隐藏但是它不知道你什么时候滚动到顶部因为你的mScrollY < 0在位置上并不真正小于0。尝试使用从这个代码,它可以给出旧位置和新位置然后你可以比较它所以它会知道你什么时候开始滚动到顶部或底部

这是link:

感谢@JEFF,在监控 OnScrollChangeListener 后,我将条件值更改为
scrollY < 22,它又出现了。
关于第二个问题,我搜索了如何制作动画,我发现有两种方法可以做到这一点

首先是使用fab.hidefab.show代替方法setVisibility();

编辑后的代码

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    scrollView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
        //   Log.d("ScrollView","scrollX_"+scrollX+"_scrollY_"+scrollY+"_oldScrollX_"+oldScrollX+"_oldScrollY_"+oldScrollY);
        if (scrollY > 0 && fab.isShown()) {
            fab.hide();
        } else if (scrollY < 22) {
            fab.show();

        }
    });
} else {
    scrollView.getViewTreeObserver().addOnScrollChangedListener(() -> {
        int mScrollY = scrollView.getScrollY();
        if (mScrollY > 0 && fab.isShown()) {
            fab.hide();
        } else if (mScrollY < 22) {
            fab.show();
        }
    });
}

第二种方式 是使用自定义比例动画向上、向下滚动,像这样

fbListFood = findViewById(R.id.fbListFood);
scrollView = findViewById(R.id.scrollView);


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

    scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
        @Override
        public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
            if (scrollY > 0 && fbListFood.isShown()) {
                fbListFood.hide();
            } else if (scrollY < 22) {
                fbListFood.show();

            }
        }
    });
} else {
    

    scrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {
            int mScrollY = scrollView.getScrollY();
            if (mScrollY > 0 && fbListFood.isShown()) {
                fbListFood.hide();
            } else if (mScrollY < 22) {
                fbListFood.show();
            }
        }
    });
}