android - 在回收站 View 中发生删除动画时如何隐藏分隔线

标签 android android-recyclerview

RecyclerView 默认情况下,确实带有漂亮的删除动画,只要您 setHasStableIds(true) 并在 getItemId 上提供正确的实现.

最近,我通过 https://stackoverflow.com/a/27037230/72437RecyclerView 中添加了分隔符

结果如下

https://www.youtube.com/watch?v=u-2kPZwF_0w

https://youtu.be/c81OsFAL3zY (为了让播放删除动画时分隔线更明显,我暂时将 RecyclerView 背景更改为红色)

在播放删除动画时,分隔线仍然可见。

但是,如果我查看 GMail 示例,当播放删除动画时,分隔线不再可见。它们被一个纯色区域覆盖。

https://www.youtube.com/watch?v=cLs7paU-BIg

请问,如何在播放删除动画时不显示分隔线,达到与GMail相同的效果?

最佳答案

解决方案相当简单。要为装饰设置动画,您可以并且应该使用 view.getTranslation_()view.getAlpha()。我前段时间写了一篇关于这个确切问题的博客文章,你可以阅读它here .

平移和淡出

默认布局管理器会在 View 被添加或删除时淡出(alpha)并翻译它们。你必须在你的装饰中考虑到这一点。

思路很简单:

However you draw your decoration, apply the same alpha and translation to your drawing by using view.getAlpha() and view.getTranslationY().

根据您的链接答案,它必须进行如下调整:

// 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);

完整示例

我喜欢自己画东西,因为我认为画一条线比布置一个可绘制对象的开销要小,如下所示:

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);
            }
        }
    }
}

关于android - 在回收站 View 中发生删除动画时如何隐藏分隔线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36577042/

相关文章:

android - GCM 和 Parse 通知冲突

android - MediaPlayer的声音被动画中断

android - 从 RecyclerView 检索数据

android - 在每个卡片 View 中有一个微调器 - recyclerview 中的卡片 View

java - 如何在 RecyclerView 中修改 Layout 宽度

android - 当上面的布局高度缩小时向上移动布局

java - 在双向 Recyclerview 中处理水平滚动时禁用 SwipeRefreshLayout

Android::如何断开与wifi网络的连接?

android - 如何从 Project.properties 或 local.properties 中读取属性?

java - 为什么RecyclerView没有显示任何项目?