Android "высота" не показывает тень

У меня есть ListView, и с каждым элементом списка я хочу, чтобы он отображал тень под ним. Я использую новую функцию рельефа для Android Lollipop, чтобы установить Z в представлении, в котором я хочу наложить тень, и уже делаю это эффективно с помощью ActionBar (технически это панель инструментов в Lollipop). Я использую Lollipop elevation, но по какой-то причине он не показывает тень под элементами списка. Вот как настроен каждый макет элемента списка:

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

Однако, вот как он показывает элемент списка без тени: enter image description here

Я также пробовал следующее безрезультатно:

  • Задайте высоту для самих ImageView и TextViews вместо родительского макета.
  • Применяется фон для ImageView.
  • Используется TranslationZ вместо Elevation.

Ответ 1

Я немного поиграл с тенями на Lollipop, и вот что я нашел:

  • Похоже, что родительский элемент ViewGroup по какой-либо причине обрезает тень своих детей; и
  • Тени, установленные с помощью android:elevation, обрезаются границами View, а не границами, простирающимися через край;
  • Правильный способ получения дочернего представления показать тень - это установить дополнение к родительскому элементу и установить android:clipToPadding="false" для этого родителя.

Здесь мое предложение для вас, основываясь на том, что я знаю:

  • Установите верхний уровень RelativeLayout, чтобы иметь отступы, равные полям, которые вы установили на относительном макете, который вы хотите показать тень;
  • установите android:clipToPadding="false" на тот же RelativeLayout;
  • Удалите границу с RelativeLayout, которая также имеет набор высоты;
  • [EDIT] вам также может потребоваться установить непрозрачный цвет фона на дочернем макете, который нуждается в повышении.

В конце дня ваш относительный макет верхнего уровня должен выглядеть следующим образом:

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

Внутренняя относительная компоновка должна выглядеть так:

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

Ответ 2

Если у вас есть представление без фона, эта строка поможет вам

android:outlineProvider="bounds"

По умолчанию тень определяется фоном представления, поэтому, если фона нет, тени тоже не будут.

Ответ 3

По-видимому, вы не можете просто установить высоту в представлении и появиться. Вам также необходимо указать фон.

Следующие строки, добавленные в мой LinearLayout, наконец, показали тень:

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

Ответ 4

еще одна вещь, о которой вы должны знать, тени не будут отображаться, если у вас есть эта строка в манифесте:

Android: hardwareAccelerated = "ложь"

Я пробовал все предлагаемые материалы, но это работало только для меня, когда я удалял строку, причина, по которой у меня была строка, потому что мое приложение работает с несколькими растровыми изображениями, и они вызывают повреждение приложения.

Ответ 6

Если у вас есть вид без фона, эта строка поможет вам

android:outlineProvider="bounds"

Если у вас есть вид с фоном, эта строка поможет вам

android:outlineProvider="paddedBounds"

Ответ 7

Ух, просто потратил час, пытаясь понять это. В моем случае у меня был набор фона, однако он был установлен в цвет. Этого недостаточно, вам нужно, чтобы фон представления был установлен на drawable.

например. Это не будет иметь тени:

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

но это будет

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

EDIT: Также обнаружили, что если вы используете селектор в качестве фона, если у вас нет установленного угла, тень не будет отображаться в окне Предварительный просмотр, но он появится на устройстве

например. Это не имеет тени в предварительном просмотре:

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

но это делает:

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

Ответ 8

Добавление фона фона помогло мне.

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

    />

Ответ 9

Если вы хотите иметь прозрачный фон и android:outlineProvider="bounds" не работает для вас, вы можете создать собственный ViewOutlineProvider:

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

И установите этот провайдер для вашего прозрачного представления:

transparentView.setOutlineProvider(new TransparentOutlineProvider());

Источники: https://code.google.com/p/android/issues/detail?id=78248#c13

[EDIT] Документация Drawable.getAlpha() говорит, что она специфична для того, как Drawable угрожает альфа. Возможно, он всегда вернет 255. В этом случае вы можете указать альфа вручную:

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

Если ваш фон представления является StateListDrawable с цветом по умолчанию # DDFF0000, который находится с альфа DDx0/FFx0 == 0.86

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

Ответ 10

Иногда, например, background="@color/***" или background="#ff33**" не работают, я заменяю background_color на drawable, тогда он работает

Ответ 11

дать немного цвета фона, чтобы макет работал для меня, как:

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

Ответ 12

Добавляя к принятому ответу, есть еще одна причина, из-за которой возвышение может не работать должным образом.

Если функция фильтра Bluelight на телефоне включена,

Я столкнулся с этой проблемой, когда высота показалась полностью искаженной и невыносимой на моем устройстве. Но высота была в порядке. Отключение фильтра Bluelight на телефоне разрешило проблему.

Итак, даже после установки

android:outlineProvider="bounds"

Высота не работает должным образом, тогда вы можете попытаться изменить настройки цвета телефона.

Ответ 13

Я считаю, что ваша проблема связана с тем фактом, что вы применили элемент Elevation к относительному макету, который заполняет его родительский элемент. Его родительский клип создает все дочерние представления в собственном холсте рисования (и это представление, которое обрабатывает дочернюю тень). Вы можете исправить это, применив свойство высоты к самому верхнему RelativeLayout в вашем представлении xml (корневой тег).

Ответ 14

В моем случае шрифты были проблемой.

1) Без fontFamily мне нужно было установить android:background в какое-то значение.

<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) с помощью fontFamily мне пришлось добавить параметр android:outlineProvider="bounds":

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

Ответ 15

Мне повезло с установкой clipChildren="false" в родительском макете.

Ответ 16

Я потратил некоторое время, работая над этим, и наконец понял, что, когда фон темный, тень не видна

Ответ 17

В моем случае это было вызвано тем, что пользовательский родительский компонент установил тип слоя рендеринга в "Программное обеспечение":

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Удаление этой строчки сделало свое дело. Или, конечно, вы должны оценить, почему это происходит в первую очередь. В моем случае это была поддержка Honeycomb, которая значительно отстает от текущего минимального SDK для моего проекта.

Ответ 18

Если это все еще не показывает высоту, попробуйте

    android:hardwareAccelerated="true" 

это определенно поможет вам.

Ответ 19

https://youtu.be/r9BCalStkTU

Как создать эффект тени или возвышение в андроид студии. Обязательно посмотрите этот видео легкий способ возвышения.