Эффект ряби на Android Lollipop CardView


192

Я пытаюсь заставить CardView отображать волновой эффект при касании, установив атрибут android: backgound в XML-файле активности, как описано здесь на странице разработчиков Android, но он не работает. Нет анимации вообще, но вызывается метод в onClick. Я также попытался создать файл ripple.xml, как предложено здесь , но тот же результат.

CardView в том виде, в каком он отображается в XML-файле упражнения:

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="155dp"
    android:layout_height="230dp"
    android:elevation="4dp"
    android:translationZ="5dp"
    android:clickable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:onClick="showNotices"
    android:background="?android:attr/selectableItemBackground"
    android:id="@+id/notices_card"
    card_view:cardCornerRadius="2dp">

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

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

Ответы:


594

Вы должны добавить следующее к CardView:

android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"

8
Работает на леденце с эффектом ряби, но дает только сплошной цвет при запуске на старых платформах. Достаточно хорошо для меня :)
маш

16
Небольшое наблюдение: я заметил, что атрибут clickable не является необходимым и даже может сломать некоторые вещи! У меня был GridView, заполненный интерактивными CardViews, и слушатель не работал должным образом. Я удалил кликабельный тег из XML, и теперь все работает безупречно
Хоакин Иурчук,

2
@ Joaquin без кликабельности, это заставляет пульсации исходить только из центра
морозный

2
?android:attr/selectableItemBackgroundтребует API уровня 11
Пратик Бутани

9
Работаем без android:clickable="true".
Шон

30

Добавьте эти два строковых кода в ваше представление XML, чтобы придать эффект ряби вашему cardView.

android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"

Потрясающие! foregroundработает с пользовательскими видами фона, как шарм! Ницца!
sud007

24

Мне удалось получить эффект пульсации на карточке:

<android.support.v7.widget.CardView 
    xmlns:card_view="http://schemas.android.com/apk/res-auto" 
    android:clickable="true" 
    android:foreground="@drawable/custom_bg"/>

и для custom_bg, который вы видите в приведенном выше коде, вы должны определить xml-файл для устройств lollipop (в пакете drawable-v21) и pre-lollipop (в пакете drawable). для custom_bg в пакете drawable-v21 код выглядит так:

<ripple 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:color="?android:attr/colorControlHighlight">
<item
    android:id="@android:id/mask"
    android:drawable="@android:color/white"/>
</ripple>

для custom_bg в отрисовываемом пакете код:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

<item android:state_pressed="true">
    <shape>
        <solid android:color="@color/colorHighlight"></solid>
    </shape>
</item>
<item>
    <shape>
        <solid android:color="@color/navigation_drawer_background"></solid>
    </shape>
</item>
</selector>

так что на устройствах перед леденцом на палочке у вас будет сильный эффект щелчка, а на устройствах с леденцом на палочке у вас будет эффект пульсации на просмотре карты.


1
Привет, я понимаю, применяя селектор (или рябь) на переднем плане CardView, он блокирует дочерние элементы в самом CardView - stackoverflow.com/questions/33763403/… Могу ли я знать, что вы сталкивались с той же проблемой, что и я? Или я что-то пропустил? Спасибо.
Чок Ян Ченг

@CheokYanCheng: Я не сталкиваюсь с такой проблемой, как ваша, но из личного опыта могу сказать, что в cardView есть некоторые ошибки для предварительного леденца на палочке. Избегайте использования свойства cardview: elevation в pre-lollipop. Вышесказанное прекрасно работает для меня и других голосов.
Рахул Ахаджа

Могу ли я узнать, каково значение вашего colorHighlight & navigation_drawer_background. Если вы использовали свой собственный определенный цвет без прозрачности, можете ли вы по-прежнему видеть детей своей карты?
Чок Ян Ченг

@CheokYanCheng: значения как, <color name = "navigation_drawer_background"> ​​# FFFFFF </ color> <color name = "colorHighlight"> # FF8A65 </ color>
Рахул Ахаджа

Я не работаю в моем случае. Я использую ваш селектор в качестве переднего плана. Как и ожидалось, сплошной белый цвет (navigation_drawer_background), который используется в качестве переднего плана просмотра карты, будет блокировать видимость всех дочерних элементов - i.imgur.com/CleYh5B.png Вот как это выглядит без применения селектора в качестве переднего плана - i.imgur. com / ZXk5Aoq.png
Чеок Ян Ченг

14

Эффект пульсации был опущен в библиотеке поддержки appcompat, которую вы используете. Если вы хотите увидеть пульсацию, используйте версию Android L и протестируйте ее на устройстве Android L. По сайту AppCompat v7:

«Почему на пред-Lollipop нет пульсаций? Многое из того, что позволяет RippleDrawable работать без сбоев, - это новый Android 5.0 RenderThread. Для оптимизации производительности на предыдущих версиях Android мы пока оставили RippleDrawable».

Проверьте эту ссылку здесь для получения дополнительной информации


Это было бы это. Спасибо!
AkraticCritic

39
Но как бы вы применили волновой эффект на cardView для Android Lollipop?
Android-разработчик

Поэтому я должен выбрать между обратной совместимостью с помощью appcompat или наличием всех новых эффектов, с использованием классов из ядра Android, но ограничусь API 21?
Урс Рупке

Вы можете сделать 2 APK один для 21+, а другой для <21. Или разделить код, так как 21+ не будет использовать supportActionbar и т. Д. Это может показаться большим трудом, но я верю, что это ваше решение.
Mathijs Segers

1
Вот почему написание «чистых» приложений для Android L в настоящее время нежизнеспособно. По состоянию на июль 2015 года вы будете ориентироваться на 12% пользователей Android.
Гленн Бек

10

Если приложение, с minSdkVersionкоторым вы работаете, уровня 9, вы можете использовать:

android:foreground="?selectableItemBackground"
android:clickable="true"

Вместо этого, начиная с 11 уровня, вы используете:

android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"

Из документации:

clickable - определяет, реагирует ли это представление на события нажатия. Должно быть логическим значением: «истина» или «ложь».

передний план - определяет рисование поверх содержимого. Это можно использовать как наложение. Рисуемое на переднем плане участвует в заполнении содержимого, если гравитация установлена ​​для заполнения.


Использование android: foreground = "? Android: attr / selectableItemBackground" работает для совместимости с AndroidX, спасибо!
dianakarenms

6

Для меня добавление foregroundкCardView не работает (причина неизвестна: /)

Добавление того же к своему дочернему макету сделало свое дело.

КОД:

<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:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:focusable="true"
    android:clickable="true"
    card_view:cardCornerRadius="@dimen/card_corner_radius"
    card_view:cardUseCompatPadding="true">

    <LinearLayout
        android:id="@+id/card_item"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:foreground="?android:attr/selectableItemBackground"
        android:padding="@dimen/card_padding">

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

2
Это связано с тем, что ребенок перехватывает событие, если вы попытаетесь что-то вроде добавления заполнения к просмотру карты (что-то вроде 20dp) и нажмете на ту часть, где будет заполнение, тогда вы увидите эффект пульсации, даже если у ребенка нет набор атрибутов переднего плана
Cruces

1
Это сработало и для меня, используя новые компоненты материалов: com.google.android.material.card.MaterialCardView. У меня был элемент elevation stateListAnimator для вида карты, чтобы настроить высоту и пульсацию, примененную к макету внутреннего ограничения с фоном выбираемого элемента на переднем плане без атрибута clickable.
Пэтти П

Сейчас я этого не помню, но есть способ настроить дочерние представления, чтобы они не реагировали на событие щелчка
Someone Somewhere

3

Добавьте эти два типа кода, работающего как очарование для любого представления, такого как Button, Linear Layout или CardView. Просто поместите эти две строки и увидите магию ...

android:foreground="?android:attr/selectableItemBackground"
android:clickable="true"

2

Если есть корневой макет, такой как RelativeLayout или LinearLayout, который содержит все компоненты элемента адаптера в CardView, необходимо установить атрибут фона в этом корневом макете. лайк:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="122dp"
android:layout_marginBottom="6dp"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
card_view:cardCornerRadius="4dp">

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/touch_bg"/>
</android.support.v7.widget.CardView>

2

Пульсация события для Cardviewуправления Android :

<android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:foreground="?android:attr/selectableItemBackground"
    android:clickable="true"
    android:layout_marginBottom="4dp"
    android:layout_marginTop="4dp" />

1

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

Демо Ripple на Galaxy S

Для более подробной информации проверьте исходный код .


ссылка не работает
темирбек

1

Добавьте следующее в ваш xml:

android:clickable="true"
android:focusable="true"
android:background="?android:attr/selectableItemBackground"

И добавить в свой адаптер (если это ваш случай)

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val attrs = intArrayOf(R.attr.selectableItemBackground)
            val typedArray = holder.itemView.context.obtainStyledAttributes(attrs)
            val selectableItemBackground = typedArray.getResourceId(0, 0)
            typedArray.recycle()

            holder.itemView.isClickable = true
            holder.itemView.isFocusable = true
            holder.itemView.foreground = holder.itemView.context.getDrawable(selectableItemBackground)
        }
    }

0

Для тех, кто ищет решение вопроса о том, что эффект ряби не работает с программно созданным CardView (или, в моем случае, с настраиваемым представлением, расширяющим CardView), отображаемым в RecyclerView, мне помогло следующее. По сути, объявление атрибутов XML, упомянутых в других ответах, декларативно в файле макета XML, похоже, не работает для программно созданного CardView или для созданного из пользовательского макета (даже если корневым представлением является CardView или используется элемент слияния), поэтому они должны быть установлены программно следующим образом:

private class MadeUpCardViewHolder extends RecyclerView.ViewHolder {
    private MadeUpCardView cardView;

    public MadeUpCardViewHolder(View v){
        super(v);

        this.cardView = (MadeUpCardView)v;

        // Declaring in XML Layout doesn't seem to work in RecyclerViews
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int[] attrs = new int[]{R.attr.selectableItemBackground};
            TypedArray typedArray = context.obtainStyledAttributes(attrs);
            int selectableItemBackground = typedArray.getResourceId(0, 0);
            typedArray.recycle();

            this.cardView.setForeground(context.getDrawable(selectableItemBackground));
            this.cardView.setClickable(true);
        }
    }
}

Где MadeupCardView extends CardViewслава этому ответ за TypedArrayчасть.


0
  android:foreground="?android:attr/selectableItemBackgroundBorderless"
   android:clickable="true"
   android:focusable="true"

Только работает API 21 и использовать это не использовать этот список строк просмотра карты


0

Вместо этого используйте Material Cardview, он расширяет Cardview и предоставляет несколько новых функций, включая кликабельный эффект по умолчанию:

<com.google.android.material.card.MaterialCardView>

...

</com.google.android.material.card.MaterialCardView>

Зависимость (может использоваться до API 14 для поддержки старых устройств):

implementation 'com.google.android.material:material:1.0.0'
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.