Эффект RIpple на RecyclerView не работает при легком нажатии

Я попытался реализовать волновой эффект в моем RecyclerView. Вот мой макет для него:

<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"
        android:layout_marginTop="7dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        card_view:cardCornerRadius="5dp"
        android:clickable="true"
        card_view:cardElevation="5dp"
        android:focusable="true"
        android:foreground="?android:attr/selectableItemBackground">

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:padding="16dp">

                <TextView
                    //some properties />

                <TextView
                    //some properties />

                <TextView
                    //some properties />
            </LinearLayout>

    </android.support.v7.widget.CardView>

Чтобы реализовать прослушиватель onclick, я в основном следовал этому руководству здесь: http://sapandiwakar.in/recycler-view-item-click-handler/

Проблема в том, что волновой эффект, генерируемый благодаря линиям:

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

не работает на лёгких (то бишь быстрых) нажатиях. Когда я просто быстро нажимаю на экран, срабатывает прослушиватель кликов. Это означает, что событие касания было обнаружено, однако волновой эффект не проявляется. Если я хочу увидеть волновой эффект, мне нужно немного дольше удерживать давление на экране, прежде чем отпустить.

Есть ли способ исправить это поведение и показать волновой эффект даже для быстрых нажатий?


person Robin Dupont    schedule 16.05.2017    source источник
comment
Используйте 1_. Я думаю, что Marshmallow изменил поведение selectableItemBackground, поэтому он показывает пульсацию только для более длинных нажатий.   -  person Gergely Kőrössy    schedule 12.07.2017


Ответы (3)


Я столкнулся с похожей проблемой. У меня был ItemClickListener в RecyclerView, и в этом слушателе я отправлял новый фрагмент. Путем проб и ошибок я заметил, что при удалении или очистке прослушивателя кликов по элементу подсветка будет отображаться каждый раз, даже при легких нажатиях.

Исправление заключалось в том, чтобы изменить мой метод onItemClick:

@Override
public void onItemClick(final RecyclerView parent, final View view, final int position, final long id)
{
    ViewCompat.postOnAnimationDelayed(parent, new Runnable()
    {
        @Override
        public void run()
        {
            // Your click code goes here
        }
    }, 50);
}

Это откладывает действие щелчка на 50 мс после следующего шага анимации и дает анимации достаточно времени для загрузки и запуска до того, как будет выполнено действие щелчка.

person Theo    schedule 11.07.2017

Это происходит из-за того, что вы использовали addOnItemTouchListener для прослушивателя щелчка элемента. Просто создайте интерфейс в RecyclerAdapter

В адаптере создайте интерфейс

public interface OnItemClickListener {
    void onItemClick(Item item);
}

private final List<ContentItem> items;
private final OnItemClickListener listener;

public Adapter(List<ContentItem> items, OnItemClickListener listener) 
{
   this.items = items;
   this.listener = listener;
}

@Override 
public void onBindViewHolder(ViewHolder holder, int position) {
   holder.bind(items.get(position), listener);
}


//In your Activity
recycler.setAdapter(new Adapter(items, new 
Adapter.OnItemClickListener() {
@Override public void onItemClick(ContentItem item) {
    Toast.makeText(getContext(), "Item Clicked", Toast.LENGTH_LONG).show();
}
}));

вместо приведенного ниже кода, и он будет работать как шарм.

recyclerView.addOnItemTouchListener( 
    new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() {
      @Override public void onItemClick(View view, int position) {
        // TODO Handle item click
      }
   })
);
person Chitrank Dave    schedule 22.09.2017

Давно спрашивал, но подумал, что это может кому-то помочь, я столкнулся с похожей проблемой и использовал метод postDelayed.

   ( new Handler()).postDelayed(new Runnable() {
        @Override
        public void run() {
           //your code 
        }
    }, 100);
person NITIN DUDA    schedule 29.03.2020