14

我有一个带有协调器布局的活动。内部活动有一个带有 Recycler 视图和浮动按钮的片段。我如何在 Scroll Recycler 视图时显示/隐藏浮动按钮并避免使用 fab 行为?!

在活动布局中:CoordinatorLayout----->AppBarLayout---->Toolbar and FrameLayout and Bottom bar view

在片段布局中:RelativeLayout---->Recycler view and float button

我想实现类似 Google+ 主页的东西。我该如何实现这个场景?


临时我用这个解决方案来解决我的问题:

在我的片段中通过接口使用活动的协调器布局并显示/隐藏具有 fab 行为的 fab ...直到我找到更好的解决方案!!!

4

5 回答 5

32

这段代码工作得很好:

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

                    super.onScrolled(recyclerView, dx, dy);
                }
            });

你不能这样做:

app:layout_anchor="@id/listView"
app:layout_anchorGravity="bottom|end"

这里

根据此 Google 帖子,没有内置的 CoordinatorLayout 支持与 ListView 一起使用。

于 2017-01-17T14:36:44.990 回答
6

我修改了 Leondro 的方法,使 FAB 在滚动时隐藏并在滚动停止时显示。

scrollListener = new RecyclerView.OnScrollListener() {  
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        switch (newState) {
            case RecyclerView.SCROLL_STATE_IDLE:
                fab.show();
                break;
            default:
                fab.hide();
                break;
        }
        super.onScrollStateChanged(recyclerView, newState);
    }
}; 

rv.clearOnScrollListeners();
rv.addOnScrollListener(scrollListener);
于 2017-03-23T03:59:34.033 回答
3

将此添加到 FAB :

应用程序:layout_behavior="@string/hide_bottom_view_on_scroll_behavior"

于 2020-12-23T16:06:47.467 回答
1

这是工作解决方案:

class HideOnScrollFabBehavior(context: Context?, attrs: AttributeSet?) : FloatingActionButton.Behavior() {

    // changes visibility from GONE to INVISIBLE when fab is hidden because
    // due to CoordinatorLayout.onStartNestedScroll() implementation
    // child view's (here, fab) onStartNestedScroll won't be called anymore
    // because it's visibility is GONE
    private val listener = object : FloatingActionButton.OnVisibilityChangedListener() {
        override fun onHidden(fab: FloatingActionButton?) {
            fab?.visibility = INVISIBLE
        }
    }

    override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout, child: FloatingActionButton, directTargetChild: View, target: View, axes: Int, type: Int): Boolean {
        return axes == ViewCompat.SCROLL_AXIS_VERTICAL // Ensure we react to vertical scrolling
                || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type)
    }

    override fun onNestedScroll(coordinatorLayout: CoordinatorLayout, child: FloatingActionButton, target: View, dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int, type: Int, consumed: IntArray) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type, consumed)
        if (!target.canScrollVertically(1) && dyConsumed > 0 && child.visibility == VISIBLE) {
            // hide the FAB when scroll view reached its bottom
            child.hide(listener)
        } else if (dyConsumed < 0 && child.visibility != VISIBLE) {
            // show the FAB on scroll up
            child.show()
        }
    }

}
于 2020-11-12T15:52:54.833 回答
1

Kotlin 中的解决方案

recycler_view = findViewById(R.id.recycler_view)

        recycler_view.addOnScrollListener(object : RecyclerView.OnScrollListener(){
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                if(dy > 0){
                    fab.hide();
                } else{
                    fab.show();
                }
                super.onScrolled(recyclerView, dx, dy)

            }
        })
于 2020-12-28T09:53:42.977 回答