Agregar elevación / sombra en la barra de herramientas para dispositivos pre-piruleta

Actualicé mi aplicación de Android para el nuevo diseño de material, pero también quería agregar alguna sombra o elevación a la barra de herramientas. Parece que hay algunas formas (hacky) de hacerlo a través de imágenes / 9-patches, pero me pregunto si se puede hacer a través de las bibliotecas de soporte. (Al igual que CardView puede tener elevación)

Según esta respuesta a otra pregunta, esto es posible al AppBarLayout la Toolbar de Toolbar en un AppBarLayout , pero esto no funciona para mí.

Mi diseño:

     

También intenté establecer la elevación a través de XML y mediante código, pero eso tampoco funciona.

¡Cualquier ayuda sería apreciada! Gracias por adelantado.

Actualizar:

Como incluyo el diseño de la barra de herramientas en mis otros diseños, a continuación se muestra uno de mis diseños principales:

      

Para Android 5.0 y versiones posteriores: AppBarLayout proporciona / sombrea automáticamente el diseño. También puede boost la elevación de AppBarLayout por app:elevation="4dp" .

Para Pre-Lollipop: puede usar el siguiente enlace: https://github.com/vipulasri/Toolbar-Elevation-Pre-Lollipop

Nota: la barra de herramientas también admite elevación, usando android:elevation="4dp"


Nueva actualización: en Appcompat v24.0.0 , no puede establecer la elevación a AppBarLayout utilizando setElevation() y app:elevation ya que están en desuso.

stateListAnimator usar la propiedad stateListAnimator para establecer la elevación ahora.

Nota: configure la duración en 1 ms en StateListAnimator para evitar retrasos en el dibujo de elevación .

El cambio de elevación de AppBarLayout se retrasa en appCompat v24.0.0

appbar_always_elevated.xml en la carpeta animator-v21 en el directorio res .

 < ?xml version="1.0" encoding="utf-8"?>      

En AppbarLayout:

   

Intenta usar AppBarLayout dentro del diseño de la actividad. Tratar:

 < ?xml version="1.0" encoding="utf-8"?>       

Toolbar.xml

 < ?xml version="1.0" encoding="utf-8"?>  

usar archivo de comstackción:


 compile 'com.android.support:cardview-v7:23.1.1' 

referir este enlace

para llamar a xml add:

 app:cardElevation="8dp" app:cardCornerRadius="8dp" app:contentPadding="5dp" 

Tengo un CollapsingToolbarLayout con la Toolbar y una View similar a una barra de herramientas que se mueve hacia arriba y hacia abajo, pero se encuentra por encima de NestedScrollView , como en https://github.com/k0shk0sh/CoordinatorLayoutExample . Intenté muchas variantes. A veces, una sombra se desplazaba por encima de una pantalla con NestedScrollView, a veces la barra de herramientas dibujaba una sombra sólida sin transparencia, a veces se sombreaba la sombra. De todos modos, esta es mi solución.

Diga, usted tiene un diseño:

                   

Agregue una sombra ( drawable / shadow.xml ):

 < ?xml version="1.0" encoding="utf-8"?>    

Agrega este método Aquí scrollShadow es una vista llamada “scroll_shadow”:

 private void setShadowVisibility(int visibility) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { scrollShadow.setVisibility(visibility); } } 

Manipúlalo como lo desees. Mostrará un degradado en dispositivos anteriores a Lollipop y mostrará una sombra normal para Android 5.0+.

También perdí un día en este tema, pero finalmente descubrí una forma de hacerlo funcionar.

 /** * Controller for the toolbar which will take care of the drop down shadow also on pre-lollipop devices. * 
* The controller also handles the status bar based on the state of the toolbar. *

* Created by Negru Ionut Valentin on 20/1/2016. */ public class ToolbarController { private boolean handleStatusBar = false; private boolean showTitle = true; /** * Call this method in onCreate() method of your Activity or in onCreateView() in Fragment * * @param view * The view into which to look for the toolbar * @param activity * The activity for which setup the toolbar * * @return The toolbar found and customized or {@code null} */ public Toolbar initToolbar(View view, Activity activity) { Toolbar mToolbar = (Toolbar) view.findViewById(R.id.toolbar); // Valid and visible toolbar - otherwise ignore if (null != mToolbar && mToolbar.getVisibility() == View.VISIBLE) { int paddingLeft = mToolbar.getPaddingLeft(); int paddingRight = mToolbar.getPaddingRight(); int paddingBottom = mToolbar.getPaddingBottom(); // Set the top padding of the toolbar to match the status bar height int paddingTop = new CynnyContextWrapper(activity).getStatusBarHeight(); mToolbar.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); if (Build.VERSION.SDK_INT < = Build.VERSION_CODES.LOLLIPOP) { ViewParent parent = mToolbar.getParent(); if (parent instanceof RelativeLayout) { // Manually create the drop shadow RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, Metrics.convertDpToPixel(4, activity)); View dropShadow = new View(activity); dropShadow.setBackgroundResource(R.drawable.toolbar_shadow); params.addRule(RelativeLayout.BELOW, R.id.toolbar); ((RelativeLayout) parent).addView(dropShadow, params); } } if (activity instanceof AppCompatActivity) { // Check if the Activity actually support ActionBar with Toolbar and set our custom Toolbar for it ((AppCompatActivity) activity).setSupportActionBar(mToolbar); // Get the actionbar from the activity ActionBar actionBar = ((AppCompatActivity) activity).getSupportActionBar(); if (null != actionBar) { // If the actionbar is valid, customize it actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setHomeButtonEnabled(true); actionBar.setDisplayShowTitleEnabled(this.showTitle); mToolbar.setNavigationIcon(R.drawable.ic_arrow_back_selector); } } if (this.handleStatusBar) { // For showing the status bar activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); } } else if (handleStatusBar) { // Force hide the status bar activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); } return mToolbar; } /** * Set the flag indicating if the controller should handle or not the status bar. * * @param handleStatusBar * Flag which indicates if the initialization of the toolbar should also update * the status bar state (if two calls are made for the init, the last one will * be taken into consideration). * * @return The current toolbar controller. */ public ToolbarController setHandleStatusBar(boolean handleStatusBar) { this.handleStatusBar = handleStatusBar; return this; } /** * Set the flag indicating if the toolbar should show or hide the title. * * @param showTitle * Flag indicating if the toolbar should also show the title (the title can be changed after the toolbar * initialization) * * @return The current toolbar controller. */ public ToolbarController setShowTitle(boolean showTitle) { this.showTitle = showTitle; return this; } }

En la actividad debes usar esto en el método onCreate () como este:

 // Create and customize the Toolbar controller new ToolbarController().setHandleStatusBar(true).setShowTitle(true) .initToolbar(((ViewGroup) findViewById(android.R.id.content)).getChildAt(0), this); 

En el fragmento debes usar esto en el método onCreateView () como este:

 new ToolbarController().setHandleStatusBar(false).setShowTitle(false).initToolbar(resultView, getActivity()); 

No olvides agregar tu barra de herramientas en los diseños y configurar su id con android:id="@id/toolbar" . Si desea utilizar otra identificación, puede personalizar el controlador y agregar otro método setter que use la identificación que proporciona.

Tengo dos diseños de barra de herramientas creados:

v21

     

otro

 < ?xml version="1.0" encoding="utf-8"?>     

Los uso en diseños de mayo usando:

  

Espero que esto ayude a resolver su problema. También tenga en cuenta que esto se puede optimizar aún más, pero funciona para mí y no quiero perder más tiempo en este tema.

Creo que la mejor solución es poner una vista sombreada de degradado debajo de la barra de herramientas y manipular con visibilidad depende de sdk del dispositivo.

toolbar.xml

  < ?xml version="1.0" encoding="utf-8"?>       

toolbar_shadow.xml

 < ?xml version="1.0" encoding="utf-8"?>    

MainActivity.class

 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { findViewById(R.id.shadow_view).setVisibility(View.VISIBLE); } 

Use CardView