Nâng cao Android không hiển thị bóng


273

Tôi có một ListView và với mỗi mục danh sách tôi muốn nó hiển thị một bóng bên dưới nó. Tôi đang sử dụng tính năng nâng cao mới của Android Lollipop để đặt Z trên Chế độ xem mà tôi muốn tạo bóng và hiện đang thực hiện điều này một cách hiệu quả với ActionBar (về mặt kỹ thuật là Thanh công cụ trong Lollipop). Tôi đang sử dụng độ cao của Lollipop, nhưng vì một số lý do, nó không hiển thị bóng dưới các mục danh sách. Đây là cách bố trí của từng mục danh sách được thiết lập:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    style="@style/block"
    android:gravity="center"
    android:layout_gravity="center"
    android:background="@color/lightgray"
    >

    <RelativeLayout
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_marginLeft="40dp"
        android:layout_marginRight="40dp"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:elevation="30dp"
        >

        <ImageView
            android:id="@+id/documentImageView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop" />

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/alphared"
            android:layout_alignParentBottom="true" >

            <appuccino.simplyscan.Extra.CustomTextView
                android:id="@+id/documentName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/white"
                app:typeface="light"
                android:paddingLeft="16dp"
                android:paddingTop="8dp"
                android:paddingBottom="4dp"
                android:singleLine="true"
                android:text="New Document"
                android:textSize="27sp"/>

            <appuccino.simplyscan.Extra.CustomTextView
                android:id="@+id/documentPageCount"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/white"
                app:typeface="italic"
                android:paddingLeft="16dp"
                android:layout_marginBottom="16dp"
                android:text="1 page"
                android:textSize="20sp"/>

        </LinearLayout>

    </RelativeLayout>

</RelativeLayout>

Tuy nhiên, đây là cách nó hiển thị mục danh sách, không có bóng: nhập mô tả hình ảnh ở đây

Tôi cũng đã thử những cách sau nhưng không có kết quả:

  1. Đặt độ cao cho ImageView và TextViews thay vì bố trí cha.
  2. Áp dụng một nền tảng cho ImageView.
  3. Sử dụng dịchZ thay cho độ cao.

Tôi đã thử bố cục của bạn (không có tùy chỉnh) và hiển thị bóng trong điện thoại của tôi, bạn có thể chia sẻ một dự án tối thiểu để tái tạo vấn đề không?
rnrneverdies

1
bản sao có thể của Android L FAB Nút bóng
naveejr

Câu trả lời:


383

Tôi đã chơi xung quanh với bóng trên Lollipop một chút và đây là những gì tôi đã tìm thấy:

  1. Có vẻ như ViewGroupgiới hạn của cha mẹ đã cắt bỏ cái bóng của con cái vì một số lý do; và
  2. các bóng được thiết lập android:elevationbị cắt bởi các Viewgiới hạn, không phải các giới hạn được mở rộng qua lề;
  3. Cách đúng để có được chế độ xem con để hiển thị bóng là đặt phần đệm trên cha mẹ và đặt android:clipToPadding="false"vào phần cha mẹ đó.

Đây là gợi ý của tôi cho bạn dựa trên những gì tôi biết:

  1. Đặt cấp cao nhất của bạn RelativeLayoutđể có phần đệm bằng với lề bạn đã đặt trên bố cục tương đối mà bạn muốn hiển thị bóng;
  2. đặt android:clipToPadding="false"trên cùng RelativeLayout;
  3. Loại bỏ lề từ RelativeLayoutđó cũng có bộ độ cao;
  4. [EDIT] bạn cũng có thể cần đặt màu nền không trong suốt trên bố cục con cần độ cao.

Vào cuối ngày, bố cục tương đối cấp cao nhất của bạn sẽ trông như thế này:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/block"
    android:gravity="center"
    android:layout_gravity="center"
    android:background="@color/lightgray"
    android:paddingLeft="40dp"
    android:paddingRight="40dp"
    android:paddingTop="20dp"
    android:paddingBottom="20dp"
    android:clipToPadding="false"
    >

Bố cục tương đối bên trong sẽ trông như thế này:

<RelativeLayout
    android:layout_width="300dp"
    android:layout_height="300dp"
    android:background="[some non-transparent color]"
    android:elevation="30dp"
    >

8
Cảm ơn vì điều đó! Tôi cũng thấy android: clipChildren = "false" hữu ích khi áp dụng cho bố cục tương đối cha mẹ.
blaffie 11/03/2015

1
Rất vui khi được giúp đỡ @blaffie!
Justin Pollard

214
Thật khó chịu khi Google tạo ra mã kém chất lượng như vậy. Chúng tôi sẽ phải tính đến các lỗi khung này trong nhiều năm.
miguel

8
Google chỉ nói (than ôi): " Bóng được vẽ bởi cha mẹ của chế độ xem nâng cao và do đó phải chịu cắt xén chế độ xem tiêu chuẩn, được cắt bởi phụ huynh theo mặc định. ".
Giăng

5
Trong trường hợp của tôi đó là màu trong suốt. Ok, những thứ trong suốt không đổ bóng ... haha
Ferran Maylinch

285

Nếu bạn có chế độ xem không có nền, dòng này sẽ giúp bạn

android:outlineProvider="bounds"

Theo mặc định, bóng được xác định bởi nền của chế độ xem, vì vậy nếu không có nền, thì cũng sẽ không có bóng.


11
Thật là một điều kỳ lạ, Bản xem trước cho thấy độ cao nhưng thiết bị thực sự thì không. Cảm ơn, cái này đã khắc phục vấn đề.
Ioane Sharvadze

Hoạt động cho API cấp 21 trở lên
Pantelis Ieronimakis

10
Kiểu này hoạt động với tôi, nhưng đưa ra một đường viền chéo ở hai bên khi áp dụng cho một textview. Đặt nền thành màu (giống như màu nền của cha mẹ) hoạt động tốt hơn.
Gober

4
Điều này cũng áp dụng nếu nền của bạn là tùy chỉnh và không có <solid>.
David Lord

Điều này có thể được sử dụng ngược lại. Khi bạn muốn một nền không trong suốt với độ cao và không muốn bóng. Đơn giản chỉ cần đặt nó vào none. Cảm ơn!
Odys

101

Rõ ràng, bạn không thể chỉ đặt độ cao trên Chế độ xem và xuất hiện. Bạn cũng cần xác định một nền tảng.

Các dòng sau được thêm vào linearLayout của tôi cuối cùng đã hiển thị một bóng:

android:background="@android:color/white"
android:elevation="10dp"

Thật là không ngờ. Tôi đã thiết lập ImageView với src và đang tìm giải pháp. Cảm ơn bạn.
Andrew Grow

47

Một điều khác mà bạn cần lưu ý, bóng sẽ không hiển thị nếu bạn có dòng này trong bảng kê khai:

android: phần cứngAccelerated = "sai"

Tôi đã thử tất cả những thứ được đề xuất nhưng nó chỉ hoạt động với tôi khi tôi xóa dòng này, lý do tôi có dòng này là vì ứng dụng của tôi hoạt động với một số hình ảnh bitmap và chúng đã khiến ứng dụng bị sập.


1
Điều này không giải quyết được vấn đề, nếu bạn cần có cờ đó.
Clive Jefferies

cảm ơn bạn!! Tôi đã dành một ngày cố gắng nâng cao AppBar và tìm thấy sự cố khi tôi kiểm tra bảng kê khai cho cờ hoạt động này
ir2pid

1
Tôi đã thử tất cả các giải pháp có thể, nhưng không có công việc nào cho tôi. Giải pháp này đã làm việc. Cảm ơn. Cũng cần android:clipToPadding="false"với giải pháp này.
Chirag Savsani

29

Nếu bạn có chế độ xem không có nền, dòng này sẽ giúp bạn

android:outlineProvider="bounds"

Nếu bạn có chế độ xem với nền, dòng này sẽ giúp bạn

android:outlineProvider="paddedBounds"

6
Giải pháp này là duy nhất làm việc cho tôi. Cảm ơn bạn
Oleh Liskovych

4
Điều này hoạt động trừ khi bạn có bán kính trên nền chế độ xem, trong trường hợp đó, bóng sẽ hiển thị dưới dạng hình chữ nhật, nhưng paddedBound không hoạt động cho chế độ xem với nền.
Trevor Hart

android:outlineProvider="paddedBounds"dòng này làm việc cho tôi. Tôi đặt Selector Drawable.
Chirag Savsani

1
Khi tôi sử dụng cái này, bóng được vẽ hoàn toàn bên trong khung nhìn chứ không phải bên ngoài, đó không phải là thứ tôi muốn.
androidguy


12

Ugh, chỉ mất một giờ cố gắng để tìm ra điều này. Trong trường hợp của tôi, tôi đã có một bộ nền, tuy nhiên nó được đặt thành một màu. Điều này là không đủ, bạn cần phải có nền của chế độ xem được đặt thành có thể vẽ được.

ví dụ: Điều này sẽ không có bóng:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="165dp"
    android:background="@color/ight_grey"
    android:elevation="20dp"
    android:orientation="vertical"
    />

nhưng điều này sẽ

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="165dp"
    android:background="@drawable/selector_grey"
    android:elevation="20dp"
    android:orientation="vertical"
    />

EDIT: Cũng đã phát hiện ra rằng nếu bạn sử dụng bộ chọn làm nền, nếu bạn không đặt góc thì bóng sẽ không hiển thị trong cửa sổ Xem trước nhưng nó sẽ hiển thị trên thiết bị

ví dụ: Điều này không có bóng trong bản xem trước:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
            <stroke
                android:width="1dp"
                android:color="@color/grey"/>
        </shape>
    </item>
</selector>

nhưng điều này không:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
            <corners android:radius="1dp" />
            <stroke
                android:width="1dp"
                android:color="@color/grey"/>
        </shape>
    </item>
</selector>

1
Trái ngược hoàn toàn với quan điểm đầu tiên của bạn là đúng với tôi trong mục RecyclerView ... Thật đáng ngạc nhiên khi tôi vẫn thấy các trường hợp phải chiến đấu với các API này sau 5 năm phát triển Android chuyên nghiệp :(
aProperFox

7

Thêm màu nền giúp tôi.

<CalendarView
    android:layout_width="match_parent"
    android:id="@+id/calendarView"
    android:layout_alignParentTop="true"
    android:layout_alignParentStart="true"
    android:layout_height="wrap_content"
    android:elevation="5dp"

    android:background="@color/windowBackground"

    />

4

Đôi khi thích background="@color/***"hoặc background="#ff33**"không hoạt động, tôi thay thế background_colorbằng drawable, sau đó nó hoạt động


4

Nếu nó vẫn không hiển thị độ cao hãy thử

    android:hardwareAccelerated="true" 

Điều này chắc chắn sẽ giúp bạn.


CÁi này đã sửa nó giúp tôi. Tôi đã giả định rằng TRUE là cài đặt mặc định, nhưng dường như không, ít nhất là trong trường hợp của tôi.
Matt Robertson

3

Nếu bạn muốn có nền trong suốt và android:outlineProvider="bounds"không phù hợp với bạn, bạn có thể tạo ViewOutlineProvider tùy chỉnh:

class TransparentOutlineProvider extends ViewOutlineProvider {

    @Override
    public void getOutline(View view, Outline outline) {
        ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
        Drawable background = view.getBackground();
        float outlineAlpha = background == null ? 0f : background.getAlpha()/255f;
        outline.setAlpha(outlineAlpha);
    }
}

Và đặt nhà cung cấp này vào chế độ xem minh bạch của bạn:

transparentView.setOutlineProvider(new TransparentOutlineProvider());

Nguồn: https://code.google.com.vn/p/android/issues/detail?id=78248#c13

[EDIT] Tài liệu về Drawable.getAlpha () nói rằng nó đặc trưng cho cách Drawable đe dọa alpha. Có thể nó sẽ luôn trả về 255. Trong trường hợp này, bạn có thể cung cấp alpha theo cách thủ công:

class TransparentOutlineProvider extends ViewOutlineProvider {

    private float mAlpha;

    public TransparentOutlineProvider(float alpha) {
        mAlpha = alpha;
    }

    @Override
    public void getOutline(View view, Outline outline) {
        ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
        outline.setAlpha(mAlpha);
    }
}

Nếu nền xem của bạn là StateListDrawable với màu mặc định # DDFF0000, với alpha DDx0 / FFx0 == 0.86

transparentView.setOutlineProvider(new TransparentOutlineProvider(0.86f));

2

cung cấp một số màu nền để bố trí làm việc cho tôi như:

    android:background="@color/catskill_white"
    android:layout_height="?attr/actionBarSize"
    android:elevation="@dimen/dimen_5dp"

1

Tôi đã có một số may mắn với thiết lập clipChildren="false"trên bố trí cha mẹ.


1

Tôi đã dành một chút thời gian để làm việc với nó và cuối cùng nhận ra rằng khi nền tối, không thể nhìn thấy bóng


1

Thêm vào câu trả lời được chấp nhận, có thêm một lý do do độ cao có thể không hoạt động như mong đợi nếu tính năng bộ lọc Bluelight trên điện thoại được BẬT.

Tôi đã phải đối mặt với vấn đề này khi độ cao xuất hiện hoàn toàn bị biến dạng và không thể chịu đựng được trong thiết bị của tôi. Nhưng độ cao là tốt trong bản xem trước. Tắt bộ lọc Bluelight trên điện thoại đã giải quyết vấn đề.

Vì vậy, ngay cả sau khi thiết lập

android:outlineProvider="bounds"

Độ cao không hoạt động chính xác, sau đó bạn có thể thử sửa đổi cài đặt màu của điện thoại.


0

Tôi tin rằng vấn đề của bạn xuất phát từ thực tế là bạn đã áp dụng yếu tố độ cao cho bố cục tương đối lấp đầy cha mẹ của nó. Cha mẹ của nó cắt tất cả các chế độ xem con trong khung vẽ của chính nó (và là chế độ xem xử lý bóng của trẻ). Bạn có thể khắc phục điều này bằng cách áp dụng thuộc tính độ cao lên trên cùng RelativeLayouttrong chế độ xem xml (thẻ gốc) của bạn.


0

Trong trường hợp của tôi, phông chữ là vấn đề.

1) Không có fontFamily cần tôi phải đặt android:backgroundthành một số giá trị.

<TextView
    android:layout_width="match_parent"
    android:layout_height="44dp"
    android:background="@android:color/white"
    android:elevation="3dp"
    android:gravity="center"
    android:text="@string/fr_etalons_your_tickets"
    android:textAllCaps="true"
    android:textColor="@color/blue_4" />

2) với fontFamilytôi đã phải thêm android:outlineProvider="bounds"cài đặt:

<TextView
    android:fontFamily="@font/gilroy_bold"
    android:layout_width="match_parent"
    android:layout_height="44dp"
    android:background="@android:color/white"
    android:elevation="3dp"
    android:gravity="center"
    android:outlineProvider="bounds"
    android:text="@string/fr_etalons_your_tickets"
    android:textAllCaps="true"
    android:textColor="@color/blue_4" />

0

Trong trường hợp của tôi, điều này là do thành phần cha mẹ tùy chỉnh cài đặt loại lớp kết xuất thành "Phần mềm":

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Loại bỏ dòng này đã làm thủ thuật. Hoặc tất nhiên bạn cần đánh giá tại sao điều này lại có ở nơi đầu tiên. Trong trường hợp của tôi, đó là để hỗ trợ Honeycomb, công ty đứng sau SDK tối thiểu hiện tại cho dự án của tôi.


0

Đồng thời kiểm tra xem Bạn không thay đổi alpha trên chế độ xem đó. Tôi đang điều tra vấn đề khi tôi thay đổi alpha trên một số quan điểm, với độ cao. Họ chỉ đơn giản là mất độ cao khi alpha được thay đổi và thay đổi trở lại 1f.

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.