自定义View并自定义其属性学习小Demo
2015-10-23 12:16
218 查看
最近在看徐老师的《Android群英传》,里面有一章是讲的如何自定义View,之前一直觉得自定义挺复杂的,感觉像座大山一直压在自己的Android之路上,看了书中讲解之后,发现原来一直神秘的自定义View也没那么神秘,下面就和我一起来通过一个简单的小Demo一起来体验一下吧。
1、首先我们重写View的onSizeChanged方法,在里面执行一些初始化的操作,比如为TextView的Paint画笔对象设置渲染对象等,代码如下:
2、重写onDraw方法,在里面实现动态的渐变效果,代码如下:
3、我们有时也需要自定义一些属性,使我们的控件用起来更加的人性化,这个其实也简单,首先在values目录下新建一个attrs.xml文件,然后在里面自定义一些自定义控件想要的属性:
4、设置好上面的属性列表之后,就可以在布局文件中使用上面的参数了,只不过要先加一个命名空间
5、现在万事具备,只欠东风了,我们还要在自定义View的构造器中,获取到上面xml布局中设置的这些属性值:
6、至此,整个一个简单的自定义View代码就实现了,下面我贴一下完整的代码供大家参考:
重写TextView实现一个简单的动态渐变效果的TextView
首先讲一下思路和知识准备,实现渐变需要使用到一个渲染对象LinearGradient,只有一个渲染对象还不行,因为这样知识一个静态的效果,要实现动态还需要一个矩阵位移对象Matrix。1、首先我们重写View的onSizeChanged方法,在里面执行一些初始化的操作,比如为TextView的Paint画笔对象设置渲染对象等,代码如下:
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // 初始化操作 if (mViewWidth == 0) { // 设置自定义textview的宽度值 mViewWidth = getMeasuredWidth(); if (mViewWidth > 0) { // 获取到TextView的paint对象 mPaint = getPaint(); // 设置自定义的线性渲染 // CLAMP重复最后一个颜色至最后 // MIRROR重复着色的图像水平或垂直方向已镜像方式填充会有翻转效果 // REPEAT重复着色的图像水平或垂直方向 mLinearGradient = new LinearGradient(0, 0, mViewWidth, 0, new int[]{colorOne, colorTwo, colorThree}, null, Shader.TileMode.CLAMP); // 为textview的paint设置渲染器 mPaint.setShader(mLinearGradient); // 初始化全局矩阵 mGradientMatrix = new Matrix(); } } }
2、重写onDraw方法,在里面实现动态的渐变效果,代码如下:
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mGradientMatrix != null) { // 每次执行一次,就将偏移增加一个值 mTranslate += mViewWidth / 5; Log.e("gu", "mTranslate==>" + mTranslate); // 如果偏移值大于了两倍的textview宽度,则将偏移值置为-mViewWidth if (mTranslate > 2 * mViewWidth) { mTranslate = -mViewWidth; } // 为矩阵设置偏移 mGradientMatrix.setTranslate(mTranslate, 0); // 为渲染器加上偏移矩阵 mLinearGradient.setLocalMatrix(mGradientMatrix); // 设置延迟重新提交绘制View postInvalidateDelayed(delayTime); } }
3、我们有时也需要自定义一些属性,使我们的控件用起来更加的人性化,这个其实也简单,首先在values目录下新建一个attrs.xml文件,然后在里面自定义一些自定义控件想要的属性:
<declare-styleable name="CustomTextViewTwo"> <attr name="shaperColorOne" format="color"></attr> <attr name="shaperColorTwo" format="color"></attr> <attr name="shaperColorThree" format="color"></attr> <attr name="delayTime" format="integer"></attr> </declare-styleable>
4、设置好上面的属性列表之后,就可以在布局文件中使用上面的参数了,只不过要先加一个命名空间
xmlns:app="http://schemas.android.com/apk/res-auto",这样编译器就可以找到我们自己定义的属性了:
<com.gu.customviewtest.CustomTextViewTwo android:layout_width="100dp" android:layout_height="50dp" android:gravity="center" android:text="我是测试的文字" app:delayTime="1000" app:shaperColorOne="#cc0e0e" app:shaperColorThree="#cc0e0e" app:shaperColorTwo="#f6d605" />
5、现在万事具备,只欠东风了,我们还要在自定义View的构造器中,获取到上面xml布局中设置的这些属性值:
private void init(Context context, AttributeSet attrs) { //获取到ta对象 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomTextViewTwo); //从ta对象中,获取到xml中对象属性配置值 colorOne = ta.getColor(R.styleable.CustomTextViewTwo_shaperColorOne, Color.BLACK); colorTwo = ta.getColor(R.styleable.CustomTextViewTwo_shaperColorTwo, Color.BLACK); colorThree = ta.getColor(R.styleable.CustomTextViewTwo_shaperColorThree, Color.BLACK); delayTime = ta.getInteger(R.styleable.CustomTextViewTwo_delayTime, 100); //TypeArray 对象用完以后必须得回收 ta.recycle(); }
6、至此,整个一个简单的自定义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.util.Log;
import android.widget.TextView;
/**
* Created by Nate on 2015/10/22.
*/
public class CustomTextViewTwo extends TextView {
private int mViewWidth = 0;
private Paint mPaint;
private LinearGradient mLinearGradient;
private Matrix mGradientMatrix;
private int mTranslate;
private int colorOne;
private int colorTwo;
private int colorThree;
private int delayTime;
/**
* 在java代码创建视图的时候被调用,如果是从xml填充的视图,就不会调用这个
*
* @param context
*/
public CustomTextViewTwo(Context context) {
super(context);
}
/**
* 这个是在xml创建但是没有指定style的时候被调用
*
* @param context
* @param attrs
*/
public CustomTextViewTwo(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
/**
* 这个是在xml创建,并且指定style的时候被调用
*
* @param context
* @param attrs
* @param defStyleAttr
*/
public CustomTextViewTwo(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) { //获取到ta对象 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CustomTextViewTwo); //从ta对象中,获取到xml中对象属性配置值 colorOne = ta.getColor(R.styleable.CustomTextViewTwo_shaperColorOne, Color.BLACK); colorTwo = ta.getColor(R.styleable.CustomTextViewTwo_shaperColorTwo, Color.BLACK); colorThree = ta.getColor(R.styleable.CustomTextViewTwo_shaperColorThree, Color.BLACK); delayTime = ta.getInteger(R.styleable.CustomTextViewTwo_delayTime, 100); //TypeArray 对象用完以后必须得回收 ta.recycle(); }
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // 初始化操作 if (mViewWidth == 0) { // 设置自定义textview的宽度值 mViewWidth = getMeasuredWidth(); if (mViewWidth > 0) { // 获取到TextView的paint对象 mPaint = getPaint(); // 设置自定义的线性渲染 // CLAMP重复最后一个颜色至最后 // MIRROR重复着色的图像水平或垂直方向已镜像方式填充会有翻转效果 // REPEAT重复着色的图像水平或垂直方向 mLinearGradient = new LinearGradient(0, 0, mViewWidth, 0, new int[]{colorOne, colorTwo, colorThree}, null, Shader.TileMode.CLAMP); // 为textview的paint设置渲染器 mPaint.setShader(mLinearGradient); // 初始化全局矩阵 mGradientMatrix = new Matrix(); } } }
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mGradientMatrix != null) { // 每次执行一次,就将偏移增加一个值 mTranslate += mViewWidth / 5; Log.e("gu", "mTranslate==>" + mTranslate); // 如果偏移值大于了两倍的textview宽度,则将偏移值置为-mViewWidth if (mTranslate > 2 * mViewWidth) { mTranslate = -mViewWidth; } // 为矩阵设置偏移 mGradientMatrix.setTranslate(mTranslate, 0); // 为渲染器加上偏移矩阵 mLinearGradient.setLocalMatrix(mGradientMatrix); // 设置延迟重新提交绘制View postInvalidateDelayed(delayTime); } }}
相关文章推荐
- jQuery技术交流资料
- nginx服务器配置
- poj2299(树状数组+离散化)
- PHP中的错误和异常处理
- 格鲁巴四大殊胜之Golang篇
- ALSA声卡驱动中的DAPM详解之一:kcontrol
- mysqldump中断的常见错误和解决措施
- objc_msgSend arm64 崩溃问题
- 初始化和清理
- Linux -- ls只显示目录
- Ubuntu Firefox installs Flashplayer
- oracle 第09章 参数文件
- java socket多线程
- Leetcode Next Permutation
- HDOJ 题目1264 Counting Squares(线段树+扫描线)
- Android-->FlowRadioGroup(流式布局RadioGroup, 自定义View的简单使用)
- spring第一课,beans配置(中)——自动装配
- 配置iptablesl时候遇到的一些问题
- 动画特效十四:手风琴效果
- nginx rewrite url