Ich aktualisiere meine App mit der neuen Toolbar aus der Support Library v21. Mein Problem ist, dass die Symbolleiste keinen Schatten wirft, wenn ich das Attribut "Elevation" nicht setze. Ist das das normale Verhalten oder mache ich etwas falsch?
Mein Code lautet:
<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">
.
.
.
Und in meiner Activity - OnCreate-Methode:
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
Ich habe am Ende meinen eigenen Schatten für die Symbolleiste gesetzt und dachte, es könnte für jeden hilfreich sein, der danach sucht:
<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>
Google hat vor einigen Wochen die Design-Support-Bibliothek veröffentlicht, und es gibt eine praktische Lösung für dieses Problem in dieser Bibliothek.
Fügen Sie die Design Support-Bibliothek als Abhängigkeit in build.gradle
hinzu:
compile 'com.Android.support:design:22.2.0'
Fügen Sie AppBarLayout
aus der Bibliothek als Wrapper um Ihr Toolbar
-Layout hinzu, um einen Schlagschatten zu erzeugen.
<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>
Hier ist das Ergebnis:
Es gibt viele andere Tricks mit der Design-Support-Bibliothek.
Sie können das Höhenattribut nicht vor API 21 (Android Lollipop) verwenden. Sie können den Schatten jedoch programmgesteuert hinzufügen, z. B. mithilfe einer benutzerdefinierten Ansicht, die sich unterhalb der Symbolleiste befindet.
@ Layout/Symbolleiste
<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>
in Ihrem Aktivitätslayout <include layout="@layout/toolbar" />
Verwenden Sie die Ordner / values, um den korrekten Schattenstil basierend auf der Betriebssystemversion anzuwenden.
Verwenden Sie für Geräte unter 5.0 _ /values/styles.xml, um windowContentOverlay zum Hauptteil Ihrer Aktivität hinzuzufügen:
<style name="MyViewArea">
<item name="Android:foreground">?android:windowContentOverlay</item>
</style>
<style name="MyToolbar">
<item name="Android:background">?attr/colorPrimary</item>
</style>
Fügen Sie dann Ihren eigenen benutzerdefinierten Schatten hinzu, indem Sie das Design wie folgt ändern:
<item name="Android:windowContentOverlay">@drawable/bottom_shadow</item>
Hier können Sie die App-Schattenressource IO von Google herunterladen: https://github.com/google/iosched/blob/master/Android/src/main/res/drawable-xxhdpi/bottom_shadow.9.png
Für 5.0-Geräte und höher verwenden Sie /values-v21/styles.xml, um Elevation mit einem benutzerdefinierten Header-Stil zu Ihrer Symbolleiste hinzuzufügen:
<style name="MyViewArea">
</style>
<style name="MyToolbar">
<item name="Android:background">?attr/colorPrimary</item>
<item name="Android:elevation">4dp</item>
</style>
Beachten Sie, dass im zweiten Fall ein leerer MyViewArea -Stil erstellt werden musste, damit das windowContentOverlay ebenfalls nicht angezeigt wurde.
[Update: Ressourcennamen geändert und Google Shadow hinzugefügt.]
Das hat für mich sehr gut funktioniert:
<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>
Wenn Sie die ToolBar
als ActionBar
setzen, rufen Sie einfach auf:
getSupportActionBar().setElevation(YOUR_ELEVATION);
Hinweis: Dies muss nach setSupportActionBar(toolbar);
aufgerufen werden.
Mein Problem ist, dass die Symbolleiste keinen Schatten wirft, wenn ich das Attribut "Elevation" nicht setze. Ist das das normale Verhalten oder mache ich etwas falsch?
Das ist das normale Verhalten. Siehe auch die FAQ am Ende von diesem Beitrag .
War stundenlang damit zu spielen, hier hat sich was für mich herausgestellt.
Entfernen Sie alle elevation
-Attribute aus den Widgets appBarLayout
und Toolbar
(einschließlich styles.xml
, wenn Sie ein Styling anwenden).
Wenden Sie jetzt in der Aktivität die elvation
auf Ihre actionBar
an:
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setElevation(3.0f);
Das sollte funktionieren.
Sie können es auch mit RelativeLayout
zum Laufen bringen. Dies reduziert die Verschachtelung des Layouts etwas;)
<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>
ich fügte hinzu
<Android.support.v7.widget.Toolbar
...
Android:translationZ="5dp"/>
in der Symbolleistenbeschreibung und es funktioniert für mich . Mit 5.0+
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>
zu actionbar_style Hintergrund hinzufügen
<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
zu Basetheme hinzufügen
<style name="BaseTheme" parent="Theme.AppCompat.Light">
<item name="Android:homeAsUpIndicator">@drawable/home_back</item>
<item name="actionBarStyle">@style/Theme.ActionBar</item>
</style>
Die meisten Lösungen funktionieren hier gut. Möchte eine andere, ähnliche Alternative zeigen:
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'
Ihr Layout kann eine Toolbar-Ansicht und einen Schatten dafür haben, ähnlich wie hier (Änderungen müssen natürlich vorgenommen werden):
<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)
}
}
Vollständiges Beispiel hier , wie ich bemerkt habe, dass IDE einen Fehler besagt, dass das foreground
-Attribut zu neu ist, um hier verwendet zu werden.
Sie benötigen lediglich einen Android:margin_bottom
, der dem Android:elevation
-Wert entspricht. Keine AppBarLayout
, clipToPadding
usw. erforderlich.
Beispiel:
<?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>
Ich hatte ein ähnliches Problem mit dem Schatten. Der Schatten wird in meinem Fall von direkten Eltern von AppBarLayout gezeichnet. Wenn die Höhe des übergeordneten Elements der von AppBarLayout entspricht, kann der Schatten nicht gezeichnet werden. Durch Überprüfen der Größe des übergeordneten Layouts und möglicherweise eines Layout-Remakes kann das Problem gelöst werden. https://www.reddit.com/r/androiddev/comments/6xddb0/having_a_toolbar_as_a_fragment_the_shadow/
Die richtige Antwort wird sein, hinzuzufügen
Android: backgroundTint = "# ff00ff" zur Symbolleiste mit Android: background = "@ Android: color/white"
Wenn Sie für den Hintergrund eine andere Farbe als Weiß verwenden, wird der Schatten entfernt. Nizza ein Google!
Für 5.0 +: Sie können AppBarLayout mit der Symbolleiste verwenden. AppBarLayout verfügt über eine Höhenangabe.
<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>