Hiệu ứng gợn trên CardView Android Lollipop


189

Tôi đang cố gắng để CardView hiển thị hiệu ứng gợn khi chạm bằng cách đặt thuộc tính android: backgound trong tệp XML hoạt động như được mô tả ở đây trên trang Nhà phát triển Android, nhưng nó không hoạt động. Không có hình ảnh động nào, nhưng phương thức trong onClick được gọi. Tôi cũng đã thử tạo một tệp ripple.xml như được đề xuất ở đây , nhưng kết quả tương tự.

CardView như xuất hiện trong tệp XML của hoạt động:

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

Tôi còn khá mới đối với sự phát triển của Android, vì vậy tôi có thể đã mắc một vài sai lầm rõ ràng.
Cảm ơn trước.

Câu trả lời:


590

Bạn nên thêm vào sau CardView:

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

8
Hoạt động trên kẹo mút với hiệu ứng gợn nhưng chỉ cho màu đặc khi chạy trên nền tảng cũ. Đủ tốt cho tôi :)
mach

16
Một quan sát nhỏ: Tôi lưu ý rằng thuộc tính có thể nhấp là không cần thiết và thậm chí có thể phá vỡ một số thứ! Tôi đã có một GridView chứa đầy CardViews có thể nhấp và trình nghe không hoạt động đúng. Tôi đã xóa thẻ có thể nhấp khỏi XML và mọi thứ hiện đang hoạt động hoàn hảo
Joaquin Iurchuk

2
@joaquin mà không thể nhấp được, nó làm cho gợn chỉ bắt nguồn từ trung tâm
frostymarvelous

2
?android:attr/selectableItemBackgroundyêu cầu API cấp 11
Pratik Butani

9
Làm việc mà không có android:clickable="true".
Sean

30

Thêm hai mã dòng này vào chế độ xem xml của bạn để tạo hiệu ứng gợn trên cardView của bạn.

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

Tuyệt vời! foregroundlàm việc với quan điểm nền tùy chỉnh như một nét duyên dáng! Đẹp!
sud007

24

Tôi đã quản lý để có được hiệu ứng gợn trên cardview bằng cách:

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

và đối với custom_bg mà bạn có thể thấy trong đoạn mã trên, bạn phải xác định tệp xml cho cả thiết bị kẹo mút (trong gói drawable-v21) và thiết bị tiền kẹo mút (trong gói có thể rút được). đối với custom_bg trong gói drawable-v21, mã là:

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

đối với custom_bg trong gói drawable, mã là:

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

Vì vậy, trên các thiết bị kẹo mút trước, bạn sẽ có hiệu ứng nhấp chuột vững chắc và trên các thiết bị kẹo mút, bạn sẽ có hiệu ứng gợn trên thẻ xem.


1
Xin chào, tôi nhận ra bằng cách áp dụng bộ chọn (hoặc Ripple) trên nền trước của CardView, nó sẽ chặn trẻ em trong chính CardView - stackoverflow.com/questions/33763403/. Tôi có thể biết bạn có gặp phải vấn đề tương tự như tôi không? Hoặc, tôi có bỏ lỡ điều gì không? Cảm ơn.
Cheok Yan Cheng

@CheokYanCheng: Tôi không gặp phải bất kỳ vấn đề nào như của bạn nhưng tôi sẽ nói từ kinh nghiệm cá nhân rằng cardView có một số lỗi đối với kẹo mút trước. Tránh sử dụng cardview: độ cao tài sản trong kẹo mút trước. Các công việc trên tốt cho tôi và các upvote khác.
Rahul Ahuja

Tôi có thể biết, giá trị của colorHighlight & navigation_drawer_background của bạn là gì không. Nếu bạn đã sử dụng màu được xác định của riêng bạn mà không trong suốt, bạn vẫn có thể nhìn thấy con của thẻ của mình chứ?
Cheok Yan Cheng

@CheokYanCheng: các giá trị là, <color name = "navigation_drawer_background"> ​​# FFFFFF </ color> <color name = "colorHighlight"> # FF8A65 </ color>
Rahul Ahuja

Tôi không làm việc cho trường hợp của tôi. Tôi sử dụng bộ chọn của bạn làm tiền cảnh. Như mong đợi, màu trắng đặc (navigation_drawer_background), được sử dụng làm tiền cảnh xem thẻ sẽ chặn khả năng hiển thị của tất cả trẻ em - i.imgur.com/CleYh5B.png Đây là giao diện mà không cần áp dụng bộ chọn làm tiền cảnh - i.imgur. com / ZXk5Aoq.png
Yan Cheng

14

Hiệu ứng gợn đã bị bỏ qua trong thư viện hỗ trợ appcompat, đó là những gì bạn đang sử dụng. Nếu bạn muốn xem Ripple, hãy sử dụng phiên bản Android L và thử nghiệm nó trên thiết bị Android L. Trên trang web AppCompat v7:

"Tại sao không có Ripple trên pre-Lollipop? Rất nhiều thứ cho phép RippleDrawable chạy trơn tru là RenderThread mới của Android 5.0. Để tối ưu hóa hiệu suất trên các phiên bản Android trước đây, chúng tôi đã bỏ RippleDrawable ngay bây giờ."

Kiểm tra liên kết này ở đây để biết thêm


Đó sẽ là nó. Cảm ơn!
AkraticCritic

39
Nhưng làm thế nào bạn có thể đặt hiệu ứng gợn lên cardView cho Android Lollipop?
nhà phát triển Android

Vì vậy, tôi phải quyết định giữa khả năng tương thích ngược bằng cách sử dụng appcompat hoặc có tất cả các hiệu ứng mới, sử dụng các lớp từ lõi Android nhưng tự giới hạn mình với API 21?
Urs Reupke

Bạn có thể tạo 2 APK cho 21+ và cái kia cho <21. Hoặc chia mã vì 21+ sẽ không sử dụng supportActionbar, v.v.
Mathijs Segers

1
Đây là lý do tại sao việc viết các ứng dụng Android L "thuần túy" hiện không khả thi. Kể từ tháng 7 năm 2015, bạn sẽ nhắm mục tiêu 12% cơ sở người dùng Android.
Glenn Bech

9

Nếu ứng dụng minSdkVersionbạn đang làm việc là cấp 9, bạn có thể sử dụng:

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

Thay vào đó, bắt đầu từ cấp 11, bạn sử dụng:

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

Từ tài liệu:

có thể nhấp - Xác định xem chế độ xem này có phản ứng với các sự kiện nhấp hay không. Phải là giá trị boolean, "true" hoặc "false".

foreground - Xác định drawable để vẽ trên nội dung. Điều này có thể được sử dụng như một lớp phủ. Có thể rút ra tiền cảnh tham gia vào phần đệm của nội dung nếu trọng lực được đặt thành lấp đầy.


6

Đối với tôi, việc thêm foregroundvào CardViewkhông hoạt động (không rõ lý do: /)

Thêm tương tự vào bố cục con của nó đã làm mẹo.

MÃ:

<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
Đó là bởi vì đứa trẻ chặn sự kiện, nếu bạn thử một cái gì đó như thêm phần đệm vào cardview (giống như 20dp), và bạn nhấp vào phần mà phần đệm sẽ ở đó, thì bạn sẽ thấy hiệu ứng gợn ngay cả khi không có đứa trẻ bộ thuộc tính tiền cảnh
Cruces

1
Điều này cũng hiệu quả với tôi, bằng cách sử dụng Thành phần Vật liệu mới: com.google.android.m vật.card.M vật liệu Xem. Tôi đã có một stateListAnimator độ cao cho chế độ xem thẻ để điều chỉnh độ cao và gợn được áp dụng cho bố cục ràng buộc bên trong với nền vật phẩm có thể chọn trong nền trước mà không có thuộc tính có thể nhấp.
Patty P

Bây giờ tôi không nhớ nó, nhưng có một cách để đặt các quan điểm trẻ em không phản ứng với sự kiện nhấp chuột
Ai đó ở đâu đó vào

3

Thêm hai mã giống như mã này hoạt động như một nét quyến rũ cho bất kỳ chế độ xem nào như Nút, Bố cục tuyến tính hoặc CardView Chỉ cần đặt hai dòng này và xem phép thuật ...

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

2

Nếu có bố cục gốc như RelativeLayout hoặc linearLayout chứa tất cả thành phần của mục bộ điều hợp trong CardView, bạn phải đặt thuộc tính nền trong bố cục gốc đó. giống:

<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

Sự kiện Ripple để Cardviewđiều khiển 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

Tôi không hài lòng với AppCompat, vì vậy tôi đã viết CardView của riêng mình và gợn sóng backport. Ở đây, nó chạy trên Galaxy S với Gingerbread, vì vậy chắc chắn là có thể.

Bản demo của Ripple trên Galaxy S

Để biết thêm chi tiết kiểm tra mã nguồn .


liên kết bị hỏng
temirbek

1

Thêm phần sau vào xml của bạn:

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

Và thêm vào bộ chuyển đổi của bạn (nếu đó là trường hợp của bạn)

    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

Đối với những người tìm kiếm giải pháp cho vấn đề hiệu ứng gợn không hoạt động trên CardView được tạo theo chương trình (hoặc trong trường hợp tùy chỉnh của tôi mở rộng CardView) được hiển thị trong RecyclerView, phần sau đây hoạt động với tôi. Về cơ bản khai báo các thuộc tính XML được đề cập trong các câu trả lời khác trong tệp bố cục XML dường như không hoạt động đối với CardView được tạo theo chương trình hoặc một thuộc tính được tạo từ bố cục tùy chỉnh (ngay cả khi chế độ xem gốc là CardView hoặc phần tử hợp nhất được sử dụng), vì vậy chúng phải được thiết lập theo chương trình như vậy:

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

Trường hợp MadeupCardView extends CardViewKudos cho câu trả lời này cho TypedArrayphần.


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

Chỉ hoạt động api 21 và sử dụng này không sử dụng chế độ xem thẻ hàng danh sách này

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.