滚动时为 RecyclerView 设置动画
Posted
技术标签:
【中文标题】滚动时为 RecyclerView 设置动画【英文标题】:Animate RecyclerView when scrolling 【发布时间】:2014-10-12 08:15:30 【问题描述】:当我滚动 RecyclerView 时,有什么方法可以为它的元素设置动画吗?
我看了DefaultItemAnimator
和RecyclerView.ItemAnimator
,但动画似乎只有在数据集发生变化时才会被调用,如果我错了,请纠正我。
我对@987654323@ 什么时候调用有点困惑?我在该类中设置了一些断点,但它们都没有停止我的应用程序。
但是回到我的问题,如何为 RecyclerView 设置动画?我希望某些元素具有另一种不透明度,这取决于一些自定义规则。
我做了更多的研究,似乎动画移动正是我正在寻找的。这些方法是从dispatchLayout()
调用的。这是该方法的javadoc:
layoutChildren() 的包装器,用于处理由布局引起的动画变化。 动画的工作假设有五种不同的项目 在玩: PERSISTENT:项目在布局前后可见 已移除:项目在布局之前可见并已被应用程序移除 添加:项目在布局之前不存在并且由应用程序添加 DISAPPEARING:项目之前/之后存在于数据集中,但从 在布局过程中可见到不可见(它们被移走 屏幕作为其他更改的副作用) 出现:项目之前/之后存在于数据集中,但从 在布局过程中不可见到可见(它们被移到 屏幕作为其他更改的副作用) 整体方法找出布局之前/之后存在哪些项目,以及 推断每个项目的上述五种状态之一。然后是动画 相应地设置: PERSISTENT 视图被移动(@link ItemAnimator#animateMove(ViewHolder, int, int, int, int)) REMOVED 视图被移除 (@link ItemAnimator#animateRemove(ViewHolder)) 添加了视图 (@link ItemAnimator#animateAdd(ViewHolder)) 消失的视图被移出屏幕 出现的视图在屏幕上移动
到目前为止,我正在寻找 PERSISTENT、DISAPPEARING 和 APPEARING,但由于这里的这一行,这些方法永远不会被调用:
boolean animateChangesSimple = mItemAnimator != null && mItemsAddedOrRemoved
&& !mItemsChanged;
mItemsAddedOrRemoved
总是假的,所以没有一个回调到达。知道如何正确设置设置标志吗?
【问题讨论】:
您可以使用 api11 中引入的 objectanimtor 对任何对象进行动画处理 很好,但是我怎么知道什么时候需要开始动画呢? 【参考方案1】:我最终使用OnScrollListener
并以自定义animate()
方法对其进行动画处理。在我的情况下,该代码只需要 2 毫秒,因此对于 60 fps 来说没问题。
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();
);
【讨论】:
你能添加更多代码吗?比如 scrollToNext ? 这超出了我的问题范围。你应该问一个独立的问题。请记住在实施时显示您当前的进度:) @rekire 你能帮我解决我的问题吗:***.com/questions/45858059/…【参考方案2】:我是这样做的。可能会帮助某人。我不知道这是否是最好的方法,但对我来说效果很好。
更新:
要修复快速滚动行为,请覆盖适配器的 onViewDetachedFromWindow
方法并在动画视图上调用 clearAnimation
(在本例中为 holder.itemView.clearAnimation()
)。
up_from_bottom.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="@android:anim/decelerate_interpolator">
<translate
android:fromXDelta="0%" android:toXDelta="0%"
android:fromYDelta="100%" android:toYDelta="0%"
android:duration="400" />
</set>
down_from_top.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="@android:anim/decelerate_interpolator">
<translate
android:fromXDelta="0%" android:toXDelta="0%"
android:fromYDelta="-100%" android:toYDelta="0%"
android:duration="400" />
</set>
最后把这段代码放在onBindViewHolder
的recyclerView
中。创建一个名为 lastPosition 的字段并将其初始化为 -1。
Animation animation = AnimationUtils.loadAnimation(context,
(position > lastPosition) ? R.anim.up_from_bottom
: R.anim.down_from_top);
holder.itemView.startAnimation(animation);
lastPosition = position;
【讨论】:
notifiydatasetchange 时动画再次出现。有什么办法解决吗?【参考方案3】:好的解决方案是在onBindViewHolder
方法中为适配器中的支架设置动画。
摘自 Material Test 项目 Slidenerd 的片段:
@Override
public void onBindViewHolder(ViewHolderBoxOffice holder, int position)
Movie currentMovie = mListMovies.get(position);
//one or more fields of the Movie object may be null since they are fetched from the web
holder.movieTitle.setText(currentMovie.getTitle());
//retrieved date may be null
Date movieReleaseDate = currentMovie.getReleaseDateTheater();
if (movieReleaseDate != null)
String formattedDate = mFormatter.format(movieReleaseDate);
holder.movieReleaseDate.setText(formattedDate);
else
holder.movieReleaseDate.setText(Constants.NA);
int audienceScore = currentMovie.getAudienceScore();
if (audienceScore == -1)
holder.movieAudienceScore.setRating(0.0F);
holder.movieAudienceScore.setAlpha(0.5F);
else
holder.movieAudienceScore.setRating(audienceScore / 20.0F);
holder.movieAudienceScore.setAlpha(1.0F);
if (position > mPreviousPosition)
AnimationUtils.animateSunblind(holder, true);
else
AnimationUtils.animateSunblind(holder, false);
mPreviousPosition = position;
这是link
【讨论】:
此解决方案适用于某个库,并非适用于所有人。以上是关于滚动时为 RecyclerView 设置动画的主要内容,如果未能解决你的问题,请参考以下文章
UICollectionVIew:在视图滚动时为单元格设置动画
javascript [在页面滚动上设置动画粘贴CTA]这将在滚动时为点击元素设置动画,并在用户点击时将其关闭。 #javascript #css #sitewre
javascript [在页面滚动上设置动画粘贴CTA]这将在滚动时为点击元素设置动画,并在用户点击时将其关闭。 #javascript #css #sitewre