最近买了本Android群英传,看到个自定义TextView的例子,实现了渐变效果,自己在此基础上加了点功能,让其可以在xml中配置其渐变的颜色等。
效果如下
简单说下我实现过程。
首先,我们新建个工程,因为公司电脑太古老,Android studio跑不动,还是用eclipse。
新建空白Android工程,MainActivity不需要太多功能,就保留以下代码就够了
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
然后新建类GradualTextView,继承TextView,代码如下:
package cn.view;
import android.content.Context;
import android.content.res.TypedArray;
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;
public class GradualTextView extends TextView
{
private int mViewWidth;
private Paint mPaint;
private LinearGradient mLinearGradient;
private Matrix mGradientMatrix;
private int mTranslate;
private int firstColor,nextColor;
private int delay;
public GradualTextView(Context context, AttributeSet attrs) {
super(context, attrs);
//获取xml中的属性值
TypedArray arry=context.obtainStyledAttributes(attrs, R.styleable.GradualTextView);
firstColor=arry.getInt(R.styleable.GradualTextView_firstColor, Color.BLUE);//渐变的第一个颜色,默认蓝色
nextColor=arry.getInt(R.styleable.GradualTextView_nextColor,Color.RED);//渐变的第二个颜色,默认红色
delay=arry.getInt(R.styleable.GradualTextView_delay, 100);//渐变的延迟,默认100ms
// TODO 自动生成的构造函数存根
}
/*
首先在onSizeChanged()中进行初始化.
mViewWidth:Textveiw的宽度
mLinearGradient:不断变化的LinearGradient;
mGradientMatrix:用于产生变化的矩阵;
mPaint:TextView的paint对象
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO 自动生成的方法存根
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[]{firstColor,nextColor,firstColor},null,Shader.TileMode.CLAMP);
mPaint.setShader(mLinearGradient);
mGradientMatrix=new Matrix();
}
}
}
@Override
protected void onDraw(Canvas canvas) {
// TODO 自动生成的方法存根
super.onDraw(canvas);
if(mGradientMatrix!=null){
mTranslate+=mViewWidth/5;
if(mTranslate>2*mViewWidth)
{
mTranslate=-mViewWidth;
}
mGradientMatrix.setTranslate(mTranslate, 0);
mLinearGradient.setLocalMatrix(mGradientMatrix);
postInvalidateDelayed(delay);
}
}
}
为了能在xml中设置自定义view的属性,我们需要创建自己命名空间
在values文件夹里新建attrs.xml
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<declare-styleable name="GradualTextView">
<attr name="firstColor" format="integer"/>
<attr name="nextColor" format="integer"/>
<attr name="delay" format="integer"></attr>
</declare-styleable>
</resources>
然后在布局文件activity_main.xml中添加 xmlns:custom="http://schemas.android.com/apk/res-auto"
网上找的其他教程都说是 xmlns:custom="http://schemas.android.com/apk/包名",我这样写的刚开始能行,后来莫名其妙报错了,让改成上面的res-auto,奇怪了,有明白的给解释下。
下面是全部布局代码
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<cn.view.GradualTextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="My TextView Test"
custom:firstColor="0xffffffff"
custom:nextColor="0xff0000ff"
/>
</LinearLayout>
注意,自定义的属性不能用android:了,前面xmlns:custom,所以你的命名空间就是custom:
这里没有配置延迟属性,默认就是100ms。可以用custom:delay="200"设置为200ms
以上,自定义的TextView就完成了,可以运行了。
新手,轻拍砖
源码下载地址:源码下载