Không có bóng theo mặc định trên Thanh công cụ?


165

Tôi đang cập nhật ứng dụng của mình với Thanh công cụ mới từ thư viện hỗ trợ v21. Vấn đề của tôi là thanh công cụ không tạo bóng bất kỳ nếu tôi không đặt thuộc tính "độ cao". Đó có phải là hành vi bình thường hay tôi đang làm gì đó sai?

Mã của tôi là:

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

Và trong Hoạt động của tôi - phương pháp OnCreate:

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

Bạn có thấy điều này trên một thiết bị chạy Lollipop?
rlay3

3
Trên thiết bị chạy Lollipop hiển thị bóng vì thuộc tính độ cao nhưng không có trên KitKat hoặc các phiên bản cũ hơn. Đó là hành vi dự kiến ​​cho thuộc tính độ cao như tài liệu nói, nhưng tôi đã hy vọng rằng, theo mặc định không có thuộc tính độ cao, bóng sẽ tạo ra giống như Action Bar trên mọi phiên bản.
MrBrightside

Tôi đã đăng một giải pháp khả thi tại đây: stackoverflow.com/a/26759202/553905
Billy

Sử dụng / giá trị thư mục và tệp kiểu tệp để áp dụng mã bóng phù hợp dựa trên phiên bản HĐH (xem bên dưới).
radley

Câu trả lời:


252

Tôi đã kết thúc việc thiết lập bóng thả của riêng mình cho thanh công cụ, nghĩ rằng nó có thể hữu ích cho bất cứ ai tìm kiếm nó:

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

@ màu / màu_alizarin

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

nhập mô tả hình ảnh ở đây


3
Đừng quên ẩn chế độ xem của bạn nếu thiết bị bạn đang chạy là> = to Lollipop, nếu không, bạn sẽ kết thúc với hai bóng.
mradzinski

1
Đây là cách sai đối với nó bởi vì bạn sẽ phải xóa chế độ xem đó cho 5.0 bố cục. Sử dụng android: windowContentOverlay hoặc android: foreground thay thế.
radley

3
Từ Google về thiết kế thiết kế vật liệu Thanh công cụ , bạn nên đặt android:layout_height="4dp"chiều cao của bóng, thay vì 5dp. Trên thực tế, độ cao giống như chiều cao của bóng bạn đặt FrameLayout.
Anggrayudi H

2
Tôi gặp rắc rối với giải pháp này vì tôi tăng bố cục hoạt động của mình vào bố cục khung trong ví dụ của bạn, bạn có thể nghĩ ra cách nào để nó hoạt động không?
Zach Sperske

2
Đề xuất sử dụng "android: endColor =" # c7c7c7 "trên android: endColor =" # 88333333 "
Mohammad Faisal

211

Google đã phát hành thư viện Hỗ trợ thiết kế một vài tuần trước và có một giải pháp tiện lợi cho vấn đề này trong thư viện này.

Thêm thư viện Hỗ trợ thiết kế làm phụ thuộc trong build.gradle:

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

Thêm AppBarLayoutđược cung cấp bởi thư viện dưới dạng một trình bao bọc xung quanh Toolbarbố cục của bạn để tạo bóng đổ.

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

Đây là kết quả:

nhập mô tả hình ảnh ở đây

Có rất nhiều thủ thuật khác với thư viện hỗ trợ thiết kế.

  1. http://inthecheesefactory.com/blog/android-design-support-l Library-cadelab / vi
  2. http://android-developers.blogspot.in/2015/05/android-design-support-l Library.html

AndroidX

Như trên nhưng với sự phụ thuộc:

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

com.google.android.material.appbar.AppBarLayout


26
Đặt AppBarLayouttrình bao bọc xung quanh Toolbarkhông đặt bất kỳ bóng nào cho tôi. Lưu ý rằng tôi không sử dụng ngăn kéo điều hướng. Bất cứ ý tưởng về lý do tại sao nó không hoạt động?
avb

@ avb1994 Không thể nói chắc chắn, tôi đã kiểm tra nó mà không có ngăn kéo điều hướng. Bạn có thể gửi nó như một câu hỏi với tập tin bố trí?
Binoy Babu

xem câu hỏi của tôi: stackoverflow.com/questions/31115531/ Cảm ơn vì nhận xét của bạn
avb

2
Bạn không cần hai dòng này biên dịch 'com.android.support:support-v4:22.2.0' biên dịch 'com.android.support:appcompat-v7:22.2.0', vì biên dịch 'com.android.support: thiết kế: 22.2.0 'phụ thuộc vào họ
Andrey

8
Hãy lưu ý điều này chỉ hoạt động cho kẹo mút trở lên. Nó sẽ không hoạt động trước kẹo mút vì bên dưới nó chỉ sử dụng ViewCompat.setElevation ().
Amirul Zin

25

Bạn không thể sử dụng thuộc tính độ cao trước API 21 (Android Lollipop). Tuy nhiên, bạn có thể thêm bóng theo chương trình, ví dụ: bằng cách sử dụng chế độ xem tùy chỉnh được đặt bên dưới Thanh công cụ.

@ bố trí / thanh công cụ

<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 / thanh công cụ_showshadow

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

trong cách bố trí hoạt động của bạn <include layout="@layout/toolbar" />

nhập mô tả hình ảnh ở đây


2
Bạn có thể sửa @layout/toolbarví dụ với tập tin bố trí đầy đủ?
Daniel Gomez Rico

1
Tại sao @ layout / thanh công cụ có hai chế độ xem gốc? Bạn có thể cung cấp ví dụ đầy đủ xin vui lòng?
ĐỎ_

18

Sử dụng / giá trị thư mục để áp dụng kiểu bóng chính xác dựa trên phiên bản HĐH.

Đối với các thiết bị dưới 5.0 , hãy sử dụng /values/styles.xml để thêm windowContentOverlay vào phần hoạt động của bạn:

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

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

Sau đó thêm bóng tùy chỉnh của riêng bạn bằng cách thay đổi Chủ đề của bạn để bao gồm:

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

Bạn có thể lấy tài nguyên bóng của ứng dụng IO của Google tại đây: https://github.com/google/iosched/blob/master/android/src/main/res/drawable-xxhdpi/bottom_shadow.9.png

Đối với các thiết bị 5.0 trở lên , hãy sử dụng /values-v21/styles.xml để thêm độ cao vào thanh công cụ của bạn bằng cách sử dụng kiểu tiêu đề tùy chỉnh:

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

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

Lưu ý rằng trong trường hợp thứ hai, tôi phải tạo kiểu MyViewArea trống để windowContentOverlay cũng không hiển thị.

[Cập nhật: đã thay đổi tên tài nguyên và thêm bóng Google.]


Tôi có thể biết MyBody và MyHeader là gì không? Tôi nên áp dụng chúng ở đâu?
Cheok Yan Cheng

Tôi đã cập nhật tên: MyHeader bây giờ là MyToolbar và MyBody là MyViewArea. Bạn có thể gán kiểu trong bố cục xml như thế này: style = "@ style / MyToolbar".
radley

MyViewArea được áp dụng cho cái gì?
Zach Sperske 01/07/2015

Trang / cơ thể / khu vực xem của bạn.
radley

Tôi nghĩ rằng android:foregroundchỉ hoạt động trên FrameLayout trước API 23.
androidguy

14

Điều này làm việc cho tôi rất tốt:

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

Làm thế nào điều này có thể làm việc nếu trên tấm lót cardview kẹo mút trước để vẽ bóng? Đây là những gì tôi nhận được: i.imgur.com/BIj8env.png câu trả lời này có hiệu quả với tôi và nó không phải chịu những hạn chế từ điều này: stackoverflow.com/questions/26575197/
Devires Dev

2
Trên thực tế, bạn tốt hơn với AppBarLayout như trong câu trả lời này stackoverflow.com/a/31026359/1451716 Câu trả lời của tôi đã cũ, trước khi AppBarLayout được phát hành
Hồi giáo A. Hassan

Điều này thậm chí là hợp pháp? Nó không được sử dụng với Thanh công cụ. CHÚA ƠI!
dùng155

12

Nếu bạn đang thiết lập ToolBarnhư vậy ActionBarthì chỉ cần gọi:

getSupportActionBar().setElevation(YOUR_ELEVATION);

Lưu ý: Điều này phải được gọi sau setSupportActionBar(toolbar);


1
Có phải chỉ mình tôi hay ngăn kéo điều hướng đặt lại độ cao của thanh công cụ? Tôi đã cố gắng đặt nó thành 0 và nó đã hoạt động, nhưng sau đó khi tôi kéo ngăn điều hướng, tôi thấy nó có bóng một lần nữa ...
nhà phát triển Android

6
setElevation()chỉ được định nghĩa cho API-21 +.
Subin Sebastian

@Sebastian Độ cao của thanh hành động hỗ trợ cũng hoạt động cho các API trước đó.
Roberto B.

2
Trong nội bộ sử dụng ViewCompat.setElevation()và do đó sẽ chỉ hoạt động trên API 21 trở lên.
chạm đáy

Sử dụng android: windowContentOverlay hoặc android: foreground cho theo API 21.
radley

9

Tôi đã thêm

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

trong mô tả thanh công cụ và nó hoạt động cho tôi. Sử dụng 5.0+


7

Vấn đề của tôi là thanh công cụ không tạo bóng bất kỳ nếu tôi không đặt thuộc tính "độ cao". Đó có phải là hành vi bình thường hay tôi đang làm gì đó sai?

Đó là hành vi bình thường. Cũng xem Câu hỏi thường gặp ở cuối bài này .


7

Đã đùa giỡn với điều này trong nhiều giờ, đây là những gì làm việc cho tôi.

Xóa tất cả các elevationthuộc tính khỏi appBarLayoutToolbarcác widget (bao gồm cả styles.xmlnếu bạn đang áp dụng bất kỳ kiểu dáng nào).

Bây giờ trong hoạt động, áp dụng elvationtrên actionBar:

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

Điều này nên làm việc.


Điều gì xảy ra nếu tôi muốn độ cao trên AppBarLayout, vì nó có thể sụp đổ / mở rộng?
nhà phát triển Android

1
setElevationlấy một tham số là pixel. Bạn cần phải chuyển đổi nó một cách thích hợp, ví dụ như(int) (3.0 / Resources.getSystem().getDisplayMetrics().density)
Ely

4

Bạn cũng có thể làm cho nó hoạt động với RelativeLayout. Điều này làm giảm bố cục lồng nhau một chút;)

<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

Tất cả bạn cần là một android:margin_bottomtương đương với android:elevationgiá trị. Không AppBarLayout, clipToPaddingvv yêu cầu.

Thí dụ:

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

không có gì hoạt động, ngoại trừ điều này, đúng điểm và cũng có ý nghĩa
DJphy

1

Đối với 5.0 +: Bạn có thể sử dụng AppBarLayout với Thanh công cụ. AppBarLayout có sự "nâng cao".

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

Còn các phiên bản trước thì sao?
nhà phát triển 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>

thêm vào nền 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

thêm vào 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

Hầu hết các giải pháp hoạt động tốt ở đây. Muốn hiển thị khác, thay thế tương tự:

lớp:

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'

Bố cục của bạn có thể có Chế độ xem Thanh công cụ và bóng cho nó, bên dưới, tương tự như thế này (tất nhiên cần sửa đổi):

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

kiểu tệp

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

ChínhActivity.kt

class MainActivity : AppCompatActivity() {

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

Mẫu đầy đủ ở đây , vì tôi nhận thấy IDE có lỗi nói foregroundthuộc tính quá mới để sử dụng ở đây.


0

Tôi đã có vấn đề tương tự với cái bóng. Cái bóng được vẽ bởi cha mẹ trực tiếp của AppBarLayout trong trường hợp của tôi. Nếu chiều cao của cha mẹ giống với AppBarLayout thì bóng không thể được vẽ. Vì vậy, kiểm tra kích thước của bố trí cha mẹ và có thể bố trí lại có thể giải quyết vấn đề. https://www.reddit.com/r/androiddev/comments/6xddb0/having_a_toolbar_as_a_fragment_the_shadow/


0

Câu trả lời đúng sẽ là thêm
android: backgroundTint = "# ff00ff" vào thanh công cụ với android: background = "@ android: color / white"

Nếu bạn sử dụng màu khác thì màu trắng cho nền nó sẽ xóa bóng. Rất vui!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.