本文章翻译于:Styling Android
- 创建一个填充有渐变的文本实际上是很简单的,虽然它不是很明显地改变文本颜色。诀窍是使用着色器,或者更具体地说是用LinearGradient类为我们工作。
Shader myShader = new LinearGradient(
0, 0, 0, 100,
Color.WHITE, Color.BLACK,
Shader.TileMode.CLAMP );
textview.getPaint().setShader( myShader );
- 构造函数要传入7个参数,这是一个复杂的形式,但是允许多个颜色的定义,第一个到四个参数代表开始的×,y和结束的x,y的直线沿该线进行梯度绘制,接下来的2个参数代表渐变的开始和结束的颜色,最后的参数决定了在前四个参数中定义的矩形的区域中如何被绘制。
- 虽然这是可以工作的,但是缺点是梯度需要的尺寸需要TextView的大小分离,所以我们需要渐变的尺寸来匹配我们的TextView。
- 这时我们需要继承TextView,重写onDraw方法来创建LinearGradient匹配每个控制绘制时间的TextView的尺寸控制。然而这是效率低下的,因为意味着在onDraw的过程中每次实例化Shader对象,实例化对象是一个相当消耗资源的,应该避免在OnDraw方法中。
- 所以,如果我们不在OnDraw中做,那我们应该怎么做呢?答案很明显,当我们想到我们经常需要创建一个新的渐变:只有当TextView大小变化的时候。因此,要做到这一点的最有效的地方其实是在onLayout:
public class GradientTextView extends TextView
{
public GradientTextView( Context context )
{
super( context, null, -1 );
}
public GradientTextView( Context context,
AttributeSet attrs )
{
super( context, attrs, -1 );
}
public GradientTextView( Context context,
AttributeSet attrs, int defStyle )
{
super( context, attrs, defStyle );
}
@Override
protected void onLayout( boolean changed,
int left, int top, int right, int bottom )
{
super.onLayout( changed, left, top, right, bottom );
if(changed)
{
getPaint().setShader( new LinearGradient(
0, 0, 0, getHeight(),
Color.WHITE, Color.BLACK,
Shader.TileMode.CLAMP ) );
}
}
}
这种配置可以用于应用不同种类的梯度(LinearGradient,RadialGradient, SweepGradient),用位图填充文本(BitmapShader),甚至结合着色器(ComposeShader).甚至可以创建自己的自定义Shader。
源码