การเพิ่ม Ripple Effect ให้กับรายการ RecyclerView


105

ฉันพยายามเพิ่ม Ripple Effect ให้กับรายการของ RecyclerView ฉันดูทางออนไลน์ แต่ไม่พบสิ่งที่ต้องการ ฉันคิดว่ามันต้องเป็นเอฟเฟกต์ที่กำหนดเอง ฉันได้ลองใช้คุณลักษณะ android: background กับ RecyclerView แล้วและตั้งค่าเป็น "? android: selectableItemBackground" แต่ไม่ได้ผล:

    <android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusable="true"
    android:clickable="true"
    android:background="?android:selectableItemBackground"
    android:id="@+id/recyclerView"
    android:layout_below="@+id/tool_bar"/>

นี่คือ RecyclerView ที่ฉันพยายามเพิ่มเอฟเฟกต์ให้กับ:

ใส่คำอธิบายภาพที่นี่


1
ฉันเปิดใหม่นี้จะไม่ซ้ำกับคำถามนี้ แม้ว่าวิธีแก้ปัญหาอาจจะคล้ายกัน แต่ก็มีบางแง่มุมของการมีCardViewคำถามนั้นมากกว่าที่จะไม่เกี่ยวข้องกับคำถามทั่วไปนี้
Suragch

@Suragch ขอบคุณที่สังเกตเห็นความแตกต่าง :)
Georgi Koemdzhiev

คำตอบ:


222

ฉันคิดออก สิ่งเดียวที่ฉันต้องทำคือเพิ่มแอตทริบิวต์นี้:

android:background="?android:attr/selectableItemBackground"

ไปยังองค์ประกอบรูทของโครงร่างที่อะแดปเตอร์ RecyclerView ของฉันพองตัวเช่นนั้น:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="8dp"
    android:paddingBottom="8dp"
    android:background="?android:attr/selectableItemBackground"
    tools:background="@drawable/bg_gradient">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="17sp"
        android:layout_marginLeft="15dp"
        android:layout_marginStart="15dp"
        android:id="@+id/shoppingListItem"
        android:hint="@string/enter_item_hint"
        android:layout_centerVertical="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"/>

    <CheckBox
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/shopping_list_item_checkbox_label"
        android:id="@+id/shoppingListCheckBox"
        android:layout_centerVertical="true"
        android:layout_marginRight="15dp"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:checked="false"/>

</RelativeLayout>

ผลลัพธ์:

ใส่คำอธิบายภาพที่นี่

หากคุณยังไม่เห็นเอฟเฟกต์ระลอกคลื่นให้เพิ่มเส้นเหล่านี้ในองค์ประกอบรากของเค้าโครงด้วย

android:clickable="true"
android:focusable="true"

3
จะเกิดอะไรขึ้นถ้าองค์ประกอบรากคือ CardView?
นาบิน

6
@SpiderMan คุณควรเขียนโค้ดของคุณภายใน Relative หรือ Linear Layout แล้ววางไว้ใน Card Layout
SanVed

7
@pronoobsanved นี้ช่วยฉันด้วย! สำหรับผู้ที่ยังคงประสบปัญหา CardView จะใช้เลย์เอาต์เดียวตั้งแต่ยังเป็นเด็ก สำหรับเด็กนั้นตั้งค่าที่คลิกได้โฟกัสได้เป็นจริงและพื้นหลังเป็น? attr / selectedableItemBackground
Vamsi Challa

42
@NabinKhadka สำหรับ CardView ตั้งเป็นฉากหน้าแทนเช่นandroid:foreground="?android:attr/selectableItemBackground"
Lorne Laliberte

6
ฉันต้องเพิ่มตัวเลือกandroid:clickable="true"เพื่อทำงานนี้ด้วย
Joaquin Iurchuk

69

ตามที่ตอบไปแล้ววิธีแก้ปัญหาที่ง่ายที่สุดคือเพิ่มสิ่งใดสิ่งหนึ่งต่อไปนี้เป็นRecyclerViewพื้นหลังของแถวของคุณ:

  • android:background="?android:attr/selectableItemBackground"
  • android:background="?attr/selectableItemBackground"

อย่างไรก็ตามหากคุณกำลังประสบปัญหากับวิธีนี้หรือหากคุณต้องการควบคุมสีให้ละเอียดขึ้นคุณสามารถทำสิ่งต่อไปนี้ได้

เอฟเฟกต์ระลอกที่กำหนดเอง

คำตอบนี้จะเริ่มต้นด้วยการที่เรียบง่ายเช่น Android RecyclerView นี้ จะมีลักษณะดังภาพต่อไปนี้

Ripple effect ตัวอย่าง GIF

เพิ่มตัวเลือกสำหรับอุปกรณ์ก่อน API 21

ก่อน API 21 (Android 5.0 Lollipop) การคลิกRecyclerViewรายการเพิ่งเปลี่ยนสีพื้นหลัง (ไม่มีเอฟเฟกต์การกระเพื่อม) นั่นคือสิ่งที่เรากำลังจะทำเช่นกัน หากคุณยังคงมีผู้ใช้อยู่กับอุปกรณ์เหล่านั้นพวกเขาคุ้นเคยกับพฤติกรรมดังกล่าวดังนั้นเราจะไม่กังวลกับพวกเขามากเกินไป (แน่นอนว่าหากคุณต้องการเอฟเฟกต์ระลอกคลื่นสำหรับพวกเขาจริงๆคุณสามารถใช้ไลบรารีที่กำหนดเองได้)

คลิกขวาที่res/drawableโฟลเดอร์ของคุณแล้วเลือกใหม่> ไฟล์ทรัพยากรที่วาดได้ เรียกมันcustom_ripple. คลิกตกลงและวางรหัสต่อไปนี้

custom_ripple.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorAccent" />
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
</selector>

ฉันใช้colorAccentเป็นสีไฮไลต์สำหรับสถานะกดเนื่องจากมีอยู่แล้ว แต่คุณสามารถกำหนดสีที่คุณต้องการได้

เพิ่ม Ripple Effect สำหรับอุปกรณ์ API 21+

คลิกขวาที่res/drawableโฟลเดอร์ของคุณแล้วเลือกใหม่> ไฟล์ทรัพยากรที่วาดได้ เรียกcustom_rippleอีกอย่าง. อย่าคลิกตกลง แต่คราวนี้ จากที่มีอยู่รอบคัดเลือกรายการเลือกรุ่นแล้วคลิก>>ปุ่มและเขียน21สำหรับระดับแพลตฟอร์ม API ตอนนี้คลิกตกลงและวางรหัสต่อไปนี้

v21 / custom_ripple.xml

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

    <item
        android:id="@android:id/mask"
        android:drawable="@android:color/white" />
</ripple>

อีกครั้งฉันใช้colorAccentสำหรับสีระลอกเพราะมีให้เลือก แต่คุณสามารถใช้สีอะไรก็ได้ที่คุณต้องการ มาสก์จะ จำกัด เอฟเฟกต์ระลอกคลื่นให้อยู่ในเค้าโครงแถวเท่านั้น เห็นได้ชัดว่าสีของหน้ากากไม่สำคัญดังนั้นฉันจึงใช้สีขาวขุ่น

ตั้งเป็นพื้นหลัง

ในเค้าโครงรูทของรายการ RecyclerView ของคุณให้ตั้งค่าพื้นหลังเป็นระลอกที่กำหนดเองที่เราสร้างขึ้น

android:background="@drawable/custom_ripple"

ในโครงการตัวอย่างที่เราเริ่มต้นมีลักษณะดังนี้:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:background="@drawable/custom_ripple"
    android:padding="10dp">

    <TextView
        android:id="@+id/tvAnimalName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="20sp"/>

</LinearLayout>

เสร็จแล้ว

แค่นั้นแหละ. คุณควรจะดำเนินโครงการได้แล้ว ขอบคุณสำหรับคำตอบนี้และวิดีโอ YouTube นี้สำหรับความช่วยเหลือ


หากคุณต้องการให้สีพื้นหลังเริ่มต้นเพียงแค่ลบบรรทัด "android: id =" @ android: id / mask "แล้วตั้งค่าสีของสิ่งที่วาดได้ตามที่คุณต้องการ
Jordan Hochstetler

26

ฉันคิดว่ามีรายละเอียดเล็ก ๆ อย่างหนึ่งที่พลาดไป

หากคุณยังไม่ได้รับเอฟเฟกต์ระลอกคลื่นหลังจากเพิ่มแล้วandroid:background="?android:attr/selectableItemBackground"ให้ลองเพิ่มบรรทัดต่อไปนี้ในรูทของเค้าโครง

android:clickable="true"
android:focusable="true"

สิ่งเหล่านี้จะทำให้แน่ใจว่ามุมมองสามารถคลิกได้และจะเปิดใช้งานเอฟเฟกต์ระลอกด้วยแอตทริบิวต์พื้นหลังที่กล่าวถึงข้างต้น



2

ที่เรียบง่ายและกำหนดเองวิธีการคือการตั้งค่ารูปแบบมุมมองดังที่ระบุไว้ที่นี่

some_view.xml

<ImageView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="?attr/selectableItemBackgroundBorderless"
   android:focusable="true"
   android:src="@drawable/up_arrow"
   android:theme="@style/SomeButtonTheme"/>

some_style.xml

<style name="SomeButtonTheme" >
   <item name="colorControlHighlight">@color/someColor</item>
</style>

การใช้งานที่กำหนดเองอื่น ๆ อาจจะพบได้ที่นี่


1

การใช้รูปแบบปุ่ม

สิ่งนี้ได้ผลสำหรับฉันนับไม่ถ้วน

เพิ่มรูปแบบปุ่มไร้ขอบให้กับองค์ประกอบรากของเค้าโครงของคุณ ไม่จำเป็นต้องมีfocusableหรือclickableแอตทริบิวต์การจัดแต่งทรงผมเริ่มต้นจะสรุปทุกอย่างให้คุณ

<androidx.constraintlayout.widget.ConstraintLayout
    style="@android:style/Widget.Material.Button.Borderless"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

เจ๋ง แต่การเพิ่มช่องว่างนี้
ededede

@ededede คุณสามารถใช้แอตทริบิวต์ XML ความสูงต่ำสุดความสูงสูงสุดความกว้าง ... เพื่อปรับแต่งให้เข้ากับรสนิยมของคุณ
Felix Favor Chinemerem
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.