public override bool OnLayoutChild(CoordinatorLayout parent, Java.Lang.Object child, int layoutDirection) { if (!(child is NestedScrollView view)) { return(base.OnLayoutChild(parent, child, layoutDirection)); } // First layout the child as normal. parent.OnLayoutChild(view, layoutDirection); // Center the FAB vertically along the top edge of the card. int fabHalfHeight = view.FindViewById(Resource.Id.fab).Height / 2; SetTopMargin(view.FindViewById(Resource.Id.cardview), fabHalfHeight); // Give the RecyclerView a maximum height to ensure the card will never // overlap the toolbar as it scrolls. int rvMaxHeight = view.Height - fabHalfHeight - view.FindViewById(Resource.Id.card_title).Height - view.FindViewById(Resource.Id.card_subtitle).Height; MaxHeightRecyclerView rv = view.FindViewById <MaxHeightRecyclerView>(Resource.Id.card_recyclerview); rv.SetMaxHeight(rvMaxHeight); // Give the card container top padding so that only the top edge of the card // initially appears at the bottom of the screen. The total padding will // be the distance from the top of the screen to the FAB's top edge. View cardContainer = view.FindViewById(Resource.Id.card_container); int toolbarContainerHeight = parent.GetDependencies(view)[0].Height; SetPaddingTop(cardContainer, rvMaxHeight - toolbarContainerHeight); // Offset the child's height so that its bounds don't overlap the // toolbar container. ViewCompat.OffsetTopAndBottom(view, toolbarContainerHeight); // Add the same amount of bottom padding to the RecyclerView so it doesn't // display its content underneath the navigation bar. SetPaddingBottom(rv, toolbarContainerHeight); // Return true so that the parent doesn't waste time laying out the // child again (any modifications made above will have triggered a second // layout pass anyway). return(true); }
private static float GetTranslationY(CoordinatorLayout parent, Android.Views.View child) { var minOffset = 0.0F; var dependencies = parent.GetDependencies(child); var i = 0; for (var z = dependencies.Count; i < z; ++i) { var view = dependencies[i]; if (IsInstanceOf <Snackbar.SnackbarLayout>(view) && parent.DoViewsOverlap(child, view)) { minOffset = Math.Min(minOffset, ViewCompat.GetTranslationY(view) - view.Height); } } return(minOffset); }
private float GetTranslationY(CoordinatorLayout parent, View child) { float minOffset = 0.0F; var dependencies = parent.GetDependencies(child); int i = 0; for (int z = dependencies.Count; i < z; ++i) { View view = (View)dependencies[i]; if (IsInstanceOf <Snackbar.SnackbarLayout>(view) && parent.DoViewsOverlap(child, view)) { minOffset = Math.Min(minOffset, ViewCompat.GetTranslationY(view) - (float)view.Height); } } return(minOffset); }
public override void OnNestedScroll(CoordinatorLayout coordinatorLayout, Java.Lang.Object child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) { // dyconsumed: user initiates movement on the y-axis and it happens on screen // dyunconsumed: user initiates movement on the y-axis but it doesn't happen on screen, for example, downwards movement at the bottom end of the list. // dy > 0: user swiping up, so screen in scrolling down // dy < 0: user swiping down, so screen is scrolling up base.OnNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed); BottomNavigationView childView = child.JavaCast <BottomNavigationView>(); if (dyUnconsumed > 0 || dyConsumed > 0) { this.SlideDown(childView); } else if (dyUnconsumed < 0 || dyConsumed < 0) { this.SlideUp(childView); } // define our own behavior IList <View> dependencies = coordinatorLayout.GetDependencies(childView); foreach (View view in dependencies) { if (view is FloatingActionButton) { FloatingActionButton floatingActionButtonView = view.JavaCast <FloatingActionButton>(); if (dyUnconsumed > 0 || dyConsumed > 0) { floatingActionButtonView.Hide(); } else if (dyUnconsumed < 0 || dyConsumed < 0) { floatingActionButtonView.Show(); } } } }