gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:06:37 28 4
gpt4 key购买 nike

我们如何才能在 TextView 的最后一行实现淡出效果,就像在 Play 商店应用的“WHAT'S NEW”部分?

Screenshot of Play Store app

最佳答案

淡入淡出效果可以通过子类化 TextView 类来拦截它的绘制,并像 View 类那样做来淡出边缘来实现,但仅限于最终文本行的最后一段。

在这个例子中,我们创建了一个从透明到纯黑色的单位水平线性渐变。当我们准备绘制时,这个单位渐变被缩放到一个长度,计算为 TextView 的最终行长度的简单分数,然后相应地定位。

创建了一个离屏缓冲区,我们让 TextView 将其内容绘制到该缓冲区。然后,我们使用 PorterDuff.Mode.DST_OUT 的传输模式在其上绘制淡入淡出渐变,这实质上将底层内容清除到相对于给定点处渐变不透明度的一定程度。将该缓冲区绘制回屏幕上会导致所需的淡入淡出,无论背景是什么。

public class FadingTextView extends AppCompatTextView {

private static final float FADE_LENGTH_FACTOR = .4f;

private final RectF drawRect = new RectF();
private final Rect realRect = new Rect();
private final Path selection = new Path();
private final Matrix matrix = new Matrix();
private final Paint paint = new Paint();
private final Shader shader =
new LinearGradient(0f, 0f, 1f, 0f, 0x00000000, 0xFF000000, Shader.TileMode.CLAMP);

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

paint.setShader(shader);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
}

@Override
protected void onDraw(Canvas canvas) {
// Locals
final RectF drawBounds = drawRect;
final Rect realBounds = realRect;
final Path selectionPath = selection;
final Layout layout = getLayout();

// Figure last line index, and text offsets there
final int lastLineIndex = getLineCount() - 1;
final int lastLineStart = layout.getLineStart(lastLineIndex);
final int lastLineEnd = layout.getLineEnd(lastLineIndex);

// Let the Layout figure a Path that'd cover the last line text
layout.getSelectionPath(lastLineStart, lastLineEnd, selectionPath);
// Convert that Path to a RectF, which we can more easily modify
selectionPath.computeBounds(drawBounds, false);

// Naive text direction determination; may need refinement
boolean isRtl =
layout.getParagraphDirection(lastLineIndex) == Layout.DIR_RIGHT_TO_LEFT;

// Narrow the bounds to just the fade length
if (isRtl) {
drawBounds.right = drawBounds.left + drawBounds.width() * FADE_LENGTH_FACTOR;
} else {
drawBounds.left = drawBounds.right - drawBounds.width() * FADE_LENGTH_FACTOR;
}
// Adjust for drawables and paddings
drawBounds.offset(getTotalPaddingLeft(), getTotalPaddingTop());

// Convert drawing bounds to real bounds to determine
// if we need to do the fade, or a regular draw
drawBounds.round(realBounds);
realBounds.offset(-getScrollX(), -getScrollY());
boolean needToFade = realBounds.intersects(getTotalPaddingLeft(), getTotalPaddingTop(),
getWidth() - getTotalPaddingRight(), getHeight() - getTotalPaddingBottom());

if (needToFade) {
// Adjust and set the Shader Matrix
final Matrix shaderMatrix = matrix;
shaderMatrix.reset();
shaderMatrix.setScale(drawBounds.width(), 1f);
if (isRtl) {
shaderMatrix.postRotate(180f, drawBounds.width() / 2f, 0f);
}
shaderMatrix.postTranslate(drawBounds.left, drawBounds.top);
shader.setLocalMatrix(shaderMatrix);

// Save, and start drawing to an off-screen buffer
final int saveCount;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
saveCount = canvas.saveLayer(null, null);
} else {
saveCount = canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
}

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

// Draw the fade to the buffer, over the TextView content
canvas.drawRect(drawBounds, paint);

// Restore, and draw the buffer back to the Canvas
canvas.restoreToCount(saveCount);
} else {
// Regular draw
super.onDraw(canvas);
}
}
}

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

<com.example.app.FadingTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#e2f3eb"
android:textColor="#0b8043"
android:lineSpacingMultiplier="1.2"
android:text="@string/umang" />

screenshot


注意事项:

  • 淡入淡出长度的计算基于最后一行文本长度的常数分数,此处由 FADE_LENGTH_FACTOR 确定。这似乎与 Play Store 组件的基本方法相同,因为淡入淡出的绝对长度似乎随行长度而变化。 FADE_LENGTH_FACTOR 值可以根据需要进行更改。

  • FadingTextView 目前扩展了 AppCompatTextView,但如果您需要的话,它可以作为普通的 TextView 完美运行。我认为它也可以用作 MaterialTextView,尽管我还没有对其进行彻底的测试。

  • 这个例子主要针对比较普通的使用;即,作为一个简单的包装静态标签。虽然我已经尝试考虑并测试我能想到的每一个 TextView 设置,这可能会影响这一点——例如,复合可绘制对象、填充、可选文本、滚动、文本方向和对齐等——我不能保证我已经想到了一切。

关于android - 如何淡出 TextView 中最后一行的结尾?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49295526/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com