如何淡出TextView中最后一行的结尾?

Vij*_*ana 9 android textview android-layout

我们如何在最后一行实现淡出效果TextView,例如Play商店应用中的"WHAT'NE NEW"部分?

Play商店应用的屏幕截图

Mik*_* M. 8

我们可以通过子类化相对简单地完成淡入淡出效果TextView,并模仿View褪色边缘的效果,但仅限于最后一行的最后一段.

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是替代品TextView,您可以在布局中使用它.

<com.mycompany.myapp.FadingTextView
    android:layout_width="275dp"
    android:layout_height="wrap_content"
    android:background="#e2f3eb"
    android:textColor="#0b8043"
    android:text="..." />
Run Code Online (Sandbox Code Playgroud)

截图


笔记:

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

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