ผลกระทบระลอกคลื่นบน Android Lollipop CardView


191

ฉันพยายามรับ 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> 

ฉันค่อนข้างใหม่สำหรับการพัฒนาแอนดรอยด์ดังนั้นฉันอาจทำผิดพลาดเล็กน้อย

คำตอบ:


593

คุณควรเพิ่มรายการต่อไปนี้ในCardView:

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

8
ใช้งานได้กับ lollipop ที่มีเอฟเฟกต์กระเพื่อม แต่ให้สีทึบเมื่อทำงานบนแพลตฟอร์มที่เก่ากว่าเท่านั้น ที่ดีพอสำหรับฉัน :)
จักร

16
ข้อสังเกตเล็กน้อย: ฉันได้ตั้งข้อสังเกตว่าคุณลักษณะที่สามารถคลิกได้นั้นไม่จำเป็นและยังสามารถทำลายบางสิ่งได้! ฉันมี GridView ที่เต็มไปด้วย CardViews ที่คลิกได้และผู้ฟังทำงานไม่ถูกต้อง ฉันลบแท็กที่คลิกได้ออกจาก XML และตอนนี้ทุกอย่างทำงานได้อย่างไร้ที่ติ
Joaquin Iurchuk

2
@joaquin ที่ไม่สามารถคลิกได้จะทำให้ระลอกเกิดจากจุดศูนย์กลางเท่านั้น
frostymarvelous

2
?android:attr/selectableItemBackgroundต้องใช้ API ระดับ 11
Pratik Butani

9
android:clickable="true"โดยไม่ต้องทำงาน
Sean

30

เพิ่มโค้ดสองบรรทัดนี้ในมุมมอง xml ของคุณเพื่อให้ระลอกคลื่นบน cardView ของคุณ

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

! น่ากลัว foregroundทำงานร่วมกับมุมมองพื้นหลังที่กำหนดเองอย่างมีเสน่ห์! ดี!
sud007

24

ฉันจัดการเพื่อให้ได้ระลอกคลื่นบน cardview โดย:

<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 (ในแพ็คเกจที่สามารถดึงได้) สำหรับ 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 ในแพ็คเกจ drawable รหัสคือ:

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

ดังนั้นสำหรับอุปกรณ์ pre-lollipop คุณจะมีเอฟเฟกต์คลิกทึบและบนอุปกรณ์ lollipop คุณจะมีเอฟเฟกต์ระลอกคลื่นบน cardview


1
สวัสดีฉันทราบด้วยการใช้ตัวเลือก (หรือระลอก) บนพื้นหน้าของ CardView มันจะบล็อกเด็ก ๆ ใน CardView ตัวเอง - stackoverflow.com/questions/33763403/ …ฉันรู้หรือไม่ว่าคุณเคยเจอปัญหาแบบเดียวกับที่เคยทำหรือไม่? หรือฉันจะพลาดอะไรไหม? ขอบคุณ
Cheok Yan Cheng

@CheokYanCheng: ฉันไม่ได้เผชิญกับปัญหาดังกล่าวเป็นของคุณ แต่ฉันจะพูดจากประสบการณ์ส่วนตัวที่ cardView มีข้อบกพร่องบางอย่างสำหรับ pre-lollipop หลีกเลี่ยงการใช้ cardview: คุณสมบัติระดับความสูงใน pre-lollipop การทำงานด้านบนดีสำหรับฉันและ upvotes อื่น ๆ
Rahul Ahuja

ฉันขอทราบค่าของไฮไลต์ & การนำทางของคุณคืออะไร หากคุณใช้สีที่กำหนดเองโดยไม่มีความโปร่งใสคุณยังสามารถเห็นลูก ๆ ของการ์ดของคุณได้หรือไม่?
Cheok Yan Cheng

@CheokYanCheng: ค่าเป็น, <color name = "navigation_drawer_background"> ​​# FFFFFF </color> <color name = "colorHighlight"> # FF8A65 </color>
Rahul Ahuja

ฉันไม่ทำงานเพื่อกรณีของฉัน ฉันใช้ตัวเลือกของคุณเป็นเบื้องหน้า ตามที่คาดไว้สีขาวทึบ (navigation_drawer_background) ซึ่งใช้เป็นพื้นหน้ามุมมองการ์ดจะปิดกั้นการมองเห็นของเด็กทุกคน - i.imgur.com/CleYh5B.pngนี่คือลักษณะที่ปรากฏโดยไม่ต้องใช้ตัวเลือกเป็นพื้นหน้า - i.imgur com / ZXk5Aoq.png
Cheok Yan Cheng

14

ระลอกเอฟเฟกต์ถูกละไว้ในไลบรารีสนับสนุน appcompat ซึ่งเป็นสิ่งที่คุณกำลังใช้งาน หากคุณต้องการดูระลอกใช้เวอร์ชัน Android L และทดสอบบนอุปกรณ์ Android L ต่อเว็บไซต์ AppCompat v7:

"เหตุใดจึงไม่มีระลอกใน pre-Lollipop อะไรมากมายที่ทำให้ RippleDrawable สามารถทำงานได้อย่างราบรื่นคือ RenderThread ใหม่ของ Android 5.0 เพื่อเพิ่มประสิทธิภาพสำหรับ Android รุ่นก่อนหน้านี้เราจึงปล่อย RippleDrawable ออกมาตอนนี้"

ตรวจสอบลิงค์นี้ที่นี่สำหรับข้อมูลเพิ่มเติม


นั่นจะเป็นอย่างไร ขอบคุณ!
AkraticCritic

39
แต่คุณจะให้ระลอกคลื่นบน cardView สำหรับ Android Lollipop ได้อย่างไร?
พัฒนา android

ดังนั้นฉันต้องตัดสินใจระหว่างความเข้ากันได้แบบย้อนหลังโดยใช้ appcompat หรือมีเอฟเฟกต์ใหม่ทั้งหมดโดยใช้คลาสจาก android core แต่ จำกัด ตัวเองไว้ที่ API 21
Urs Reupke

คุณสามารถสร้าง 2 APK สำหรับ 21+ และอีกอันสำหรับ <21 หรือหารรหัสตั้งแต่ 21+ จะไม่ใช้ supportActionbar ฯลฯ อาจฟังดูเป็นปัญหามาก แต่นั่นก็คือความเชื่อของคุณ
Mathijs Segers

1
นี่คือเหตุผลว่าทำไมการเขียนแอปพลิเคชัน Android L ที่ไม่สามารถใช้งานได้ในขณะนี้ ตั้งแต่เดือนกรกฎาคม 2015 คุณจะกำหนดเป้าหมาย 12% ของฐานผู้ใช้ Android
Glenn Bech

10

หากแอพminSdkVersionที่คุณใช้งานอยู่ระดับ 9 คุณสามารถใช้:

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

คุณเริ่มจากระดับ 11 โดยใช้:

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

จากเอกสาร:

คลิกได้ - กำหนดว่ามุมมองนี้จะตอบสนองต่อการคลิกเหตุการณ์ ต้องเป็นค่าบูลีนไม่ว่าจะเป็น "true" หรือ "false"

เบื้องหน้า - กำหนด drawable เพื่อวาดเนื้อหา สามารถใช้เป็นภาพซ้อนทับได้ drawable เบื้องหน้ามีส่วนร่วมในการขยายเนื้อหาหากแรงโน้มถ่วงถูกกำหนดให้เติม


ใช้ 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
นั่นเป็นเพราะเด็กขัดขวางเหตุการณ์ถ้าคุณลองทำอะไรบางอย่างเช่นการเพิ่มช่องว่างใน cardview (บางอย่างเช่น 20dp) และคุณคลิกที่ส่วนที่จะมีช่องว่างคุณจะเห็นเอฟเฟกต์กระเพื่อมแม้จะไม่มีลูกก็ตาม ชุดคุณลักษณะเบื้องหน้า
Cruces

1
สิ่งนี้ใช้ได้สำหรับฉันเช่นกันโดยใช้ส่วนประกอบวัสดุใหม่: com.google.android.material.card.MaterialCardView ฉันมี stateListAnimator ระดับความสูงสำหรับมุมมองการ์ดเพื่อปรับระดับความสูงและระลอกที่ใช้กับเค้าโครงข้อ จำกัด ด้านในที่มีพื้นหลังรายการที่เลือกได้ในเบื้องหน้าโดยไม่มีแอตทริบิวต์ที่คลิกได้
Patty P

ฉันจำไม่ได้แล้วตอนนี้ แต่มีวิธีตั้งค่ามุมมองเด็กที่จะไม่ตอบสนองต่อเหตุการณ์คลิก
คนอยู่ที่ไหนสักแห่ง

3

เพิ่มโค้ดสองอย่างนี้ของการทำงานของรหัสเช่นเสน่ห์สำหรับมุมมองใด ๆ เช่นปุ่ม, เลย์เอาต์เชิงเส้นหรือ 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

สำหรับรายละเอียดเพิ่มเติมตรวจสอบรหัสที่มา


ลิงก์ใช้งานไม่ได้
temirbek

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>

เมืองขึ้น

implementation 'com.google.android.material:material:1.0.0'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.