根据这个
答案,我修改了您的代码。请尝试以下代码:
double angleInRadians = Math.toRadians(45);
double length = textView.getPaint().getTextSize();
double endX = Math.sin(angleInRadians) * length;
double endY = Math.cos(angleInRadians) * length;
Shader textShader = new LinearGradient(0, 0, endX, endY,
new int[]{context.getResources().getColor(R.color.color1), context.getResources().getColor(R.color.color2)},
new float[]{0, 1}, Shader.TileMode.CLAMP);
textView.getPaint().setShader(textShader);
更新:
我很惭愧地说,我的上面的回答是不正确的。这些答案(mayank1513 answer和Chaudhari Sachin answer)是相同的,它们很好,但它们有一些错误:
1. 它们对于大于90度的角度不正确。例如,如果你用180度测试它们,那么你将看不到任何渐变,因为这些解决方案使用(0,0)点作为旋转中心。
2. 如果你有一个TextView的宽度或高度比其文本宽度或高度更多或更少,那么渐变不会正确地呈现。例如,你可以通过一个具有match_parent
宽度和高度和居中Hello
文本或启用滚动小TextView和长文本来测试它。
我开发了新的解决方案。它首先计算文本范围,然后围绕该范围的中心旋转渐变线。
textView.post(new Runnable() {
@Override
public void run() {
final Rect textBound = new Rect(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE);
final Layout layout = textView.getLayout();
for(int i = 0; i < textView.getLineCount(); i++) {
float left = layout.getLineLeft(i);
float right = layout.getLineRight(i);
if(left < textBound.left) textBound.left = (int)left;
if(right > textBound.right) textBound.right = (int)right;
}
textBound.top = layout.getLineTop(0);
textBound.bottom = layout.getLineBottom(textView.getLineCount() - 1);
if(textView.getIncludeFontPadding()) {
Paint.FontMetrics fontMetrics = textView.getPaint().getFontMetrics();
textBound.top += (fontMetrics.ascent - fontMetrics.top);
textBound.bottom -= (fontMetrics.bottom - fontMetrics.descent);
}
double angleInRadians = Math.toRadians(45);
double r = Math.sqrt(Math.pow(textBound.bottom - textBound.top, 2) +
Math.pow(textBound.right - textBound.left, 2)) / 2;
float centerX = textBound.left + (textBound.right - textBound.left) / 2;
float centerY = textBound.top + (textBound.bottom - textBound.top) / 2;
float startX = (float)Math.max(textBound.left, Math.min(textBound.right, centerX - r * Math.cos(angleInRadians)));
float startY = (float)Math.min(textBound.bottom, Math.max(textBound.top, centerY - r * Math.sin(angleInRadians)));
float endX = (float)Math.max(textBound.left, Math.min(textBound.right, centerX + r * Math.cos(angleInRadians)));
float endY = (float)Math.min(textBound.bottom, Math.max(textBound.top, centerY + r * Math.sin(angleInRadians)));
Shader textShader = new LinearGradient(startX, startY, endX, endY,
new int[]{context.getResources().getColor(R.color.color1),
context.getResources().getColor(R.color.color2)},
new float[]{0, 1}, Shader.TileMode.CLAMP);
textView.setTextColor(Color.WHITE);
textView.getPaint().setShader(textShader);
}
});
new float[] {0, 1}
作为Positions
参数。你可以使用null来使它线性。根据官方文档: "float: 可以为空。颜色数组中每个对应颜色的相对位置 [0..1]。如果这是空的,那么颜色沿着渐变线均匀分布。此值可以为空。" - Mir Milad Hosseiny