Как установить отступ для виджета 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>

5 ответов

Решение

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

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

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

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

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

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>

Если вы хотите использовать заполнение CardView на устройствах до 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 (логическое значение)

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

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

<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", а не инструментами, а также установите отрицательные поля в раме для сохранения теней - работает отлично.

Просто добавьте ниже две строки

      <androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_marginTop="24dp"
            android:layout_marginRight="16dp"
            android:layout_marginBottom="24dp"
            android:layout_marginLeft="16dp"
            app:cardUseCompatPadding="true" // add this line
            app:contentPadding="16dp" // add this line`enter code here`
            app:cardCornerRadius="8dp"
           >
        </androidx.cardview.widget.CardView>

вот и все... наслаждайтесь кодированием...

Другие вопросы по тегам