Tidak ada bayangan secara default di Toolbar?


165

Saya memperbarui aplikasi saya dengan Toolbar baru dari perpustakaan dukungan v21. Masalah saya adalah bahwa bilah alat tidak menampilkan bayangan apa pun jika saya tidak menetapkan atribut "elevasi". Apakah itu perilaku normal atau saya melakukan sesuatu yang salah?

Kode saya adalah:

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

Dan dalam Aktivitas saya - Metode OnCreate:

    Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
    setSupportActionBar(toolbar);

Apakah Anda melihat ini pada perangkat yang menjalankan Lollipop?
rlay3

3
Pada perangkat yang menjalankan Lollipop menunjukkan bayangan karena atribut elevasi tetapi tidak pada KitKat atau versi yang lebih lama. Itulah perilaku yang diharapkan untuk atribut elevasi seperti yang dikatakan oleh dokumentasi, tetapi saya mengharapkan, secara default tanpa atribut elevasi, bayangan akan ditampilkan seperti halnya Action Bar pada setiap versi.
MrBrightside

Saya memposting solusi yang mungkin di sini: stackoverflow.com/a/26759202/553905
Billy

Gunakan / nilai folder dan styles.xml untuk menerapkan kode bayangan yang tepat berdasarkan versi OS (lihat di bawah).
radley

Jawaban:


252

Saya akhirnya menetapkan drop shadow saya sendiri untuk bilah alat, berpikir mungkin bermanfaat bagi siapa pun yang mencarinya:

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

masukkan deskripsi gambar di sini


3
Jangan lupa sembunyikan tampilan Anda jika perangkat yang Anda jalankan>> ke Lollipop, jika tidak, Anda akan berakhir dengan dua bayangan.
mradzinski

1
Ini adalah cara yang salah untuk itu karena Anda harus menghapus tampilan itu untuk tata letak 5.0. Gunakan android: windowContentOverlay atau android: foreground sebagai gantinya.
radley

3
Dari Google tentang mendesain desain materi Toolbar , Anda harus menetapkan android:layout_height="4dp"ketinggian bayangan, alih-alih 5dp. Sebenarnya, ketinggian sama dengan ketinggian bayangan yang Anda atur FrameLayout.
Anggrayudi H

2
Saya mengalami masalah dengan solusi ini karena saya mengembang tata letak kegiatan saya ke tata letak bingkai dalam contoh Anda, dapatkah Anda memikirkan cara agar ini bekerja?
Zach Sperske

2
Merekomendasikan menggunakan "android: endColor =" # c7c7c7 "melalui android: endColor =" # 88333333 "
Mohammad Faisal

211

Google merilis perpustakaan Dukungan Desain beberapa minggu yang lalu dan ada solusi bagus untuk masalah ini di perpustakaan ini.

Tambahkan pustaka Dukungan Desain sebagai ketergantungan di build.gradle:

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

Tambahkan yang AppBarLayoutdisediakan oleh perpustakaan sebagai pembungkus di sekitar Toolbartata letak Anda untuk menghasilkan drop shadow.

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

Inilah hasilnya:

masukkan deskripsi gambar di sini

Ada banyak trik lain dengan perpustakaan dukungan desain.

  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

Seperti di atas tetapi dengan ketergantungan:

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

dan com.google.android.material.appbar.AppBarLayout


26
Mengatur AppBarLayoutsebagai pembungkus di sekitar Toolbartidak mengatur bayangan untuk saya. Perhatikan bahwa saya tidak menggunakan laci navigasi. Ada ide mengapa itu tidak berhasil?
avb

@ avb1994 Tidak bisa mengatakan dengan pasti, saya telah mengujinya tanpa laci nav. Bisakah Anda mempostingnya sebagai pertanyaan dengan file tata letak?
Binoy Babu

lihat pertanyaan saya: stackoverflow.com/questions/31115531/… terima kasih atas komentar Anda
avb

2
Anda tidak memerlukan kompilasi dua baris ini 'com.android.support:support-v4:22.2.0' compile 'com.android.support:appcompat-v7:22.2.0', karena kompilasi 'com.android.support: desain: 22.2.0 'tergantung pada mereka
Andrey

8
Perhatikan ini hanya berfungsi untuk lollipop dan yang lebih tinggi. Ini tidak akan berfungsi pre lollipop karena di bawahnya hanya menggunakan ViewCompat.setElevation ().
Amirul Zin

25

Anda tidak dapat menggunakan atribut elevasi sebelum API 21 (Android Lollipop). Namun Anda dapat menambahkan bayangan secara pemrograman, misalnya menggunakan tampilan khusus yang ditempatkan di bawah Bilah Alat.

@ tata letak / bilah alat

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

dalam tata letak aktivitas Anda <include layout="@layout/toolbar" />

masukkan deskripsi gambar di sini


2
Bisakah Anda memperbaiki @layout/toolbarcontoh dengan file layout penuh?
Daniel Gomez Rico

1
Mengapa @ layout / toolbar memiliki dua tampilan root? Bisakah Anda memberikan contoh lengkapnya?
RED_

18

Gunakan / nilai folder untuk menerapkan gaya bayangan yang benar berdasarkan versi OS.

Untuk perangkat di bawah 5.0 , gunakan /values/styles.xml untuk menambahkan windowContentOverlay ke tubuh aktivitas Anda:

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

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

Kemudian tambahkan bayangan kustom Anda sendiri dengan mengubah Tema Anda untuk memasukkan:

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

Anda dapat mengambil sumber bayangan aplikasi Google IO di sini: https://github.com/google/iosched/blob/master/android/src/main/res/drawable-xxhdpi/bottom_shadow.9.png

Untuk 5.0 perangkat & yang lebih baru , gunakan /values-v21/styles.xml untuk menambahkan elevasi ke toolbar Anda menggunakan gaya header khusus:

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

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

Perhatikan bahwa dalam kasus kedua, saya harus membuat gaya MyViewArea kosong sehingga windowContentOverlay tidak akan muncul juga.

[Perbarui: mengubah nama sumber daya dan menambahkan Google shadow.]


Bolehkah saya tahu apa itu MyBody dan MyHeader? Di mana saya harus menerapkannya?
Cheok Yan Cheng

Saya memperbarui nama: MyHeader sekarang MyToolbar dan MyBody adalah MyViewArea. Anda dapat menetapkan gaya dalam tata letak xml seperti ini: style = "@ style / MyToolbar".
Radley

Apa yang diterapkan MyViewArea?
Zach Sperske

Halaman / tubuh / area tampilan Anda.
radley

Saya pikir android:foregroundhanya bekerja di FrameLayout sebelum API 23.
androidguy

14

Ini bekerja dengan baik untuk saya:

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

Bagaimana ini bisa berfungsi jika pada pre lollipop cardview pad sendiri untuk menggambar bayangan? Inilah yang saya dapatkan: i.imgur.com/BIj8env.png jawaban ini bekerja untuk saya dan tidak mengalami kekurangan dari yang ini: stackoverflow.com/questions/26575197/…
Aspiring Dev

2
Sebenarnya, Anda lebih baik dengan AppBarLayout seperti dalam jawaban ini stackoverflow.com/a/31026359/1451716 Jawaban saya sudah tua, sebelum AppBarLayout dirilis
Islam A. Hassan

Apakah ini sah? Seharusnya tidak digunakan dengan Toolbar. OH TUHAN!
user155

12

Jika Anda seting yang ToolBarsebagai ActionBarkemudian hanya menyebut:

getSupportActionBar().setElevation(YOUR_ELEVATION);

Catatan: Ini harus dipanggil setelah setSupportActionBar(toolbar);


1
Apakah hanya saya, atau apakah laci navigasi mengatur ulang ketinggian bilah alat? Saya sudah mencoba untuk mengaturnya ke 0, dan itu berhasil, tetapi kemudian ketika saya seret laci navigasi, saya melihatnya memiliki bayangan lagi ...
pengembang android

6
setElevation()didefinisikan hanya untuk API-21 +.
Subin Sebastian

@Sebastian Elevasi actionbar dukungan juga berfungsi untuk API sebelumnya.
Roberto B.

2
Secara internal yang menggunakan ViewCompat.setElevation()dan hanya akan bekerja pada API 21 dan lebih tinggi.
botteaap

Gunakan android: windowContentOverlay atau android: foreground untuk di bawah API 21.
radley

9

saya tambahkan

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

dalam deskripsi bilah alat dan berfungsi untuk saya. Menggunakan 5.0+


7

Masalah saya adalah bahwa bilah alat tidak menampilkan bayangan apa pun jika saya tidak menetapkan atribut "elevasi". Apakah itu perilaku normal atau saya melakukan sesuatu yang salah?

Itu perilaku normal. Lihat juga FAQ di akhir posting ini .


7

Bermain-main dengan ini selama berjam-jam, inilah yang bekerja untuk saya.

Hapus semua elevationatribut dari widget appBarLayoutdan Toolbar(termasuk styles.xmljika Anda menerapkan gaya apa pun).

Sekarang di dalam aktivitas, terapkan elvationpada actionBar:

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

Ini seharusnya bekerja.


Bagaimana jika saya ingin ketinggian AppBarLayout, karena bisa runtuh / meluas?
pengembang android

1
setElevationmengambil parameter sebagai piksel. Anda harus mengonversinya dengan tepat, misalnya(int) (3.0 / Resources.getSystem().getDisplayMetrics().density)
Ely

4

Anda juga bisa membuatnya bekerja RelativeLayout. Ini sedikit mengurangi tata letak bersarang;)

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

3

Yang Anda butuhkan adalah android:margin_bottomsama dengan android:elevationnilainya. Tidak AppBarLayout,, clipToPaddingdll. Diperlukan.

Contoh:

<?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>

tidak ada yang berhasil, kecuali ini, tepat pada titik dan masuk akal juga
DJphy

1

Untuk 5.0 +: Anda dapat menggunakan AppBarLayout dengan Bilah Alat. AppBarLayout memiliki atribut "elevasi".

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

Bagaimana dengan versi sebelumnya?
pengembang 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>

tambahkan ke latar belakang 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

tambahkan ke Basetheme

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

1

Sebagian besar solusi berfungsi dengan baik di sini. Ingin menampilkan alternatif lain yang serupa:

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'

Tata letak Anda dapat memiliki Tampilan Bilah Alat, dan bayangan untuk itu, di bawah, mirip dengan ini (perlu modifikasi tentu saja):

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

Contoh lengkap di sini , karena saya perhatikan bahwa IDE memiliki bug untuk mengatakan foregroundatribut terlalu baru untuk digunakan di sini.



0

Jawaban yang benar adalah menambahkan
android: backgroundTint = "# ff00ff" ke bilah alat dengan android: background = "@ android: color / white"

Jika Anda menggunakan warna lain maka putih untuk latar belakang itu akan menghapus bayangan. Bagus sekali Google!

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.