Как установить дополнение для виджета CardView в Android L

Я использую android:paddingLeft и android:paddingTop для установки дополнения для нового виджета CardView, но он не работает.

Я могу установить маржу для всех элементов управления внутри CardView в качестве обходного пути, но это боль, если слишком много элементов управления.

Как установить дополнение для нового виджета виджетов?

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:paddingLeft="20dp"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="20dp"
    android:paddingBottom="@dimen/activity_vertical_margin"
    card_view:cardCornerRadius="2dp">

    <TextView
        android:id="@+id/info_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hello World!"/>
</android.support.v7.widget.CardView>

Ответ 1

CardView перед L-preview использует RoundRectDrawableWithShadow для рисования фона, который переопределяет Drawable.getPadding(), чтобы добавить теневое дополнение. Фон представления устанавливается через код после инфляции, который переопределяет любое дополнение, указанное в XML.

У вас есть два варианта:

  • Устанавливайте заполнение во время выполнения с помощью View.setPadding() и будьте осторожны, чтобы настроить тени (но только до L-предварительного просмотра!).
  • Поместите все в макет, который указывает заполнение.

Последний вариант является самым безопасным.

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    card_view:cardCornerRadius="2dp">

    <FrameLayout
        android:paddingLeft="20dp"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="20dp"
        android:paddingBottom="@dimen/activity_vertical_margin">

        <TextView
            android:id="@+id/info_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Hello World!"/>
    </FrameLayout>
</android.support.v7.widget.CardView>

Ответ 2

CardView должен обрабатывать это, используя атрибуты contentPadding, которые он поставляется с:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    card_view:cardCornerRadius="2dp"
    card_view:contentPaddingLeft="20dp"
    card_view:contentPaddingRight="@dimen/activity_horizontal_margin"
    card_view:contentPaddingTop="20dp"
    card_view:contentPaddingBottom="@dimen/activity_vertical_margin">

    <TextView
        android:id="@+id/info_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hello World!"/>
</android.support.v7.widget.CardView>

Ответ 3

Если вы хотите использовать дополнение CardView на устройствах pre-L и выглядеть так же на устройствах Lollipop +, вам нужно будет использовать setUseCompatPadding(true) или вариант XML cardUseCompatPadding="true".

Это связано с тем, что "CardView добавляет дополнительное дополнение для рисования теней на платформах до L". [1] Таким образом, реализация по умолчанию имеет разные версии API, выглядящие по-разному, и представления могут не совпадать правильно. Таким образом, самый простой способ исправить эту проблему - это способы, указанные выше, или использовать поля.

Пример кода

<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_context"
    card_view:cardUseCompatPadding="true"
    card_view:contentPadding="8dp"
    card_view:cardCornerRadius="4dp" >

    ...

</android.support.v7.widget.CardView>

Источники

[1] CardView.setUseCompatPadding(boolean)

[2] android.support.v7.cardview:cardUseCompatPadding

Ответ 4

Это то, что сработало для меня - помещение каждого элемента в макет фрейма

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
 android:layout_marginBottom="-4dp">

   <android.support.v7.widget.CardView   
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:card_view="http://schemas.android.com/apk/res-auto"

            android:background="@color/white_three"
            android:orientation="vertical"
            card_view:cardCornerRadius="2dp"
            card_view:cardElevation="@dimen/card_elevation"
            card_view:cardMaxElevation="0dp"
            card_view:cardPreventCornerOverlap="false"
            card_view:cardUseCompatPadding="true"
   </android.support.v7.widget.CardView>

Дважды проверьте, что card_view " http://schemas.android.com/apk/res-auto", а не инструменты, а также установите отрицательные поля в представлении кадра для сохранения теней - отлично работает.

Ответ 5

Я пришел сюда, чтобы найти решение, как установить заполнение для CardView в styles.xml, потому что android:padding не работал. (Я знаю, что это не Ват OP спрашивал, но я считаю, что его достаточно)

В styles.xml заполнение может быть установлено просто с помощью contentPadding

<style name="myCardViewStyle" parent="CardView">
    <item name="contentPadding">20dp</item>