Невозможно расширить TextView для рисования текста с градиентом. Однако этого эффекта можно добиться, создав холст и рисуя на нем. Сначала нам нужно объявить наш элемент пользовательского интерфейса . В начале мы должны создать подкласс Layout . В этом случае мы будем использовать BoringLayout , который поддерживает текст только одной строкой.
Shader textShader=new LinearGradient(0, 0, 0, 20,
new int[]{bottom,top},
new float[]{0, 1}, TileMode.CLAMP);//Assumes bottom and top are colors defined above
textPaint.setTextSize(textSize);
textPaint.setShader(textShader);
BoringLayout.Metrics boringMetrics=BoringLayout.isBoring(text, textPaint);
boringLayout=new BoringLayout(text, textPaint, 0, Layout.Alignment.ALIGN_CENTER,
0.0f, 0.0f, boringMetrics, false);
Затем мы переопределяем onMeasure
и onDraw
:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
setMeasuredDimension((int) textPaint.measureText(text), (int) textPaint.getFontSpacing());
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
boringLayout.draw(canvas);
}
Наша реализация onDraw
на данный момент довольно ленива (она полностью игнорирует характеристики измерения !, но до тех пор, пока вы гарантируете, что представлению предоставлено достаточно места, все должно работать нормально.
Кроме того, можно было бы наследовать от Canvas
и переопределить метод onPaint
. Если это будет сделано, то, к сожалению, привязка к рисуемому тексту всегда будет внизу, поэтому мы должны добавить -textPaint.getFontMetricsInt().ascent()
к нашей координате y.