Nenhuma sombra por padrão na barra de ferramentas?

165

Estou atualizando meu aplicativo com a nova barra de ferramentas da biblioteca de suporte v21. Meu problema é que a barra de ferramentas não lança sombra se eu não definir o atributo "elevação". Esse é o comportamento normal ou estou fazendo algo errado?

Meu código é:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:orientation="vertical">

   <android.support.v7.widget.Toolbar
       xmlns:app="http://schemas.android.com/apk/res-auto"
       android:id="@+id/my_awesome_toolbar"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:background="?attr/colorPrimary"
       android:elevation="4dp"
       android:minHeight="?attr/actionBarSize"
       app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
       app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

   <FrameLayout
       android:id="@+id/FrameLayout1"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       .
       .
       .

E no meu método Activity - OnCreate:

    Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
    setSupportActionBar(toolbar);
Sr. Brightside
fonte
Você está vendo isso em um dispositivo executando o Lollipop?
rlay3
3
Em um dispositivo executando o Lollipop mostra a sombra por causa do atributo de elevação, mas não no KitKat ou em versões anteriores. Esse é o comportamento esperado para o atributo de elevação, como diz a documentação, mas eu esperava que, por padrão, sem o atributo de elevação, a sombra fosse projetada como a barra de ação em todas as versões.
MrBrightside
Eu postei uma possível solução aqui: stackoverflow.com/a/26759202/553905
Billy
Use as pastas / values ​​e styles.xml para aplicar o código de sombra apropriado com base na versão do sistema operacional (veja abaixo).
radley

Respostas:

252

Acabei definindo minha própria sombra para a barra de ferramentas, achei que poderia ser útil para quem estava procurando:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:app="http://schemas.android.com/apk/res-auto"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_gravity="top"
              android:orientation="vertical">

    <android.support.v7.widget.Toolbar android:id="@+id/toolbar"
                                       android:layout_width="match_parent"
                                       android:layout_height="wrap_content"
                                       android:background="@color/color_alizarin"
                                       android:titleTextAppearance="@color/White"
                                       app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>

    <FrameLayout android:layout_width="match_parent"
                 android:layout_height="match_parent">

        <!-- **** Place Your Content Here **** -->

        <View android:layout_width="match_parent"
              android:layout_height="5dp"
              android:background="@drawable/toolbar_dropshadow"/>

    </FrameLayout>

</LinearLayout>

@ drawable / toolbar_dropshadow:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
       android:shape="rectangle">

    <gradient android:startColor="@android:color/transparent"
              android:endColor="#88333333"
              android:angle="90"/>

</shape>

@ color / color_alizarin

<color name="color_alizarin">#e74c3c</color>

insira a descrição da imagem aqui

Eu sou um dragão sapo
fonte
3
Não se esqueça de ocultar sua visualização se o dispositivo que você estiver executando for> = to Lollipop; caso contrário, você terá duas sombras.
Mradzinski
1
Esse é o caminho errado, porque você precisará remover essa visualização para layouts 5.0. Use android: windowContentOverlay ou android: foreground.
radley
3
No Google, sobre como projetar o design do material da Barra de Ferramentas , você deve definir android:layout_height="4dp"a altura da sombra, em vez de 5dp. Na verdade, a elevação é a mesma que a altura da sombra que você definiu FrameLayout.
Anggrayudi H
2
Estou tendo problemas com esta solução porque inflado meu layout de atividades no layout de quadro do seu exemplo. Você consegue pensar em uma maneira de isso funcionar?
Zach Sperske
2
Recomendando o uso de "android: endColor =" # c7c7c7 "no android: endColor =" # 88333333 "
Mohammad Faisal
211

O Google lançou a biblioteca de suporte de design há algumas semanas e existe uma solução bacana para esse problema nessa biblioteca.

Adicione a biblioteca Design Support como uma dependência em build.gradle:

compile 'com.android.support:design:22.2.0'

Adicione AppBarLayoutfornecido pela biblioteca como um invólucro ao redor do seu Toolbarlayout para gerar uma sombra projetada.

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
       <android.support.v7.widget.Toolbar
           .../>
    </android.support.design.widget.AppBarLayout>

Aqui está o resultado:

insira a descrição da imagem aqui

Existem muitos outros truques com a biblioteca de suporte ao design.

  1. http://inthecheesefactory.com/blog/android-design-support-library-codelab/en
  2. http://android-developers.blogspot.in/2015/05/android-design-support-library.html

AndroidX

Como acima, mas com dependência:

implementation 'com.google.android.material:material:1.0.0'

e com.google.android.material.appbar.AppBarLayout

Binoy Babu
fonte
26
Definir o AppBarLayoutcomo um invólucro ao redor do Toolbarnão define nenhuma sombra para mim. Observe que eu não uso uma gaveta de navegação. Alguma idéia de por que não funciona?
AVB
@ avb1994 Não posso ter certeza, eu testei sem uma gaveta de navegação. Você pode publicá-lo como uma pergunta com o arquivo de layout?
precisa
veja minha pergunta: stackoverflow.com/questions/31115531/… obrigado pelo seu comentário
avb
2
Você não precisa dessas duas linhas compilar 'com.android.support:support-v4:22.2.0' compilar 'com.android.support:appcompat-v7:22.2.0', porque compile 'com.android.support: design: 22.2.0 'depende deles
Andrey /
8
Observe que isso só funciona para pirulito e acima. Ele não funcionará antes do pirulito, já que embaixo está apenas usando o ViewCompat.setElevation ().
Amirul Zin
25

Você não pode usar o atributo de elevação antes da API 21 (Android Lollipop). No entanto, você pode adicionar a sombra programaticamente, por exemplo, usando uma exibição personalizada colocada abaixo da Barra de Ferramentas.

@ layout / barra de ferramentas

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/blue"
    android:minHeight="?attr/actionBarSize"
    app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />

<View
    android:id="@+id/toolbar_shadow"
    android:layout_width="match_parent"
    android:layout_height="3dp"
    android:background="@drawable/toolbar_dropshadow" />

@ drawable / toolbar_dropshadow

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <gradient
        android:startColor="@android:color/transparent"
        android:endColor="#88333333"
        android:angle="90"/> </shape>

no seu layout de atividade <include layout="@layout/toolbar" />

insira a descrição da imagem aqui

Muhammad Aamir Ali
fonte
2
Você pode corrigir o @layout/toolbarexemplo com o arquivo de layout completo?
Daniel Gomez Rico
1
Por que @ layout / barra de ferramentas tem duas visualizações de raiz? Você pode fornecer o exemplo completo, por favor?
RED_
18

Use as pastas / values para aplicar o estilo de sombra correto com base na versão do sistema operacional.

Para dispositivos abaixo de 5.0 , use /values/styles.xml para adicionar windowContentOverlay ao corpo da sua atividade:

<style name="MyViewArea">
    <item name="android:foreground">?android:windowContentOverlay</item>
</style>

<style name="MyToolbar">
    <item name="android:background">?attr/colorPrimary</item>
</style>

Em seguida, adicione sua própria sombra personalizada alterando seu Tema para incluir:

<item name="android:windowContentOverlay">@drawable/bottom_shadow</item>

Você pode pegar o recurso de sombra do aplicativo IO do Google aqui: https://github.com/google/iosched/blob/master/android/src/main/res/drawable-xxhdpi/bottom_shadow.9.png

Para dispositivos 5.0 e posteriores , use /values-v21/styles.xml para adicionar elevação à sua barra de ferramentas usando um estilo de cabeçalho personalizado:

<style name="MyViewArea">
</style>

<style name="MyToolbar">
    <item name="android:background">?attr/colorPrimary</item>
    <item name="android:elevation">4dp</item>
</style>

Observe que, no segundo caso, eu tive que criar um estilo MyViewArea vazio para que o windowContentOverlay não aparecesse também.

[Atualização: nomes de recursos alterados e adição de sombra do Google.]

radley
fonte
Posso saber o que é MyBody e MyHeader? Onde devo aplicá-los?
Cheok Yan Cheng
Atualizei os nomes: MyHeader agora é MyToolbar e MyBody é MyViewArea. Você pode atribuir estilos em layouts xml como este: style = "@ style / MyToolbar".
Radley 17/05
A que MyViewArea é aplicado?
Zach Sperske 01/07/2015
Sua página / corpo / área de visualização.
Radley
Eu acho que android:foregroundsó funciona no FrameLayout antes da API 23.
androidguy
14

Isso funcionou muito bem para mim:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/primary"
    card_view:cardElevation="4dp"
    card_view:cardCornerRadius="0dp">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/primary"
        android:minHeight="?attr/actionBarSize" />

</android.support.v7.widget.CardView>
Islam A. Hassan
fonte
Como isso pode funcionar se no cardview pré-pirulito se cobrir a fim de desenhar a sombra? Isto é o que eu recebo: i.imgur.com/BIj8env.png esta resposta funcionou para mim e não sofre com as desvantagens desta: stackoverflow.com/questions/26575197/…
Aspiring Dev
2
Na verdade, você é melhor fora com o AppBarLayout como nesta resposta stackoverflow.com/a/31026359/1451716 Minha resposta é velho, antes do AppBarLayout foi lançado
Islam A. Hassan
Isso é legal? Não é para ser usado com a Barra de Ferramentas. AMD!
user155
12

Se você estiver configurando o ToolBaras ActionBar, basta ligar para:

getSupportActionBar().setElevation(YOUR_ELEVATION);

Nota: Isso deve ser chamado após setSupportActionBar(toolbar);

Roberto B.
fonte
1
Sou eu ou a gaveta de navegação redefine a elevação da barra de ferramentas? Eu tentei defini-lo como 0 e funcionou, mas quando eu arrasto a gaveta de navegação, vejo que ela tem uma sombra novamente ...
desenvolvedor Android
6
setElevation()é definido apenas para API-21 +.
Subin Sebastian
@Sebastian A elevação da barra de ação de suporte também funciona para APIs anteriores.
Roberto B.
2
Internamente, isso usa ViewCompat.setElevation()e, portanto, funcionará apenas na API 21 ou superior.
botteaap
Use Android: windowContentOverlay ou Android: primeiro plano para menos de API 21.
radley
9

Eu adicionei

<android.support.v7.widget.Toolbar
...
android:translationZ="5dp"/>

na descrição da barra de ferramentas e funciona para mim. Usando 5.0+

Alex Mazur
fonte
7

Meu problema é que a barra de ferramentas não lança sombra se eu não definir o atributo "elevação". Esse é o comportamento normal ou estou fazendo algo errado?

Esse é o comportamento normal. Consulte também as perguntas frequentes no final deste post .

cigana
fonte
7

Estava brincando com isso por horas, eis o que funcionou para mim.

Remova todos os elevationatributos dos widgets appBarLayoute Toolbar(incluindo styles.xmlse você estiver aplicando algum estilo).

Agora dentro da atividade, aplique o elvationem seu actionBar:

Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setElevation(3.0f);

Isso deve funcionar.

Irshu
fonte
E se eu quiser a elevação no AppBarLayout, pois ela pode ser recolhida / expandida?
desenvolvedor android
1
setElevationaceita um parâmetro como pixels. Você precisa convertê-lo adequadamente, por exemplo:(int) (3.0 / Resources.getSystem().getDisplayMetrics().density)
Ely
4

Você também pode fazê-lo funcionar RelativeLayout. Isso reduz um pouco o layout do layout;)

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <include
        android:id="@+id/toolbar"
        layout="@layout/toolbar" />

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/toolbar" />

    <View
        android:layout_width="match_parent"
        android:layout_height="5dp"
        android:layout_below="@id/toolbar"
        android:background="@drawable/toolbar_shadow" />
</RelativeLayout>
iluu
fonte
3

Tudo que você precisa é android:margin_bottomigual ao android:elevationvalor. Não AppBarLayout, clipToPaddingetc. é necessário.

Exemplo:

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:layout_marginBottom="4dp"
    android:background="@android:color/white"
    android:elevation="4dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!--Inner layout goes here-->

    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.appcompat.widget.Toolbar>
Rohan Taneja
fonte
nada funcionou, exceto isso, bem no ponto e faz sentido também
DJphy 24/04
1

Para 5.0 +: você pode usar o AppBarLayout com a Barra de Ferramentas. AppBarLayout tem atributo "elevação".

 <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:elevation="4dp"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <include layout="@layout/toolbar" />
    </android.support.design.widget.AppBarLayout>
Eugene Lezov
fonte
E as versões anteriores?
desenvolvedor android
1

actionbar_background.xml

    <item>
        <shape>
            <solid android:color="@color/black" />
            <corners android:radius="2dp" />
            <gradient
                android:startColor="@color/black"
                android:centerColor="@color/black"
                android:endColor="@color/white"
                android:angle="270" />
        </shape>
    </item>

    <item android:bottom="3dp" >
        <shape>

            <solid android:color="#ffffff" />
            <corners android:radius="1dp" />
        </shape>
    </item>
</layer-list>

adicionar ao plano de fundo actionbar_style

<style name="Theme.ActionBar" parent="style/Widget.AppCompat.Light.ActionBar.Solid">
    <item name="background">@drawable/actionbar_background</item>
    <item name="android:elevation">0dp</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:layout_marginBottom">5dp</item>

name = "displayOptions"> useLogo | showHome | showTitle | showCustom

adicionar ao Basetheme

<style name="BaseTheme" parent="Theme.AppCompat.Light">
   <item name="android:homeAsUpIndicator">@drawable/home_back</item>
   <item name="actionBarStyle">@style/Theme.ActionBar</item>
</style>
Samet ÖZTOPRAK
fonte
1

A maioria das soluções funciona bem aqui. Gostaria de mostrar outra alternativa semelhante:

gradle:

implementation 'androidx.appcompat:appcompat:1.0.0-rc02'
implementation 'com.google.android.material:material:1.0.0-rc02'
implementation 'androidx.core:core-ktx:1.0.0-rc02'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

Seu layout pode ter uma Visualização da barra de ferramentas e uma sombra para ela, abaixo, semelhante a esta (é necessário modificar, é claro):

<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.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:titleTextAppearance="@style/Base.TextAppearance.Widget.AppCompat.Toolbar.Title"/>

    <include
        layout="@layout/toolbar_action_bar_shadow"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

res / drawable-v21 / toolbar_action_bar_shadow.xml

<androidx.appcompat.widget.AppCompatImageView
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="wrap_content" android:src="@drawable/msl__action_bar_shadow"/>

res / drawable / toolbar_action_bar_shadow.xml

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent" android:layout_height="wrap_content"
    android:foreground="?android:windowContentOverlay" tools:ignore="UnusedAttribute"/>

res / drawable / msl__action_bar_shadow.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <shape
            android:dither="true"
            android:shape="rectangle" >
            <gradient
                android:angle="270"
                android:endColor="#00000000"
                android:startColor="#33000000" />

            <size android:height="10dp" />
        </shape>
    </item>

</layer-list>

styles.xml

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
</resources>

MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        setSupportActionBar(toolbar as Toolbar)
    }
}

Exemplo completo aqui , como observei que o IDE tem um erro ao dizer que o foregroundatributo é muito novo para ser usado aqui.

desenvolvedor android
fonte
0

A resposta correta será adicionar
android: backgroundTint = "# ff00ff" à barra de ferramentas com android: background = "@ android: color / white"

Se você usar outra cor, em seguida, branco para o fundo, ela removerá a sombra. Bom Google!

user3193413
fonte