Android群英传笔记系列二view的绘制

Posted xiaofeiyang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android群英传笔记系列二view的绘制相关的知识,希望对你有一定的参考价值。

 .view的绘制
1.  使用方法:通过继承view并重写它的onDraw()方法来完成绘图。
2.  具体实现:
a.先定义一个Canvas对象,这个对象类似于一个花板,定义方法如下:Canvas canvas=new Canvas(bitmap);
b.我们可以看到在定义Canvas对象时,我们传入了一个bitmap对象,那么这个bitmap的作用是什么呢?其实bitmap的作用是存储所有绘制在Canvas上的像素信息。比如:
canvas.drawBitmap(bitmap1,0,0,null);
canvas.drawBitmap(bitmap2,0,0,null);
Canvas mCanvas=new Canvas(bitmap2);
mCanvas.drawXXX();
上面这段代码的含义是,将bitmap2,装载到另一个Canvas对象中,然后在其他地方使用Canvas对象对装载bitmap2的Canvas对象进行绘图。
c.实际上我们绘图,并不是直接绘制在onDraw()方法指定的那块布上,而是通过改变bitmap,然后让view重绘,从而显示改变之后的bitmap。
3.自定义view的常用函数:
onFinishInflate():从xml加载组件后回调
onSizeChanged():组件大小改变时回调
onMeasure():回调该方法来进行测量
onLayout():回调该方法来确定显示的位置
onTouchEvent();监听到触摸事件时回调
4.常见的实现自定义控件的方法:
a.  对现有控件进行扩展
b.  通过组合来实现新的控件
c.  重写view来实现全新的控件
5.对现有控件进行扩展:扩展textview,对textview加入多重颜色背景;
a.  定义一个类继承至TextView,并添加其构造函数:要注意的一点就是,添加构造函数时,一定要添加到含有Attributset参数的的构造函数,否则程序会报错,因为Attributset参数的作用是:外部通过它来获取到自定义view的属性。
public class DrawTextView extends TextView{
    public DrawTextView(Context context) {
        super(context); 
    }
    public DrawTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
}

b.定义两个画笔,并对画笔进行初始化内容:

private Paint mPaint1,mPaint2;
//初始化画笔内容:颜色和风格
mPaint1=new Paint();
mPaint2=new Paint();
mPaint1.setColor(getResources().getColor(R.color.colorPrimary));
mPaint1.setStyle(Paint.Style.FILL);
mPaint2.setColor(getResources().getColor(R.color.colorAccent));
mPaint2.setStyle(Paint.Style.FILL);

c.重写onDraw函数:这里要注意下save函数和restore函数之间的区别,前者是保存画布的状态,然后经过onDraw函数后,会对画布进行一些操作,比如旋转之类,这里是添加文字,而后者是对操作后的画布进行保存。

protected void onDraw(Canvas canvas) {
    //绘制内矩阵
    canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),mPaint1);
    //绘制外矩阵
    canvas.drawRect(10,10,getMeasuredWidth()-10,getMeasuredHeight()-10,mPaint2);
    //保存画布的状态
    canvas.save();
    //添加文字
    super.onDraw(canvas);
    //保存画布被操作后的状态
    canvas.restore();
}

d.在布局中引用自定义textview:

<main.view.com.drawmyview.DrawTextView
    android:layout_width="200dp"
    android:layout_height="50dp"
    android:textSize="20sp"
    android:gravity="center"
    android:text="@string/mytextview"/>

e.实现效果:

3.实现textview文字闪烁:

a.实现效果:

b.实现原理:使用Android中Paint对象的Shander渲染器,通过设置一个不断变化的LinearGradient,并使用带有该属性的Paint对象来绘制要显示的文字。

c.具体实现过程:

(1) 在onSizeChanged()方法中进行一些对象的初始化,并根据view的宽带设置一个LinearGradient渐变渲染器:

protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    if (mViewWidth==0){//一开始初始化为0了,所以会进入这个if判断语句
        mViewWidth=getMeasuredWidth();//获取到当前宽度
        if (mViewWidth>0){
            mPaint=getPaint();//获取当前绘制textview的Paint对象
            /*
            * 设置一个LinearGradient渐变器渲染器
            * 第一二个参数是设置渐变的起点,这里设置的是矩形的左上角为起点
            * 第三四个参数为设置渐变的终点,这里设置的是矩阵的右上角为终点
            * 第五个参数为一个int数组,表示渐变的颜色,这里选择的是蓝-白-蓝
            * 第六个参数为设置梯度颜色变化,设置方法为new float[]{0.25f,0.5f,0.75f},
            * 如果设置为空,表示颜色均匀分布,但一定要注意的是要保证颜色数组和位置数组大小一样
            * 第七个参数为平铺方式,CLMP为重复最后一个颜色至最后,其他的两个自己体验一下
            * */
            mLinearGradient=new LinearGradient(0,0,mViewWidth,0,new int[]{Color.BLUE,Color.WHITE,Color.BLUE}
                    ,new float[]{0.25f,0.5f,0.75f}, Shader.TileMode.CLAMP);
        //给paint对象添加渲染器
            mPaint.setShader(mLinearGradient);
            mGradientMatrix=new Matrix();
        }
    }

(2) 紧接着我们在onDraw()函数中,通过矩阵的方式来不断平移渐变效果,从而在绘制文字时,产生动态的闪动效果:

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);
        //延迟100ms
        postInvalidateDelayed(100);
    }
}

最后在xml布局文件中引用:

<main.view.com.drawmyview.MyTextView
    android:layout_marginTop="20dp"
    android:text="@string/textview2"
    android:textSize="30sp"
    android:layout_gravity="center"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

 

 

 

以上是关于Android群英传笔记系列二view的绘制的主要内容,如果未能解决你的问题,请参考以下文章

Android群英传笔记系列一view的介绍

Android群英传笔记——第五章:Android Scroll分析

Android群英传知识点回顾——第三章:Android控件架构与自定义控件详解

Android群英传神兵利器读书笔记——第三章:Android Studio奇技淫巧

Android view的测量及绘制

《Android群英传》---读书笔记7