Android 具有RecyclerView垂直滚动的BottomNavigationView的垂直滚动协调布局行为

Android 具有RecyclerView垂直滚动的BottomNavigationView的垂直滚动协调布局行为,android,android-coordinatorlayout,android-design-library,android-bottom-nav-view,Android,Android Coordinatorlayout,Android Design Library,Android Bottom Nav View,如何定义与RecyclerView veritical滚动同步的滚动的类 我已经看到和,但它所做的只是立即在veritical scroll事件上显示/隐藏NavigationView。我不想立即显示/隐藏NavigationView,而是想要一种类似于AppbarLayout的行为,它有一个工具栏,滚动标志为app:layout\u scrollFlags=“scroll | enterally” 公共类BottomNavigationBehavior扩展了CoordinatorLayout.

如何定义与RecyclerView veritical滚动同步的滚动的类

我已经看到和,但它所做的只是立即在veritical scroll事件上显示/隐藏
NavigationView
。我不想立即显示/隐藏
NavigationView
,而是想要一种类似于
AppbarLayout
的行为,它有一个
工具栏,滚动标志为
app:layout\u scrollFlags=“scroll | enterally”

公共类BottomNavigationBehavior扩展了CoordinatorLayout.Behavior{
公共导航行为(){
超级();
}
公共底部导航行为(上下文、属性集属性){
超级(上下文,attrs);
}
@凌驾
公共布尔布局依赖项(CoordinatorLayoutDependson父项、底部导航视图子项、视图依赖项){
布尔dependsOn=FrameLayout的依赖实例;
返回dependsOn;
}
@凌驾
公共布尔值onStartNestedScroll(CoordinatorLayout CoordinatorLayout,BottomNavigationView子级,View directTargetChild,View target,int nestedScrollAxes){
返回NestedScrollAxis==ViewCompat.SCROLL\u AXIS\u VERTICAL;
}
@凌驾
public void onNestedPreScroll(CoordinatorLayout CoordinatorLayout,BottomNavigationView子视图,视图目标,int dx,int dy,int[]已消耗){
if(dy<0){
showBottomNavigationView(子级);
}
如果(dy>0),则为else{
hideBottomNavigationView(儿童);
}
}
私有void hideBottomNavigationView(底部导航视图){
view.animate().translationY(view.getHeight());
}
私有void showBottomNavigationView(BottomNavigationView视图){
view.animate().translationY(0);
}
}

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

  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和recycler视图

或使用CoordinatorLayout。行为类:

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);
        }
    }


}
公共类视图ScrollWithRecycleServiceWBehavior扩展CoordinatorLayout.Behavior{
私有布尔可见=真;
私有布尔inStartPosition=true;
私家花车;
私有显示度量;
公共视图ScrollWithRecycleServiceWBehavior(上下文、属性集属性){
超级(上下文,attrs);
metrics=Resources.getSystem().getDisplayMetrics();
}
@凌驾
公共布尔布局依赖项(协调布局父项、视图工厂、视图依赖项){
返回AppBarLayout的依赖实例;
}
@凌驾
公共布尔onDependentViewChanged(协调布局父项、视图子项、视图依赖项){
if(AppBarLayout的依赖项实例){
CoordinatorLayout.LayoutParams lp=(CoordinatorLayout.LayoutParams)child.getLayoutParams();
float dy=oldY-dependency.getY();
如果(dy>0&&visible){
下移(儿童、老人);
}如果(!inStartPosition),则为else{
向上移动(儿童、老人);
}
oldY=dependency.getY();
}
返回true;
}
私有void moveUp(查看子对象、浮动对象){
if(child.getY()+dy>=metrics.heightPixels-child.getHeight()){
setY(metrics.heightPixels-child.getHeight());
}否则{
setY(child.getY()+dy);
}
inStartPosition=child.getY()==metrics.heightPixels-child.getHeight();
visible=child.getY()>metrics.heightPixels;
}
私有空心下移(视图子对象、浮动对象){
setY(child.getY()+dy);
visible=child.getY()>metrics.heightPixels;
如果(!可见){
setY(metrics.heightPixels);
}
}
@凌驾
公共布尔值onStartNestedScroll(最终坐标或布局坐标或布局,最终视图子对象,
最终视图directTargetChild、最终视图目标、最终int嵌套滚动轴){
返回true;
}
@凌驾
公共空间与STEDSCROLL(最终协调人布局协调人布局,
最终视图子对象,
最终视图目标,最终整数dx,最终整数dy,
最终整数dx未使用,最终整数dy未使用){
super.onNestedScroll(协调布局、子项、目标、dxConsumed、dy、dxUnumed、dyUnumed);
如果(dy>0&&visible){
向下移动(儿童,dy);
}如果(!inStartPosition),则为else{
移动(儿童,dy);
}
}
}

我会尝试设置对appbarlayout的依赖关系,并根据appbarlayout的高度变化移动BottomNavigationBari的意思,我想实现一个布局行为,就像appbar布局的行为一样,它会响应RecyclerView滚动事件,所以使用recycler视图缓慢地向外移动,而不是仅仅取消显示?是的,没错。带有带有“scroll | enterAlways”标志的工具栏的Appbarlayout就是此类滚动的一个例子。我需要一个类来扩展协调器行为,如问题中所述,该行为可以在xml中使用。抱歉,我以前监督过它,但是该过程是相同的,您可以将其重写为协调器行为classis它是您想要的吗?
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);
        }
    }


}