Android 为什么列表和状态列表选择器ripple动画不能完全在API24上绘制?
在本例中,问题与RecyclerView有关,我希望涟漪效果能够从手指接触自定义颜色的位置到视图的整个范围进行动画制作(如果不是精确的话),就像视图布局中的listview行一样,最后用另一种颜色选择的行结束动画 我有 items\u row.xmlAndroid 为什么列表和状态列表选择器ripple动画不能完全在API24上绘制?,android,android-recyclerview,rippledrawable,statelistdrawable,Android,Android Recyclerview,Rippledrawable,Statelistdrawable,在本例中,问题与RecyclerView有关,我希望涟漪效果能够从手指接触自定义颜色的位置到视图的整个范围进行动画制作(如果不是精确的话),就像视图布局中的listview行一样,最后用另一种颜色选择的行结束动画 我有 items\u row.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" a
<?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>
<?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>
及
items\u ripple\u state\u selector.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>
<?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>
结果不佳的测试
我在以下设备上进行了测试,其中涟漪效果动画停止得太早,导致更多的是“光点”/“ping”,而不是视图边缘的完全扩展
- Nexus 6、牛轧糖(7.0.0)、API 24
- Nexus 5X,牛轧糖(7.x.x),非100%小版本
- 针对API级别24的不同AVD
- Nexus 5,棉花糖(6.0.1),API等级23
- Nexus 4,棒棒糖(5.1.1),API等级22
有人知道为什么会发生这种情况以及如何解决吗?我不知道为什么它在棉花糖中有效,但在牛轧糖中无效。然而,当您看到这个问题时,最常见的原因是
RecyclerView
太过刷新和/或重新绑定
基本上会发生的是
RecyclerAdapter\notifyItemChanged(int)
方法或RecyclerAdapter\notifyDatasetChanged()
太多次时会发生这种情况
如果可能,最好使用RecyclerView.Adapter#notifyItem uuuuu
方法notifyDatasetChanged()
将导致列表中的所有项目重新绑定。使用notifyItem\uuuuuuuuuuuuu
方法将确保在需要时仅更新单个项目。否则,您需要确保仅在数据集中有实际更改时调用nofityDatasetChanged()
另一个常见问题是,如果应用程序在
RecyclerView
或RecyclerView
的任何父项中调用invalidate
。这将导致整个视图树的刷新,这将需要重新绑定RecyclerView
中的所有项目。我不知道明确的答案,但我知道如果RecyclerView绑定太多,这是非常常见的情况。这是由于在适配器上调用notifyItem\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。使这个问题更难找出问题的根源的原因是,相同的代码只在几个API级别的缺口上工作。这可能更像是一个更大问题的症状。我怀疑现在的情况是,RecyclerView再次将项目绑定到相同的项目上。看起来项目没有改变,但是所有的动画都会重置。是的,你把钉子钉在了这个项目的头上!我在ContentProvider中注释掉了notifyChange调用,它将光标馈送给RecyclerView,而涟漪效应现在正像我所期望的那样产生动画效果。如果你想发表你的评论或类似的回答,我很乐意接受。棘手的调试,这一个!嗯,修复它会更困难,因为如果数据集被更新,您仍然需要这些通知。否则,您的RecyclerView将过时(或者有时会出现异常)。