Ответ 1
Что-то, о чем не упоминалось в других ответах: установка android:clickable="true"
требуется, чтобы анимация работала, когда на экране не добавлено OnClickListener.
У меня есть этот items.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:focusable="true"
android:clickable="true"
android:background="?android:attr/selectableItemBackground"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="60dp"
android:id="@+id/colorPreview" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textAppearance="@android:style/TextAppearance.Large"
android:textColor="@android:color/white"
android:id="@+id/colorName" />
</RelativeLayout>
Когда я использую его отдельно, selectableItemBackground анимируется, когда я нажимаю на представление. Но когда я использую его для элементов в RecyclerView, эффект на клик больше не случается. Как я могу это исправить?
PS: это прослушиватель RecyclerView, если он имеет значение:
public ColorListOnItemTouchListener(Context context, OnItemClickListener clickListener) {
mClickListener = clickListener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
if(childView != null && mClickListener != null) {
mClickListener.onItemLongPress(childView, index);
}
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
if(childView != null && mClickListener != null) {
mClickListener.onItemClick(childView, index);
}
return true;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
});
}
Спасибо!
Изменить:
public class ColorsCursorAdapter extends RecyclerView.Adapter<ColorsCursorAdapter.ViewHolder> {
private static final int layout = R.layout.color_item;
private Cursor mCursor;
public ColorsCursorAdapter(Cursor c) {
super();
this.mCursor = c;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
TextView name = (TextView) v.findViewById(R.id.colorName);
ImageView image = (ImageView) v.findViewById(R.id.colorPreview);
return new ViewHolder(v, name, image);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
mCursor.moveToPosition(position);
int color = mCursor.getInt(mCursor.getColumnIndex(ColorItem.COLUMN_COLOR));
holder.colorName.setText(Utils.getColorString(color));
holder.colorPreview.setImageDrawable(new ColorDrawable(color));
}
@Override
public int getItemCount() {
if(mCursor != null) {
return mCursor.getCount();
}
return 0;
}
public void swapCursor(Cursor c) {
mCursor = c;
notifyDataSetChanged();
}
public Cursor getCursor() {
return mCursor;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView colorName;
public ImageView colorPreview;
public ViewHolder(View root, TextView colorName, ImageView colorPreview) {
super(root);
root.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//
}
});
this.colorName = colorName;
this.colorPreview = colorPreview;
}
}
}
А адаптер создан с помощью
colorList.setLayoutManager(new LinearLayoutManager(this));
adapter = new ColorsCursorAdapter(null);
colorList.setAdapter(adapter);
Что-то, о чем не упоминалось в других ответах: установка android:clickable="true"
требуется, чтобы анимация работала, когда на экране не добавлено OnClickListener.
Вместо того, чтобы устанавливать его как фон, я устанавливаю его как передний план, он работает. Надеюсь, это будет полезно.
android:foreground="?attr/selectableItemBackground"
В вашем items.xml установите FrameLayout в качестве корневого макета и установите selectableItemBackground для FrameLayout. Это работает для меня, но я не знаю, почему.
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?android:selectableItemBackground">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- your code -->
</RelativeLayout>
</FrameLayout>
Вид, что вы хотите иметь волновой эффект, должен быть кликабельным. Вы можете сделать это, указав android: clickable = "true" в файле XML или установив onClickListener программно. Когда вы используете это для элемента внутри RecyclerView, и вы используете Kotlin, установите onClickListener для "itemView" из класса ViewHolder.
Я видел такое же поведение. С моей стороны это было связано с тем, что, когда я щелкнул элемент списка внутри фрагмента и напрямую заменил этот фрагмент на другой, анимация не успевала показываться. Как только я удалил замену фрагмента, я смог увидеть анимацию.
@Override
public boolean onSingleTapUp(MotionEvent e) {
if(childView != null && mClickListener != null) {
mClickListener.onItemClick(childView, index);
}
return true;
}
Возврат false может решить эту проблему. Для меня я переопределял onTouch на своей кнопке и возвращался в конце. Возврат false включал анимацию касания от установки:
android:background="?attr/selectableItemBackground"
В моем случае проблема была вызвана DividerItemDecoration
. Как только я избавился от этого, он начал работать. Я предлагаю поместить строку в конец файла xml
для каждого элемента в RecyclerView
, это намного проще настроить, и вы не столкнетесь с такими проблемами.
Ни одно из предыдущих решений не помогло мне.
В конце концов мне пришлось реализовать свой собственный drawable для этого, и его работу, как в Android.
Рез/рисуем /selectable_item_background.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>
Так же, как вы использовали Android Drawable
Android: фон = "@вытяжка /selectable_item_background"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/selectable_item_background"
android:clickable="true"
android:orientation="vertical">
...
Для получения дополнительной информации или реализации для версий до API 21. Посмотрите этот пост.
Работает счастливое кодирование
<LinearLayout
android:id="@+id/lly_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="3"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="horizontal"
android:layout_margin="10dp">
</LinearLayout>