Вертикальная прокрутка CoordinatorLayout Поведение для BottomNavigationView с RecyclerView вертикальной прокрутки
Как определить класс CoordinatorLayout.Behavior для BottomNavigationView, который выполняет прокрутку, синхронизированную с вертикальной прокруткой RecyclerView.
Я видел это и это, но все, что он делает, это просто показывает / скрывает 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);
}
}
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 class:
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);
}
}
}