滚动时动画 RecyclerView [英] Animate RecyclerView when scrolling
问题描述
当我滚动 RecyclerView 时,有什么方法可以为它的元素设置动画吗?
Is there any way to animate the elements of a RecyclerView when I scroll it?
我查看了 DefaultItemAnimator
和 RecyclerView.ItemAnimator
,但似乎只有在数据集发生变化时才会调用动画,如果我错了,请纠正我.
I took a look at DefaultItemAnimator
and RecyclerView.ItemAnimator
, but that animations seems to be only called if the dataset has changed, please correct me if I am wrong.
我对 RecyclerView.ItemAnimator.animateMove()
什么时候调用它有点困惑?我在该类中设置了一些断点,但没有一个会停止我的应用程序.
I'm a little confused about RecyclerView.ItemAnimator.animateMove()
when is it called? I put some breakpoints into that class but none of them stops my app.
但是回到我的问题,如何为 RecyclerView 设置动画?我希望某些元素具有另一种不透明度,这取决于某些自定义规则.
However back to my question how can I animate the RecyclerView? I want that some elements have another opacity, depended on some custom rules.
我做了一些更多的研究,似乎动画移动正是我正在寻找的.这些方法是从 dispatchLayout()
调用的.这是该方法的 javadoc:
I did some more reaseach it seems that animation move is exactly that what I'm looking for. That methods are called from dispatchLayout()
. Here is the javadoc of that method:
layoutChildren() 周围的包装器,用于处理由布局引起的动画变化.动画的工作假设有五种不同的项目在玩:
持久性:项目在布局前后可见
REMOVED:项目在布局之前可见并被应用程序删除
添加:项目在布局之前不存在并且是由应用程序添加的
DISAPPEARING:项目存在于数据集中之前/之后,但从在布局过程中可见到不可见(它们被移开屏幕作为其他更改的副作用)
APPEARING:项目存在于数据集中之前/之后,但从在布局过程中不可见到可见(它们被移动了屏幕作为其他更改的副作用)
整体方法确定布局之前/之后存在哪些项目,以及为每个项目推断上述五个状态之一.然后是动画进行了相应的设置:
PERSISTENT 视图被移动 ({@link ItemAnimator#animateMove(ViewHolder, int, int, int, int)})REMOVED 视图被移除 ({@link ItemAnimator#animateRemove(ViewHolder)})
添加了添加的视图 ({@link ItemAnimator#animateAdd(ViewHolder)})
DISAPPEARING 视图已移出屏幕
APPEARING 视图在屏幕上移动
Wrapper around layoutChildren() that handles animating changes caused by layout. Animations work on the assumption that there are five different kinds of items in play:
PERSISTENT: items are visible before and after layout
REMOVED: items were visible before layout and were removed by the app
ADDED: items did not exist before layout and were added by the app
DISAPPEARING: items exist in the data set before/after, but changed from visible to non-visible in the process of layout (they were moved off screen as a side-effect of other changes)
APPEARING: items exist in the data set before/after, but changed from non-visible to visible in the process of layout (they were moved on screen as a side-effect of other changes)
The overall approach figures out what items exist before/after layout and infers one of the five above states for each of the items. Then the animations are set up accordingly:
PERSISTENT views are moved ({@link ItemAnimator#animateMove(ViewHolder, int, int, int, int)}) REMOVED views are removed ({@link ItemAnimator#animateRemove(ViewHolder)})
ADDED views are added ({@link ItemAnimator#animateAdd(ViewHolder)})
DISAPPEARING views are moved off screen
APPEARING views are moved on screen
到目前为止,我正在寻找 PERSISTENT、DISAPPEARING 和 APPEARING,但由于这里的这一行,这些方法从未被调用:
So far I'm looking for PERSISTENT, DISAPPEARING and APPEARING, but that methods are never called because of this line here:
boolean animateChangesSimple = mItemAnimator != null && mItemsAddedOrRemoved
&& !mItemsChanged;
mItemsAddedOrRemoved
总是假的,所以没有一个回调被到达.知道如何正确设置设置标志吗?
mItemsAddedOrRemoved
is simply always false so none of that callback are ever reached. Any idea how to set set flag correctly?
推荐答案
我最终使用了 OnScrollListener
并在自定义 animate()
方法中对其进行了动画处理.在我的情况下,代码只需要 2 毫秒,因此对于 60fps 来说没有问题.
I ended in using an OnScrollListener
and animating it in a custom animate()
method. In my case that code takes just 2ms so that is no problem for the 60fps.
recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(int newState) {
if(newState == RecyclerView.SCROLL_STATE_IDLE) {
// special handler to avoid displaying half elements
scrollToNext();
}
animate();
}
@Override
public void onScrolled(int dx, int dy) {
animate();
}
});
这篇关于滚动时动画 RecyclerView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!