Я хотел бы включить сенсорную обратную связь для своей библиотеки Open Source.
Я создал RecyclerView
и CardView
. CardView
содержит разные области с различными действиями onClick
. Теперь я хотел бы вызвать эффект Ripple, если пользователь щелкает в любом месте карты, но я не могу добиться такого поведения.
Это мой список, вы также можете найти его на GitHub: https://github.com/mikepenz/AboutLibraries/blob/master/library/src/main/res/layout/listitem_opensource.xml
<RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" android:clickable="true" android:background="@drawable/button_rect_normal"/> <LinearLayout android:padding="6dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <LinearLayout android:gravity="center_vertical" android:paddingLeft="8dp" android:paddingRight="8dp" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/libraryName" android:textColor="@color/title_openSource" android:textSize="@dimen/textSizeLarge_openSource" android:textStyle="normal" android:layout_width="0dp" android:layout_weight="5" android:layout_height="wrap_content" android:ellipsize="end" android:maxLines="1"/> <TextView android:id="@+id/libraryCreator" android:textColor="@color/text_openSource" android:textStyle="normal" android:layout_width="0dp" android:layout_weight="2" android:layout_height="wrap_content" android:layout_marginTop="2dp" android:gravity="right" android:maxLines="2" android:textSize="@dimen/textSizeSmall_openSource"/> </LinearLayout> <View android:layout_width="match_parent" android:layout_height="1px" android:layout_marginTop="4dp" android:background="@color/dividerLight_openSource"/> <TextView android:id="@+id/libraryDescription" android:textSize="@dimen/textSizeSmall_openSource" android:textStyle="normal" android:textColor="@color/text_openSource" android:padding="8dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:maxLines="20"> </TextView> <View android:id="@+id/libraryBottomDivider" android:layout_width="match_parent" android:layout_height="1px" android:layout_marginTop="4dp" android:background="@color/dividerLight_openSource"/> <LinearLayout android:id="@+id/libraryBottomContainer" android:gravity="center_vertical" android:paddingLeft="8dp" android:paddingTop="4dp" android:paddingRight="8dp" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@+id/libraryVersion" android:textColor="@color/text_openSource" android:textStyle="normal" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:gravity="left" android:maxLines="1" android:textSize="@dimen/textSizeSmall_openSource"/> <TextView android:id="@+id/libraryLicense" android:textColor="@color/text_openSource" android:textStyle="normal" android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:gravity="right" android:maxLines="1" android:textSize="@dimen/textSizeSmall_openSource"/> </LinearLayout> </LinearLayout>
И onClick
установлен на 3 части этого макета. libraryCreator
, libraryCreator
и libraryBottomContainer
.
Надеюсь, кто-то понял, что здесь происходит не так.
Спасибо за вашу помощь.
Предполагая, что вы используете тему Material / Appcompat и Lollipop, я получил это, чтобы сделать CardView следующими атрибутами:
android:focusable="true" android:clickable="true" android:foreground="?android:attr/selectableItemBackground"
CardLayout – это просто подкласс ViewGroup, поэтому настройка:
android:background="?android:attr/selectableItemBackground"
Должен сделать трюк.
ОБНОВИТЬ:
(Похоже, вы пытаетесь использовать собственный цвет пульсации).
Попытайтесь использовать рябь, выбирая с пользовательским цветом в качестве фона (я не использовал это, поэтому я не могу проверить это поведение.) См. Документацию или этот вопрос, чтобы вы начали.
для меня:
android:background="?android:attr/selectableItemBackground"
Наконец, закончил работу. См. Фон recyclerView / content позади элемента, а также см. Эффект пульсации, используемый с recyclerView.
Ни один из вышеперечисленных ответов не работал для меня или был слишком сложным.
Тогда я понял, что должен был установить следующие свойства в АДАПТЕРЕ РЕЦИКЛЕРОВ.
android:background="?android:attr/selectableItemBackground" android:focusable="true" android:clickable="true"
Затем я получил его на работу.
Теперь я смог решить проблему.
Проблема в том, что я использую onClickListener в TextViews, и этот прослушиватель кликов предотвращает уведомление RippleForeground о событии touch. Таким образом, решение состоит в том, чтобы реализовать TouchListener в этих TextViews и пройти через сенсорное событие.
Класс действительно прост и может использоваться повсеместно:
package com.mikepenz.aboutlibraries.util; import android.support.v7.widget.CardView; import android.view.MotionEvent; import android.view.View; /** * Created by mikepenz on 16.04.15. */ public class RippleForegroundListener implements View.OnTouchListener { CardView cardView; public RippleForegroundListener setCardView(CardView cardView) { this.cardView = cardView; return this; } @Override public boolean onTouch(View v, MotionEvent event) { // Convert to card view coordinates. Assumes the host view is // a direct child and the card view is not scrollable. float x = event.getX() + v.getLeft(); float y = event.getY() + v.getTop(); if (android.os.Build.VERSION.SDK_INT >= 21) { // Simulate motion on the card view. cardView.drawableHotspotChanged(x, y); } // Simulate pressed state on the card view. switch (event.getActionMasked()) { case MotionEvent.ACTION_DOWN: cardView.setPressed(true); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: cardView.setPressed(false); break; } // Pass all events through to the host view. return false; } }
Его можно использовать, добавив это как TouchListener:
RippleForegroundListener rippleForegroundListener = new RippleForegroundListener(); older.libraryCreator.setOnTouchListener(rippleForegroundListener);
Этот слушатель просто пройдет через сенсорное событие в CardView и активирует правильный эффект пульсации. (Вы также можете изменить это, чтобы получить любое представление. Он не должен ограничиваться CardView)
android:foreground="?android:attr/selectableItemBackground"
Если вместо фона используется фон переднего плана, вам не нужно использовать интерактивный или настраиваемый
В моем случае мне нужно было показать собственный фон и эффект пульсации. Таким образом, я достиг этого, применяя эти два атрибута в корневом макете моего объекта ресайклеров:
android:background="@drawable/custom_bg" android:foreground="?android:attr/selectableItemBackground"
Имел ту же проблему, что и Цзян:
Я должен установить атрибуты в макет-файл, который раздувает RecycleView.
My Main-Layout: ( Не добавляйте сюда свойства!)
<?xml version="1.0" encoding="utf-8"?> <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="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" /> </RelativeLayout>
Мой RecycleViewAdapter:
View v = inflater.inflate(R.layout.list_center_item, parent, false);
Мой list_center_item.xml ( добавьте свойства здесь! )
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:background="?android:attr/selectableItemBackground" android:clickable="true" android:focusable="true" />
Вы должны добавить следующие строки в макете, которые вы используете в CardView
android:clickable="true" android:focusable="true" android:background="@drawable/my_ripple"
пример
<android.support.v7.widget.CardView android:layout_height="wrap_content" android:layout_width="match_parent" xmlns:android="http://schemas.android.com/apk/res/android"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:clickable="true" android:focusable="true" android:background="@drawable/my_ripple">