在回收器视图中发生删除动画时如何隐藏分隔线 [英] How to hide divider when delete animation happens in recycler view
问题描述
RecyclerView
确实具有不错的删除动画,只要您setHasStableIds(true)
并在getItemId
上提供正确的实现即可.
RecyclerView
by default, does come with a nice deletion animation, as long as you setHasStableIds(true)
and provide correct implementation on getItemId
.
最近,我已通过 https://stackoverflow.com/a/27037230/72437RecyclerView >
Recently, I had added divider into RecyclerView
via https://stackoverflow.com/a/27037230/72437
结果如下
https://www.youtube.com/watch?v=u-2kPZwF_0w
https://youtu.be/c81OsFAL3zY (为使分隔线在播放删除动画时更加可见,我暂时将RecyclerView
背景更改为红色)
https://youtu.be/c81OsFAL3zY (To make the dividers more visible when delete animation played, I temporary change the RecyclerView
background to red)
播放删除动画时,分隔线仍然可见.
但是,如果我看一下GMail示例,当播放删除动画时,分隔线将不再可见.它们正在覆盖纯色区域.
However, if I look at GMail example, when deletion animation being played, divider lines are no longer visible. They are being covered a solid color area.
https://www.youtube.com/watch?v=cLs7paU-BIg
我可以知道,在播放删除动画时如何不显示分隔线来达到与GMail相同的效果吗?
May I know, how can I achieve the same effect as GMail, by not showing divider lines, when deletion animation played?
推荐答案
该解决方案非常简单.要为装饰设置动画,可以并且应该使用view.getTranslation_()
和view.getAlpha()
.我前一段时间写了一篇有关此确切问题的博客文章,您可以在此处阅读a>.
The solution is fairly easy. To animate a decoration, you can and should use view.getTranslation_()
and view.getAlpha()
. I wrote a blog post some time ago on this exact issue, you can read it here.
当添加或删除视图时,默认布局管理器将淡出视图并对其进行翻译.您必须在装修时考虑到这一点.
The default layout manager will fade views out (alpha) and translate them, when they get added or removed. You have to account for this in your decoration.
想法很简单:
但是,您绘制装饰时,请使用
view.getAlpha()
和view.getTranslationY()
将相同的Alpha和平移应用于图形.
However you draw your decoration, apply the same alpha and translation to your drawing by using
view.getAlpha()
andview.getTranslationY()
.
在链接答案之后,必须进行如下修改:
Following your linked answer, it would have to be adapted like the following:
// translate
int top = child.getBottom() + params.bottomMargin + view.getTranslationY();
int bottom = top + mDivider.getIntrinsicHeight();
// apply alpha
mDivider.setAlpha((int) child.getAlpha() * 255f);
mDivider.setBounds(left + view.getTranslationX(), top,
right + view.getTranslationX(), bottom);
mDivider.draw(c);
完整的样本
我喜欢自己绘制东西,因为我认为绘制线条比布置可绘制对象的开销少,所以看起来像以下内容:
A complete sample
I like to draw things myself, since I think drawing a line is less overhead than layouting a drawable, this would look like the following:
public class SeparatorDecoration extends RecyclerView.ItemDecoration {
private final Paint mPaint;
private final int mAlpha;
public SeparatorDecoration(@ColorInt int color, float width) {
mPaint = new Paint();
mPaint.setColor(color);
mPaint.setStrokeWidth(width);
mAlpha = mPaint.getAlpha();
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
// we retrieve the position in the list
final int position = params.getViewAdapterPosition();
// add space for the separator to the bottom of every view but the last one
if (position < state.getItemCount()) {
outRect.set(0, 0, 0, (int) mPaint.getStrokeWidth()); // left, top, right, bottom
} else {
outRect.setEmpty(); // 0, 0, 0, 0
}
}
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
// a line will draw half its size to top and bottom,
// hence the offset to place it correctly
final int offset = (int) (mPaint.getStrokeWidth() / 2);
// this will iterate over every visible view
for (int i = 0; i < parent.getChildCount(); i++) {
final View view = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
// get the position
final int position = params.getViewAdapterPosition();
// and finally draw the separator
if (position < state.getItemCount()) {
// apply alpha to support animations
mPaint.setAlpha((int) (view.getAlpha() * mAlpha));
float positionY = view.getBottom() + offset + view.getTranslationY();
// do the drawing
c.drawLine(view.getLeft() + view.getTranslationX(),
positionY,
view.getRight() + view.getTranslationX(),
positionY,
mPaint);
}
}
}
}
这篇关于在回收器视图中发生删除动画时如何隐藏分隔线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!