Efekt tętnienia na Androidzie Lollipop CardView


191

Próbuję uzyskać CardView, aby wyświetlał efekt tętnienia po dotknięciu, ustawiając atrybut android: backgound w pliku XML aktywności, jak opisano tutaj na stronie programistów Androida, ale to nie działa. Brak animacji, ale wywoływana jest metoda onClick. Próbowałem również utworzyć plik ripple.xml, jak sugerowano tutaj , ale ten sam wynik.

CardView, jak pojawia się w pliku XML działania:

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

Jestem stosunkowo nowy w rozwoju Androida, więc mogłem popełnić kilka oczywistych błędów.

Odpowiedzi:


593

Dodaj następujące informacje do CardView:

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

8
Działa na Lollipop z efektem marszczenia, ale daje jednolity kolor, gdy działa na starszych platformach. Wystarczająco dobrze dla mnie :)
mach

16
Mała uwaga: zauważyłem, że klikalny atrybut nie jest konieczny, a nawet może popsuć niektóre rzeczy! Miałem GridView wypełniony klikalnymi kartami CardView, a detektor nie działał poprawnie.
Usunąłem

2
@joaquin bez klikalnego, powoduje, że tętnienie powstaje tylko od środka
frostymarvelous

2
?android:attr/selectableItemBackgroundwymaga interfejsu API na poziomie 11
Pratik Butani

9
Praca bez android:clickable="true".
Sean

30

Dodaj te dwa kody wiersza do swojego widoku XML, aby uzyskać efekt falowania na karcie.

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

Niesamowite! foregrounddziała z niestandardowymi widokami tła jak urok! Miły!
sud007

24

Udało mi się uzyskać efekt marszczenia w widoku karty poprzez:

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

a dla custom_bg, który widzisz w powyższym kodzie, musisz zdefiniować plik xml zarówno dla urządzeń Lollipop (w pakiecie drawable-v21), jak i pre-Lollipop (w pakiecie drawable). dla custom_bg w pakiecie drawable-v21 kod to:

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

dla custom_bg w pakiecie wysuwnym kod to:

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

więc na urządzeniach z pre-Lollipop będziesz mieć efekt solidnego kliknięcia, a na urządzeniach z Lollipop będziesz miał efekt tętnienia na widoku karty.


1
Cześć, zdaję sobie sprawę, że zastosowanie selektora (lub tętnienia) na pierwszym planie CardView spowoduje zablokowanie dzieci w samym CardView - stackoverflow.com/questions/33763403/... Czy mogę wiedzieć, czy napotykasz ten sam problem, co ja? Czy coś mi umknęło? Dzięki.
Cheok Yan Cheng

@CheokYanCheng: Nie mam do czynienia z żadnym takim problemem, jak twój, ale z własnego doświadczenia powiedziałbym, że cardView ma kilka błędów dla pre-Lollipopa. Unikaj używania właściwości cardview: elevation w pre-Lollipop. Powyższe działa dobrze dla mnie i innych entuzjastów.
Rahul Ahuja

Czy mogę wiedzieć, jaka jest wartość twojego koloru. Jeśli użyłeś własnego zdefiniowanego koloru bez przezroczystości, czy nadal widzisz dzieci swojej karty?
Cheok Yan Cheng

@CheokYanCheng: wartości są takie, <color name = "navigation_drawer_background"> ​​# FFFFFF </color> <color name = "colorHighlight"> # FF8A65 </color>
Rahul Ahuja

Nie pracuję dla mojej sprawy. Używam twojego selektora jako pierwszego planu. Zgodnie z oczekiwaniami, jednolity biały kolor (nawigacja_szuflowanie_pola), który jest używany jako pierwszy plan widoku karty, zablokuje widoczność wszystkich dzieci - i.imgur.com/CleYh5B.png Tak to wygląda bez zastosowania selektora jako pierwszego planu - i.imgur. com / ZXk5Aoq.png
Cheok Yan Cheng

14

Efekt marszczenia został pominięty w bibliotece obsługi aplikacji appcompat, której używasz. Jeśli chcesz zobaczyć tętnienie, użyj wersji Android L i przetestuj ją na urządzeniu z Androidem L. W witrynie AppCompat v7:

„Dlaczego w wersji wcześniejszej niż Lollipop nie ma żadnych zmarszczek? Wiele z tego, co pozwala RippleDrawable na płynne działanie, to nowy RenderThread Androida 5.0. Aby zoptymalizować wydajność w poprzednich wersjach Androida, na razie pozostawiliśmy RippleDrawable”.

Sprawdź ten link tutaj, aby uzyskać więcej informacji


To by było na tyle. Dzięki!
AkraticCritic

39
Ale jak w takim razie zastosowałbyś efekt fali na cardView dla Androida Lollipop?
programista Androida

Więc muszę zdecydować między zgodnością wsteczną przy użyciu appcompat lub posiadaniem wszystkich nowych efektów, używając klas z rdzenia Androida, ale ograniczając się do API 21?
Urs Reupke,

Możesz zrobić 2 APK jeden dla 21+, a drugi dla <21. Lub podzielić kod, ponieważ 21+ nie będzie korzystał z supportActionbar itp. Może to brzmieć jak duże kłopoty, ale wierzę, że to twój spokój.
Mathijs Segers,

1
Dlatego pisanie „czystych” aplikacji na Androida L nie jest w tej chwili wykonalne. Od lipca 2015 r. Będziesz kierować reklamy na 12% bazy użytkowników Androida.
Glenn Bech,

10

Jeśli minSdkVersionpracujesz nad aplikacją na poziomie 9, możesz użyć:

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

Zamiast tego, zaczynając od poziomu 11, używasz:

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

Z dokumentacji:

klikalne - określa, czy ten widok reaguje na zdarzenia kliknięcia. Musi być wartością logiczną, „prawda” lub „fałsz”.

pierwszoplanowy - definiuje dającą się rysować zawartość. Może to być użyte jako nakładka. Drabina na pierwszym planie uczestniczy w dopełnianiu zawartości, jeśli grawitacja jest ustawiona na wypełnienie.


Korzystanie z Androida: foreground = "? Android: attr / selectableItemBackground" działało na zgodność z AndroidX, dzięki!
dianakarenms

6

Dla mnie dodanie foregrounddo CardViewnie działało (przyczyna nieznana: /)

Dodanie tego samego do układu potomnego załatwiło sprawę.

KOD:

<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
Dzieje się tak, ponieważ dziecko przechwytuje zdarzenie, jeśli spróbujesz czegoś takiego jak dodanie dopełnienia do widoku karty (coś w rodzaju 20dp) i klikniesz część, w której będzie padding, zobaczysz efekt marszczenia nawet bez zestaw atrybutów pierwszego planu
Cruces

1
To również zadziałało dla mnie, używając nowych Materiałów: Com.google.android.material.card.MaterialCardView. Miałem statusListAnimator stanu elewacji dla widoku karty, aby dostosować rzędną, a tętnienie zastosowane do układu wewnętrznego ograniczenia z wybieralnym tłem elementu na pierwszym planie bez atrybutu klikalnego.
Patty P

Teraz tego nie pamiętam, ale istnieje sposób, aby ustawić widoki dziecka tak, aby nie reagowały na zdarzenie kliknięcia
Someone Somewhere

3

Dodaj te dwa kody działające jak urok dla dowolnego widoku, takiego jak Button, układ liniowy lub CardView Wystarczy umieścić te dwa wiersze i zobaczyć magię ...

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

2

Jeśli istnieje układ główny, taki jak RelativeLayout lub LinearLayout, który zawiera cały składnik elementu adaptera w CardView, należy ustawić atrybut tła w tym układzie głównym. lubić:

<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

Zdarzenie Ripple dla Cardviewkontroli Androida :

<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

Nie byłam zadowolona z AppCompat, więc napisałam własne CardView i backported ripples. Tutaj działa na Galaxy S z Piernikiem, więc jest to zdecydowanie możliwe.

Demo of Ripple na Galaxy S.

Aby uzyskać więcej informacji, sprawdź kod źródłowy .


link jest zerwany
temirbek

1

Dodaj następujące elementy do pliku xml:

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

I dodaj do adaptera (jeśli to Twoja obudowa)

    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

Dla tych, którzy szukają rozwiązania problemu efektu marszczenia, który nie działa na programowo utworzonym CardView (lub w moim przypadku widoku niestandardowym, który rozszerza CardView) wyświetlanym w RecyclerView, następujące działanie działało dla mnie. Zasadniczo deklaratywne deklarowanie atrybutów XML wspomnianych w innych odpowiedziach w pliku układu XML nie działa w przypadku programu CardView lub programu utworzonego z niestandardowego układu (nawet jeśli widok główny to CardView lub używany jest element scalania), więc muszą być ustawione programowo tak:

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

Gdzie MadeupCardView extends CardViewpochwały dla tej odpowiedzi za tę TypedArrayczęść.


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

Działa tylko interfejs API 21 i nie używaj tego widoku karty listy wierszy


0

Zamiast tego użyj Material Cardview, rozszerza Cardview i zapewnia wiele nowych funkcji, w tym domyślny efekt klikalności:

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

...

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

Zależność

implementation 'com.google.android.material:material:1.0.0'
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.