Thêm hiệu ứng Ripple vào mục RecyclerView


105

Tôi đang cố gắng thêm Hiệu ứng Ripple vào mục của RecyclerView. Tôi đã xem trực tuyến, nhưng không thể tìm thấy thứ tôi cần. Tôi cho rằng nó phải là một hiệu ứng tùy chỉnh. Tôi đã thử thuộc tính android: background cho chính RecyclerView và đặt nó thành "? Android: selectableItemBackground" nhưng nó không hoạt động.:

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

Đây là RecyclerView mà tôi đang cố gắng thêm hiệu ứng vào:

nhập mô tả hình ảnh ở đây


1
Tôi đang mở lại đây không phải là bản sao của câu hỏi này . Mặc dù các giải pháp có thể tương tự nhau, nhưng có một số khía cạnh của việc có một CardViewcâu hỏi đó hơn là không liên quan đến câu hỏi tổng quát hơn này.
Suragch

@Suragch Cảm ơn bạn đã nhận thấy sự khác biệt :)
Georgi Koemdzhiev

Câu trả lời:


222

Tôi đã tìm ra. Điều duy nhất tôi phải làm là thêm thuộc tính này:

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

vào phần tử gốc của bố cục mà bộ điều hợp RecyclerView của tôi tăng lên như vậy:

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

Kết quả:

nhập mô tả hình ảnh ở đây

Nếu bạn vẫn không thể thấy hiệu ứng gợn sóng, hãy thêm các dòng này vào phần tử gốc của bố cục.

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

3
Điều gì sẽ xảy ra nếu phần tử gốc là CardView?
Nabin

6
@SpiderMan Bạn nên viết mã của mình bên trong Bố cục Tương đối hoặc Tuyến tính và sau đó đặt nó bên trong Bố cục Thẻ.
SanVed

7
@pronoobsanved, điều này đã giúp tôi! Đối với những người vẫn đang đối mặt với vấn đề này, CardView có một bố cục duy nhất khi còn nhỏ. Đối với đứa trẻ đó, đặt có thể nhấp, có thể lấy tiêu điểm là true và nền là?
Attr / selectableItemBackground

42
@NabinKhadka cho một CardView đặt nó làm nền trước thay vào đó, tức làandroid:foreground="?android:attr/selectableItemBackground"
Lorne Laliberte

6
Tôi cũng phải thêm tùy chọn android:clickable="true"để làm cho tác phẩm này
Joaquin Iurchuk

69

Như đã trả lời, giải pháp đơn giản nhất là chỉ cần thêm một trong những thứ sau làm RecyclerViewnền cho hàng của bạn :

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

Tuy nhiên nếu bạn đang gặp sự cố với phương pháp này hoặc nếu bạn muốn kiểm soát màu sắc tốt hơn, thì bạn có thể làm như sau.

Hiệu ứng Ripple tùy chỉnh

Câu trả lời này bắt đầu với ví dụ Android RecyclerView đơn giản này . Nó sẽ giống như hình ảnh sau đây.

Ví dụ về hiệu ứng gợn sóng GIF

Thêm bộ chọn cho các thiết bị trước API 21

Trước API 21 (Android 5.0 Lollipop), nhấp vào một RecyclerViewmục chỉ thay đổi màu nền của nó (không có hiệu ứng gợn sóng). Đó cũng là những gì chúng tôi sẽ làm. Nếu bạn vẫn có người dùng với các thiết bị đó, họ đã quen với hành vi đó, vì vậy chúng tôi sẽ không lo lắng về họ quá nhiều. (Tất nhiên, nếu bạn thực sự muốn có hiệu ứng gợn sóng cho chúng, bạn có thể sử dụng thư viện tùy chỉnh .)

Nhấp chuột phải vào res/drawablethư mục của bạn và chọn Mới> Tệp tài nguyên có thể vẽ . Gọi nó đicustom_ripple . Nhấp vào OK và dán mã sau vào.

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>

Tôi đã sử dụng colorAccentlàm màu đánh dấu cho trạng thái được ép bởi vì nó đã có sẵn, nhưng bạn có thể xác định bất kỳ màu nào bạn muốn.

Thêm hiệu ứng Ripple cho các thiết bị API 21+

Nhấp chuột phải vào res/drawablethư mục của bạn và chọn Mới> Tệp tài nguyên có thể vẽ . Gọi custom_ripplelại lần nữa. Tuy nhiên, đừng nhấp vào OK, nhưng lần này. Từ vòng loại sẵn danh sách chọn bản , sau đó nhấp vào >> nút và ghi 21cho cấp API nền tảng . Bây giờ hãy nhấp vào OK và dán mã sau vào.

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>

Một lần nữa, tôi đã sử dụng colorAccentcho màu gợn sóng vì nó có sẵn, nhưng bạn có thể sử dụng bất kỳ màu nào bạn muốn. Mặt nạ giới hạn hiệu ứng gợn sóng chỉ với bố cục hàng. Màu mặt nạ dường như không quan trọng vì vậy tôi chỉ sử dụng một màu trắng đục.

Đặt làm nền

Trong bố cục gốc của mục RecyclerView của bạn, hãy đặt nền thành gợn sóng tùy chỉnh mà chúng tôi đã tạo.

android:background="@drawable/custom_ripple"

Trong dự án ví dụ mà chúng tôi đã bắt đầu, nó trông giống như sau:

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

Đã kết thúc

Đó là nó. Bạn sẽ có thể chạy dự án của mình ngay bây giờ. Cảm ơn câu trả lời nàyvideo YouTube này để được trợ giúp.


Nếu bạn muốn có màu nền mặc định, chỉ cần xóa dòng 'android: id = "@ android: id / mask' và sau đó đặt màu của có thể vẽ thành bất kỳ màu gì bạn muốn.
Jordan Hochstetler

26

Tôi nghĩ rằng có một chi tiết nhỏ bị bỏ sót.

Nếu bạn vẫn không nhận được hiệu ứng gợn sóng sau khi thêm, android:background="?android:attr/selectableItemBackground"hãy thử thêm các dòng sau vào gốc của bố cục.

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

Những điều này sẽ đảm bảo rằng chế độ xem có thể nhấp được và sẽ kích hoạt hiệu ứng gợn sóng với thuộc tính nền được đề cập ở trên


5

thêm dòng này trong chế độ xem gốc xml của bộ điều hợp của bạn

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

2

Một cách tiếp cận đơn giản và tùy chỉnh là đặt chủ đề chế độ xem như được nêu ở đây .

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>

Các triển khai tùy chỉnh khác có thể được tìm thấy ở đây .


1

Sử dụng kiểu nút

Điều này đã làm việc cho tôi vô số.

Thêm Kiểu nút không viền vào phần tử gốc của bố cục của bạn. Không cần focusablehoặc clickablethuộc tính, kiểu mặc định gói gọn tất cả những điều đó cho bạn.

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

tuyệt, nhưng điều này thêm đệm
ededede

@ededede Bạn có thể sử dụng các thuộc tính XML min-height, max-height, width ... để điều chỉnh theo sở thích của mình.
Felix Favor Chinemerem
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.