0

В этом случае вопрос относится к RecyclerView, где я хотел бы, чтобы эффект пульсации был анимирован (грубо, если не совсем), откуда палец коснулся пользовательского цвета в полной мере просмотра, что очень похоже на просмотр списка строка с точки зрения макета представления и, наконец, завершает свою анимацию строкой, выбранной в другом цвете.Почему анимация пульсации списка и списка состояний не полностью нарисована на API24?

У меня есть

items_row.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/rowLayout" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" 
    android:paddingBottom="5dp" 
    android:paddingTop="5dp" 
    android:background="@drawable/items_ripple_state_selector" 
    > 

    <RelativeLayout 
    android:layout_width="0dp" 
    android:layout_height="match_parent" 
    android:layout_weight="1" 
    android:gravity="center"> 

    <TextView 
     android:id="@+id/item_unit" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/item_amount" 
     android:layout_centerHorizontal="true" 
     android:gravity="center" 
     android:text="unit" /> 

    <TextView 
     android:id="@+id/item_amount" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentTop="true" 
     android:layout_centerHorizontal="true" 
     android:gravity="center" 
     android:text="amount" /> 
    </RelativeLayout> 

    <RelativeLayout 
    android:layout_width="0dp" 
    android:layout_height="match_parent" 
    android:layout_weight="4.6" 
    android:gravity="center_vertical"> 

    <TextView 
     android:id="@+id/item_title" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="title" 
     android:textAppearance="?android:attr/textAppearanceLarge" /> 

    <TextView 
     android:id="@+id/item_description" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignLeft="@+id/item_title" 
     android:layout_alignWithParentIfMissing="true" 
     android:layout_below="@+id/item_title" 
     android:text="description" /> 
    </RelativeLayout> 
</LinearLayout> 

и

items_ripple_state_selector.xml

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item> 
    <selector> 
     <item android:state_pressed="true" android:drawable="@color/state_activated" /> 
     <item android:state_selected="true" android:drawable="@color/state_selected" /> 
     <item android:drawable="@android:color/transparent" /> 
    </selector> 
    </item> 
    <item> 
    <ripple android:color="@color/primary"> 
     <item android:id="@android:id/mask"> 
     <color android:color="@android:color/white" /> 
     </item> 
    </ripple> 
    </item> 
</layer-list> 

Тесты, которые вышли из строя

Я провел тесты на следующих устройствах, в которых анимация эффекта пульсации останавливается слишком рано, в результате чего больше происходит «блик»/«пинг», а не полное расширение до представления кромки.

  • Nexus 6, нуга (7.0.0), API 24
  • Nexus 5X, нуга (7.xx), а не 100% на младшую версию
  • Различный уровень ориентируетесь API AVD в 24

тесты, которые вышли хорошо

Я делал тесты на следующих устройствах, в которых волновой эффект анимации одушевляет красиво в том, что я бы ожидать, является его полная длина, к краям вида по:

  • Nexus 5, Зефир (6.0.1), уровень API 23
  • Nexus 4, леденец (5.1.1), уровень API 22

Я не могу на всю жизнь понять, что происходит с этим. Это выглядит довольно ужасно на N6 и N5X, так как анимация останавливается в середине, без каких-либо различий в том, когда анимация прекращается.

Я прочитал немало вопросов SO, а также документации RecyclerView, StateListDrawable и RippleDrawable, но нет ничего, что давало бы объяснения поведению, которое я вижу.

Ближайший я пришел, что это то, что я в данный момент, и то, что я поделился в этой должности с точки зрения кода, пришел из этого ответа https://stackoverflow.com/a/31335539/975641

Кто-нибудь есть идея, почему это происходит и как это исправить?

+1

Я не знаю явного ответа, но я знаю, что это очень распространенное явление, если RecyclerView слишком сильно связывает. Это вызвано либо вызовом 'notifyItem _____', либо' notifyDatasetChanged' слишком много на адаптере. – DeeV

+0

Хорошо, я мог бы изучить это и посмотреть, что это дает. Что затрудняет проблему, чтобы определить источник проблемы, так это то, что один и тот же код работает на нескольких паре уровня API. –

+1

Это может быть больше симптомом более серьезной проблемы. Я подозреваю, что все, что происходит, это RecyclerView снова привязывает элементы к тем же элементам. Было бы похоже, что элементы не изменились, но все анимации будут сброшены. – DeeV

ответ

0

Я не знаю конкретной причины, почему это работает в Зефире, но не Нуга. Однако чаще всего, когда вы видите эту проблему, это потому, что RecyclerView освежает и/или повторно связывает слишком много.

В принципе, что произойдет это

  1. Пользователь щелкает
  2. Анимация начинается
  3. то, что называется для перепривязки по этому пункту
  4. RecyclerView вызовы повторно связать по пункту
  5. анимация отменяется, так как просмотр сбрасывается.

Чаще всего это происходит при вызове либо RecyclerAdapter#notifyItemChanged(int) метод или RecyclerAdapter#notifyDatasetChanged() слишком много раз.

Было бы лучше использовать методы RecyclerView.Adapter#notifyItem____, если это возможно. notifyDatasetChanged() вызовет повторную проверку всех элементов в списке. Используя методы notifyItem_____, вы убедитесь, что только отдельные элементы обновляются, когда они должны быть. В противном случае вам необходимо обеспечить только вызов nofityDatasetChanged() при фактическом изменении в наборе данных.

Еще одна распространенная проблема заключается в том, что приложение вызывает invalidate либо в RecyclerView, либо в любом родителе RecyclerView. Это приведет к обновлению всего дерева View, для которого потребуется переподготовка для всех элементов в RecyclerView.

Смежные вопросы