在Android开发中,TextView可以说是出镜率非常高的控件,除了常用的设置文字大小,文字颜色等基本属性,有时也需要一些特殊的效果,例如文字的闪烁效果。首先上效果图:
实现这一效果可以使用Paint对象的Shader渲染器,通过给Paint对象设置一个不断变化的LinearGradient来绘制要显示的字符串。
布局文件如下:
<com.example.tom.designviewdemo.flicker.FlickerTextView
android:id="@+id/flicker_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/bicker_text"
android:textSize="@dimen/bicker_text_size"/>
FlickerTextView 的代码如下:
package com.example.tom.designviewdemo.flicker;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* Created by tom on 17/6/27.
*/
public class FlickerTextView extends TextView {
private int mViewWidth = 0;
private Paint mPaint;
private LinearGradient mLinearGradient;
private Matrix mGradientMatrix;
private int mTranslate = 0;
public FlickerTextView(Context context) {
super(context);
}
public FlickerTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FlickerTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public FlickerTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if(mViewWidth == 0){
mViewWidth = getMeasuredWidth();
if(mViewWidth > 0){
mPaint = getPaint();
mLinearGradient = new LinearGradient(0,0,mViewWidth,0,new int[]{Color.BLUE,0xffffff,Color.BLUE},null, Shader.TileMode.CLAMP);
mPaint.setShader(mLinearGradient);
mGradientMatrix = new Matrix();
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mGradientMatrix != null){
mTranslate += mViewWidth/5;
if (mTranslate > 2 * mViewWidth){
mTranslate = - mViewWidth;
}
mGradientMatrix.setTranslate(mTranslate, 0);
mLinearGradient.setLocalMatrix(mGradientMatrix);
postInvalidateDelayed(100);
}
}
}
对主要代码进行简要分析。
第50行 LinearGradient的说明如下:
Shader.TileMode.CLAMP
,主要有3种,CALMP
:如果渲染器超出原始边界范围,会复制范围内边缘染色;REPEAT
:横向和纵向的重复渲染器图片,平铺;MIRROR
:横向和纵向的重复渲染器图片,以镜像方式平铺。 第61行 每次移动屏幕宽度的1/5
/** Create a shader that draws a linear gradient along a line.
@param x0 The x-coordinate for the start of the gradient line
@param y0 The y-coordinate for the start of the gradient line
@param x1 The x-coordinate for the end of the gradient line
@param y1 The y-coordinate for the end of the gradient line
@param colors The colors to be distributed along the gradient line
@param positions May be null. The relative positions [0..1] of
each corresponding color in the colors array. If this is null,
the the colors are distributed evenly along the gradient line.
@param tile The Shader tiling mode
*/
public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],
TileMode tile) {
if (colors.length < 2) {
throw new IllegalArgumentException("needs >= 2 number of colors");
}
if (positions != null && colors.length != positions.length) {
throw new IllegalArgumentException("color and position arrays must be of equal length");
}
mType = TYPE_COLORS_AND_POSITIONS;
mX0 = x0;
mY0 = y0;
mX1 = x1;
mY1 = y1;
mColors = colors;
mPositions = positions;
mTileMode = tile;
init(nativeCreate1(x0, y0, x1, y1, colors, positions, tile.nativeInt));
}
最后附上完整项目代码(Android Studio环境下)
点我下载