如何淡出TextView最后一行的结尾? [英] How to fade out the end of the last line in a 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. TheFADE_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屋!