如何淡出TextView最后一行的结尾? [英] How to fade out the end of the last line in a TextView?

查看:171
本文介绍了如何淡出TextView最后一行的结尾?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在TextView的最后一行上实现淡出效果,就像Play商店应用中的新增功能"部分一样?

How can we achieve the fade-out effect on the last line of a TextView, like in the "WHAT'S NEW" section in the Play Store app?

推荐答案

我们可以通过对TextView进行子类化,并模仿View对褪色边缘的作用,来实现褪色效果,而只是在最后一步最后一行.

We can accomplish that fade effect relatively simply by subclassing TextView, and mimicking what View does for faded edges, but only in the last stretch of the final line.

在此示例中,我们基本上创建了一个从透明到纯黑色的线性渐变.将根据TextView的最终行长进行缩放,然后在PorterDuff.Mode.DST_OUT的适当区域中进行绘制,这实际上将基础内容清除到相对于给定点的渐变不透明度的程度.

In this example, we basically create a linear gradient that goes from transparent to solid black. This will be scaled according to the TextView's final line length, and then painted in the appropriate area with PorterDuff.Mode.DST_OUT, which essentially clears the underlying content to a degree relative to the gradient's opacity at a given point.

public class FadingTextView extends TextView {

    private static final int FADE_LENGTH_FACTOR = 3;

    private final Shader shader;
    private final Matrix matrix;
    private final Paint paint;
    private final Rect bounds;

    public FadingTextView(Context context) {
        this(context, null);
    }

    public FadingTextView(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.textViewStyle);
    }

    public FadingTextView(Context context, AttributeSet attrs, int defStyleAttribute) {
        super(context, attrs, defStyleAttribute);

        matrix = new Matrix();
        paint = new Paint();
        bounds = new Rect();
        shader = new LinearGradient(0f, 0f, 1f, 0f, 0, 0xFF000000, Shader.TileMode.CLAMP);
        paint.setShader(shader);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // Locals
        final Matrix m = matrix;
        final Rect b = bounds;
        final Layout l = getLayout();

        // Last line index
        final int line = getLineCount() - 1;

        // Determine text direction
        final boolean isRtl = l.getParagraphDirection(line) == Layout.DIR_RIGHT_TO_LEFT;

        // Last line bounds
        getLineBounds(line, b);

        // Adjust end bound to text length
        final int lineStart = l.getLineStart(line);
        final int lineEnd = l.getLineEnd(line);
        final CharSequence text = getText().subSequence(lineStart, lineEnd);
        final int measure = (int) (getPaint().measureText(text, 0, text.length()) + .5f);
        if (isRtl) {
            b.left = b.right - measure;
        }
        else {
            b.right = b.left + measure;
        }

        // Figure fade length
        final int fadeLength = b.width() / FADE_LENGTH_FACTOR;

        // Adjust start bound to fade start
        if (isRtl) {
            b.right = b.left + fadeLength;
        }
        else {
            b.left = b.right - fadeLength;
        }

        // Save the layer
        final int saveCount = canvas.saveLayer(b.left, b.top, b.right,
                                               b.bottom, null,
                                               Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);

        // Let TextView draw itself
        super.onDraw(canvas);

        // Adjust and set the Shader Matrix
        m.reset();
        m.setScale(fadeLength, 1f);
        if (isRtl) {
            m.postRotate(180f, fadeLength / 2f, 0f);
        }
        m.postTranslate(b.left, 0f);
        shader.setLocalMatrix(matrix);

        // Finally draw the fade
        canvas.drawRect(b, paint);

        canvas.restoreToCount(saveCount);
    }
}

这是TextView的直接替代品,您将在布局中类似地使用它.

This is a drop-in replacement for TextView, and you'd use it in your layout similarly.

<com.mycompany.myapp.FadingTextView
    android:layout_width="275dp"
    android:layout_height="wrap_content"
    android:background="#e2f3eb"
    android:textColor="#0b8043"
    android:text="..." />



注意:

  • 渐变长度的计算基于最终线条长度的恒定分数,此处由FADE_LENGTH_FACTOR确定.这似乎与Play商店组件的基本方法相同,因为淡入淡出的绝对长度似乎随行长而变化.可以根据需要更改FADE_LENGTH_FACTOR值.

  • The fade length calculation is based on a constant fraction of the final line length, here determined by FADE_LENGTH_FACTOR. This seems to be the same basic methodology of the Play Store component, as the absolute length of the fade appears to vary with line length. The FADE_LENGTH_FACTOR value can be altered as desired.

如果您正在使用appcompat库及其便利设施,则此类应扩展AppCompatTextView,以确保正确处理着色和其他内容.

If you're using the appcompat library and its amenities, this class should instead extend AppCompatTextView, to ensure that the tinting and whatnot are handled correctly.

这篇关于如何淡出TextView最后一行的结尾?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆