Je suis confronté à des problèmes avec la nouvelle barre inférieure.
Je ne peux pas forcer le snackbar à se déplacer au-dessus de la barre inférieure (c’est ainsi que la directive de conception me dit de: https://www.google.com/design/spec/components/bottom- navigation.html # bottom-navigation-specs ).
C'est mon activité_main.xml
<?xml version="1.0" encoding="utf-8"?>
<Android.support.v4.widget.DrawerLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/drawer_layout"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_bar_main_activity"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
<Android.support.design.widget.NavigationView
Android:id="@+id/nav_view"
Android:layout_width="wrap_content"
Android:layout_height="match_parent"
Android:layout_gravity="start"
Android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main_activity"
app:menu="@menu/activity_main_drawer" />
</Android.support.v4.widget.DrawerLayout>
C'est mon app_bar_main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/main_content"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true"
tools:context="test.tab_activity">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/appbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:paddingTop="@dimen/appbar_padding_top"
Android:theme="@style/MyAppTheme.NoActionBar.AppBarOverlay">
<Android.support.v7.widget.Toolbar
Android:id="@+id/main_activity_toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/MyAppTheme.NoActionBar.PopupOverlay">
</Android.support.v7.widget.Toolbar>
</Android.support.design.widget.AppBarLayout>
<Android.support.v4.view.ViewPager
Android:id="@+id/container"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<Android.support.v4.view.ViewPager
Android:id="@+id/view_pager"
Android:layout_width="match_parent"
Android:layout_height="0dp"
Android:layout_weight="1" />
<Android.support.design.widget.FloatingActionButton
Android:id="@+id/fab"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="end|bottom"
Android:layout_margin="@dimen/fab_margin"
Android:src="@drawable/ic_add_white_24dp" />
<Android.support.design.widget.TabLayout
Android:id="@+id/tab_layout"
style="@style/AppTabLayout"
Android:layout_width="match_parent"
Android:layout_height="56dp"
Android:background="?attr/colorPrimary"
/>
</LinearLayout>
Le snack dans main_activity.Java ressemble à ceci
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(findViewById(R.id.main_content), "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
remplacez votre xml ->
<?xml version="1.0" encoding="utf-8"?>
<Android.support.design.widget.CoordinatorLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools"
Android:id="@+id/main_content"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:fitsSystemWindows="true"
tools:context="test.tab_activity">
<Android.support.design.widget.AppBarLayout
Android:id="@+id/appbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<Android.support.v7.widget.Toolbar
Android:id="@+id/main_activity_toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways">
</Android.support.v7.widget.Toolbar>
</Android.support.design.widget.AppBarLayout>
<Android.support.v4.view.ViewPager
Android:id="@+id/container"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical">
<Android.support.design.widget.CoordinatorLayout
Android:layout_width="match_parent"
Android:layout_height="0dp"
Android:layout_weight="1"
Android:id="@+id/placeSnackBar">
<Android.support.v4.view.ViewPager
Android:id="@+id/view_pager"
Android:layout_width="match_parent"
Android:layout_height="0dp"
Android:layout_weight="1" />
<Android.support.design.widget.FloatingActionButton
Android:id="@+id/fab"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="end|bottom"
Android:layout_margin="@dimen/fab_margin"
Android:src="@drawable/ic_menu_gallery" />
</Android.support.design.widget.CoordinatorLayout>
<Android.support.design.widget.TabLayout
Android:id="@+id/tab_layout"
Android:layout_width="match_parent"
Android:layout_height="56dp"
Android:background="?attr/colorPrimary" />
</LinearLayout>
</Android.support.design.widget.CoordinatorLayout>
et Le code Snackbar sera
Snackbar.make(findViewById(R.id.placeSnackBar), "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
Vous pouvez le faire par programme sans encombrer votre xml avec des coordinatorsLayouts supplémentaires en modifiant les marges du snackbar.
Exemple Java:
Snackbar snack = Snackbar.make(findViewById(R.id.coordinatorLayout),
"Your message", Snackbar.LENGTH_LONG);
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams)
snack.getView().getLayoutParams();
params.setMargins(leftMargin, topMargin, rightMargin, bottomBar.height);
snack.getView().setLayoutParams(params);
snack.show();
Kotlin simple ligne:
Snackbar.make(coordinatorLayout, "Your message", Snackbar.LENGTH_LONG).apply {view.layoutParams = (view.layoutParams as CoordinatorLayout.LayoutParams).apply {setMargins(leftMargin, topMargin, rightMargin, bottomBar.height)}}.show()
En supposant que vous travailliez avec Coordinator Layout, vous pouvez modifier les paramètres de présentation de la barre de contrôle avant d'appeler show (). En définissant anchorId et anchorGravity, le snackBar s’affiche au-dessus de la barre de navigation inférieure:
val layoutParams = snackbar.view.layoutParams as CoordinatorLayout.LayoutParams
layoutParams.anchorId = R.id.navigation //Id for your bottomNavBar or TabLayout
layoutParams.anchorGravity = Gravity.TOP
layoutParams.gravity = Gravity.TOP
snackbar.view.layoutParams = layoutParams
Il y a un excellent article sur la façon de l'utiliser ICI . Là, vous saurez faire un snack-bar au-dessus de BottomNavigationBar
Fondamentalement, le code ci-dessous présente l'utilisation la plus courante de Toolbar
avec BottomNavigationBar
et FrameLayout
en tant que conteneur de fragments.
Important! Notez que
BottomNavigationView
utilise layout_behaviour pour gérer le défilement et la position de la barre de snack
<Android.support.design.widget.AppBarLayout
Android:id="@+id/myAppBar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:descendantFocusability="beforeDescendants"
Android:focusableInTouchMode="true"
Android:theme="@style/AppTheme.AppBarOverlay">
<Android.support.v7.widget.Toolbar
Android:id="@+id/toolbar"
Android:layout_width="match_parent"
Android:layout_height="?attr/actionBarSize"
Android:background="?attr/colorPrimary"
app:contentInsetStart="0dp"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</Android.support.design.widget.AppBarLayout>
<FrameLayout
Android:id="@+id/fragment_container"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>
<Android.support.design.widget.BottomNavigationView
Android:id="@+id/navigation_bar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_gravity="bottom"
app:menu="@menu/bottom_navigation"
app:layout_behavior="murt.shoppinglistapp.ui.BottomNavigationBehavior"
Android:background="?android:attr/windowBackground"
/>
<Android.support.design.widget.FloatingActionButton
Android:id="@+id/fab_add_shopping_list"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:useCompatPadding="true"
app:srcCompat="@drawable/ic_add_24"
app:layout_anchor="@id/navigation_bar"
app:layout_anchorGravity="top|right"
Android:layout_gravity="top"
/>
Implémentation de Behavior n'hésite pas à l'utiliser! C'est facile et convivial;) (défilement)
class BottomNavigationBehavior : CoordinatorLayout.Behavior<BottomNavigationView> {
constructor(): super()
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
override fun layoutDependsOn(parent: CoordinatorLayout, child: BottomNavigationView,
dependency: View): Boolean {
if (dependency is Snackbar.SnackbarLayout) {
updateSnackbar(child, dependency)
}
return super.layoutDependsOn(parent, child, dependency)
}
private fun updateSnackbar(child: View, snackbarLayout: Snackbar.SnackbarLayout) {
if (snackbarLayout.layoutParams is CoordinatorLayout.LayoutParams) {
val params = snackbarLayout.layoutParams as CoordinatorLayout.LayoutParams
params.anchorId = child.id
params.anchorGravity = Gravity.TOP
params.gravity = Gravity.TOP
snackbarLayout.layoutParams = params
}
}
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView,
directTargetChild: View,
target: View,
nestedScrollAxes: Int
): Boolean {
return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL
}
override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView,
target: View,
dx: Int,
dy: Int,
consumed: IntArray
) {
if (dy < 0) {
showBottomNavigationView(child)
} else if (dy > 0) {
hideBottomNavigationView(child)
}
}
private fun hideBottomNavigationView(view: BottomNavigationView) {
view.animate().translationY(view.height.toFloat())
}
private fun showBottomNavigationView(view: BottomNavigationView) {
view.animate().translationY(0f)
}
}
J'utilise BottomNavigationView et Snackbar à partir de la version 25.3.1 de la bibliothèque de support de conception sur les systèmes d'exploitation cibles KitKat, Lollipop et Marshmallow. Sur Lollipop et au-dessus, Snackbar se cache derrière BottomNavigationView mais dans KitKat, BottomNavigationView est caché derrière Snackbar.
J'ai essayé de montrer le Snackbar avec une approche différente. Lorsque la barre est affichée, BottomNavigationView est traduit sur l’axe Y (défilement vers le bas) à l’aide de propriété translationY et Interpolator. Une fois que la barre est partie, BottomNavigationView apparaît à nouveau avec la même propriété translationY.
Masquage de la vue de navigation inférieure (vers le bas):
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) bottomNavigationView.getLayoutParams();
bottomNavigationView.animate().translationY(bottomNavigationView.getHeight() + layoutParams.bottomMargin).setInterpolator(new LinearInterpolator()).start();
Affiche à nouveau l'écran BottomNavigationView:
bottomNavigationView.animate().translationY(0).setInterpolator(new LinearInterpolator()).start();
Cela peut être fait simplement si la mise en page parent était une mise en page de coordinateur.
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams)
snackbar.getView().getLayoutParams();
params.setAnchorId(R.id.navigation); //id of the bottom navigation view
params.gravity = Gravity.TOP;
params.anchorGravity = Gravity.TOP;
snackbar.getView().setLayoutParams(params);
Pour ce faire, vous devez vous assurer que le ViewGroup que vous fournissez au snackbar est un CoordinatorLayout sinon le snackbar ne serait pas affiché au-dessus du menu de navigation inférieur.