【问题标题】:Vertical Scrolling CoordinatorLayout Behavior for BottomNavigationView with RecyclerView vertical scrolling使用 RecyclerView 垂直滚动的 BottomNavigationView 的垂直滚动 CoordinatorLayout 行为
【发布时间】:2017-04-06 05:24:59
【问题描述】:

如何为BottomNavigationView 定义一个CoordinatorLayout.Behavior 类,该类的滚动与 RecyclerView 垂直滚动同步。

我见过thisthis,但它所做的只是立即在垂直滚动事件上显示/隐藏NavigationView。我不想立即显示/隐藏NavigationView,而是我想要一个类似于AppbarLayout 的行为,它有一个Toolbar,滚动标志为app:layout_scrollFlags="scroll|enterAlways"

 public class BottomNavigationBehavior extends CoordinatorLayout.Behavior<BottomNavigationView> {

    public BottomNavigationBehavior() {
        super();
    }

    public BottomNavigationBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, BottomNavigationView child, View dependency) {
        boolean dependsOn = dependency instanceof FrameLayout;
        return dependsOn;
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, BottomNavigationView child, View directTargetChild, View target, int nestedScrollAxes) {
        return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, BottomNavigationView child, View target, int dx, int dy, int[] consumed) {
        if(dy < 0) {
            showBottomNavigationView(child);
        }
        else if(dy > 0) {
            hideBottomNavigationView(child);
        }
    }

    private void hideBottomNavigationView(BottomNavigationView view) {
        view.animate().translationY(view.getHeight());
    }

    private void showBottomNavigationView(BottomNavigationView view) {
        view.animate().translationY(0);
    }
}

【问题讨论】:

  • 我会尝试设置对 appbarlayout 的依赖,并根据 appbarlayout 的高度变化移动 BottomNavigationBar
  • 我的意思是,我想实现一个布局行为,就像响应 RecyclerView 滚动事件的 appbar 布局行为一样
  • 所以慢慢地使用回收站视图而不是不显示它?
  • 是的,没错。带有带有“scroll|enterAlways”标志的工具栏的 Appbarlayout 就是这种滚动的一个示例。

标签: android android-coordinatorlayout android-design-library android-bottom-nav-view


【解决方案1】:

经过一番尝试,我想出了这个解决方案:

  recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                    if(dy > 0 && visible){
                        mBinding.bnv.test.setY(mBinding.bnv.getY() + dy);
                        DisplayMetrics metrics = new DisplayMetrics();
                        getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
                        visible = mBiding.bnv.getY() > metrics.heightPixels;
                        if(!visible) {
                            mBinding.bnv.setY(metrics.heightPixels);
                        }
                    } else {
                        mBinding.bnv.setY(mBinding.bnv.getY() + dy);
                        DisplayMetrics metrics = new DisplayMetrics();
                        getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
                        visible = mBinding.bnv.getY() > metrics.heightPixels;
                    }
        }

所以你正在使用回收器视图滚动 BottomNavigationView

或者用 CoordinatorLayout.Behavior 类:

public class ViewScrollWithRecyclerViewBehavior extends CoordinatorLayout.Behavior<View> {
    private boolean visible = true;
    private boolean inStartPosition = true;
    private float oldY;
    private DisplayMetrics metrics;



    public ViewScrollWithRecyclerViewBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
        metrics = Resources.getSystem().getDisplayMetrics();
    }

    @Override
    public boolean layoutDependsOn(CoordinatorLayout parent, View fab, View dependency) {
        return dependency instanceof AppBarLayout;
    }

    @Override
    public boolean onDependentViewChanged(CoordinatorLayout parent, View child, View dependency) {
        if (dependency instanceof AppBarLayout) {
            CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) child.getLayoutParams();
            float dy  = oldY - dependency.getY();
            if(dy > 0 && visible){
                moveDown(child, oldY);
            } else if(!inStartPosition) {
               moveUp(child, oldY);
            }
            oldY = dependency.getY();
        }
        return true;
    }

    private void moveUp(View child, float dy){
        if(child.getY() + dy >= metrics.heightPixels - child.getHeight()){
            child.setY(metrics.heightPixels - child.getHeight());
        } else {
            child.setY(child.getY() + dy);
        }
        inStartPosition = child.getY() == metrics.heightPixels - child.getHeight();
        visible = child.getY() > metrics.heightPixels;
    }


    private void moveDown(View child, float dy){
        child.setY(child.getY() + dy);

        visible = child.getY() > metrics.heightPixels;
        if(!visible) {
            child.setY(metrics.heightPixels);
        }
    }

    @Override
    public boolean onStartNestedScroll(final CoordinatorLayout coordinatorLayout, final View child,
                                       final View directTargetChild, final View target, final int nestedScrollAxes) {
        return true;
    }

    @Override
    public void onNestedScroll(final CoordinatorLayout coordinatorLayout,
                               final View child,
                               final View target, final int dxConsumed, final int dy,
                               final int dxUnconsumed, final int dyUnconsumed) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dy, dxUnconsumed, dyUnconsumed);
        if(dy > 0 && visible){
           moveDown(child, dy);
        } else if(!inStartPosition) {
          moveUp(child, dy);
        }
    }


}

【讨论】:

  • 我需要一个扩展 Coordinator Behavior 的类,可以在 xml 中使用,如问题中所述。
  • 对不起我之前看过,但是过程是一样的
  • 你能不能把它改写成一个CoordinatorBehavior类
  • 是你想要的吗?
猜你喜欢
  • 2020-08-22
  • 1970-01-01
  • 2021-11-13
  • 2022-10-12
  • 1970-01-01
  • 2016-10-26
  • 2020-05-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多