custom android layout snackbar

android - custom - Mueva el snackbar sobre la barra inferior



custom snackbar android (6)

Estoy utilizando BottomNavigationView y Snackbar de la biblioteca de soporte de diseño versión 25.3.1 en el kitkat, lollipop y Marshmallow de OS de destino. En la paleta y arriba, Snackbar se esconde detrás de BottomNavigationView pero en Kitkat BottomNavigationView está oculto detrás de Snackbar.

Intenté mostrar el Snackbar con un enfoque diferente. Cuando se muestra el Snackbar, BottomNavigationView se traduce en el eje Y (se desplaza hacia abajo) utilizando la propiedad de traducciónY e Interpolator . Una vez que Snackbar se ha ido, BottomNavigationView aparece de nuevo con la misma propiedad de traducciónY.

Ocultar el BottomNavigationView (hacia abajo):

CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) bottomNavigationView.getLayoutParams(); bottomNavigationView.animate().translationY(bottomNavigationView.getHeight() + layoutParams.bottomMargin).setInterpolator(new LinearInterpolator()).start();

Mostrando el BottomNavigationView de nuevo en la pantalla:

bottomNavigationView.animate().translationY(0).setInterpolator(new LinearInterpolator()).start();

Estoy enfrentando algunos problemas con la nueva barra inferior.
No puedo forzar el movimiento de la barra de aperitivos sobre la barra inferior (así es como me dijo la guía de diseño https://www.google.com/design/spec/components/bottom-navigation.html#bottom-navigation-specs ).

Este es mi activity_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>

Este es mi 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>

El snackbar en main_activity.java se ve así

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


Hay un gran artículo sobre cómo usarlo HERE . Allí sabrás cómo hacer un snackbar arriba. BottomNavigationBar

Básicamente, el código a continuación presenta el uso más común de la Toolbar de Toolbar junto con BottomNavigationBar y FrameLayout como contenedor de fragmentos

¡Importante! Darse cuenta de

  1. El botón fab utiliza el ancla para colocarse correctamente y usa CompactPadding para conservar los márgenes
  2. BottomNavigationView utiliza layout_behaviour para manejar el desplazamiento y la posición de SnackBar

    <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" />

Implementación de comportamiento ¡No dude en usar eso! Es fácil y amigable;) (desplazamiento)

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


Para lograr esto, debe tener cuidado de que el ViewGroup que está proporcionando a la barra de aperitivos sea un CoordinatorLayout; de lo contrario, la barra de snack no se mostrará sobre el menú de navegación inferior.


Puede hacer esto programáticamente sin saturar su xml con CoordinatorLayouts adicionales cambiando los márgenes de la barra de aperitivos.

Ejemplo de 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 sola línea:

Snackbar.make(coordinatorLayout, "Your message", Snackbar.LENGTH_LONG).apply {view.layoutParams = (view.layoutParams as CoordinatorLayout.LayoutParams).apply {setMargins(leftMargin, topMargin, rightMargin, bottomBar.height)}}.show()


Suponiendo que esté trabajando con CoordinatorLayout, puede modificar los paquetes de diseño de Snackbar antes de llamar a show (). Al establecer anchorId y anchorGravity, la barra de aperitivos se mostrará arriba de la barra de navegación inferior:

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


reemplazar su 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>

y el código de Snackbar será

Snackbar.make(findViewById(R.id.placeSnackBar), "Replace with your own action", Snackbar.LENGTH_LONG) .setAction("Action", null).show();