JHH*_*JHH 7 android android-support-library android-recyclerview
我使用的是RecyclerView一个SortedList使用a的数据SortedListAdapterCallback.我想禁用onChange事件的动画,但保留它们为onInserted/ onRemoved/ onMoved.我曾尝试调用setSupportsChangeAnimations(false)上DefaultItemAnimator使用的RecyclerView,但动画仍然出现.如果我调用setItemAnimator(null) 所有动画都按预期成功删除了.
我试着查看实现,看起来似乎supportsChangeAnimations是true,RecyclerView通过保持旧的viewHolder并将其交叉淡入到新的viewHolder ,将动画更改事件.我不希望这样.如果supportsChangeAnimations是false,新老viewHolders然而,将相同的对象,而且会有替代地是onMoved动画从x到x(即没有实际移动).然而,这意味着该项目将产生令人讨厌的反弹效果.我也不想要那个,我根本不需要动画.:(
来自DefaultItemAnimator.java:
@Override
public boolean animateChange(ViewHolder oldHolder, ViewHolder newHolder,
int fromX, int fromY, int toX, int toY) {
if (oldHolder == newHolder) {
// Don't know how to run change animations when the same view holder is re-used.
// run a move animation to handle position changes.
return animateMove(oldHolder, fromX, fromY, toX, toY);
}
...
Run Code Online (Sandbox Code Playgroud)
有时当我加载我的列表时,我异步地获取一些数据并更新项目1-3次,当它每次都弹跳和闪烁时看起来真的很糟糕.
如何在onChange不诉诸编写完全自定义的ItemAnimator的情况下有效地完全禁用动画?
Den*_*nis 12
我参加这个派对有点晚了,但是使用androidx.recyclerview:recyclerview:1.1.0我可以将默认动画师的更改设置changeDuration为 0,这有效地禁用了动画,同时允许添加/移动/删除动画继续正常运行。不需要自定义覆盖DefaultItemAnimator.
示例(在 Kotlin 中):
view.my_recycler_view.itemAnimator?.changeDuration = 0
Run Code Online (Sandbox Code Playgroud)
查看代码(我正在使用支持库25.2.0):setSupportsChangeAnimations(<value>)是抽象类的一个方法SimpleItemAnimator,它也是DefaultItemAnimator超类.在内部,它修改了值mSupportsChangeAnimations.
在DefaultItemAnimator代码中执行文本搜索,显示既没有mSupportsChangeAnimations,也没有getSupportsChangeAnimations()查询 - > DefaultItemAnimator字面上忽略了这个标志.
正确的解决方案是以DefaultItemAnimator下列方式扩展:
public class CustomItemAnimator extends DefaultItemAnimator {
@Override
public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromX, int fromY, int toX, int toY) {
if (getSupportsChangeAnimations()) {
return super.animateChange(oldHolder, newHolder, fromX, fromY, toX, toY);
} else {
if (oldHolder == newHolder) {
if (oldHolder != null) {
//if the two holders are equal, call dispatch change only once
dispatchChangeFinished(oldHolder, /*ignored*/true);
}
} else {
//else call dispatch change once for every non-null holder
if (oldHolder != null) {
dispatchChangeFinished(oldHolder, true);
}
if (newHolder != null) {
dispatchChangeFinished(newHolder, false);
}
}
//we don't need a call to requestPendingTransactions after this, return false.
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
查看文档animateChange(...)以了解dispatchChangeFinished(...)在没有运行动画时需要调用的原因.
当没有动画可以运行时,可能有一种更优雅的方式来编写else分支,但是唉,这实现了所需的行为.
有点晚了,但希望这有帮助!
上面的解决方案不适用于支持库版本25.3.1的我,因为我想禁用所有回收者视图项目的动画。我通过重写解决了它SimpleItemAnimator:
private class NoAnimationItemAnimator extends SimpleItemAnimator {
@Override
public boolean animateRemove(RecyclerView.ViewHolder holder) {
dispatchRemoveFinished(holder);
return false;
}
@Override
public boolean animateAdd(RecyclerView.ViewHolder holder) {
dispatchAddFinished(holder);
return false;
}
@Override
public boolean animateMove(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
dispatchMoveFinished(holder);
return false;
}
@Override
public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromX, int fromY, int toX, int toY) {
dispatchChangeFinished(oldHolder, true);
dispatchChangeFinished(newHolder, false);
return false;
}
@Override
public void runPendingAnimations() {
// stub
}
@Override
public void endAnimation(RecyclerView.ViewHolder item) {
// stub
}
@Override
public void endAnimations() {
// stub
}
@Override
public boolean isRunning() {
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5951 次 |
| 最近记录: |