三 .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" />
时间: 2024-10-18 03:08:33