web-dev-qa-db-fra.com

Déplacez le snackbar au-dessus de la barre inférieure

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

Wrong...snackbar should be above bottom bar

36
Wladislaw

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();
29
Zahidul Islam

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()
40
Amagi82

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
24
jesusF10

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

  1. le bouton fab utilise l'ancre pour être placé correctement et utiliseCompactPadding pour préserver les marges.
  2. 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)
    }
}
10
murt

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();
2
Prashant

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);
2
Jarin Rocks

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.

1
sanjay kumar