Android View绘制原理的初步理解
Posted wjinhhua
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android View绘制原理的初步理解相关的知识,希望对你有一定的参考价值。
在理解View绘制原理之前,我们先要明白View是什么。
android中是这样理解View这个类的
* This class represents the basic building block for user interface components. A View
* occupies a rectangular area on the screen and is responsible for drawing and
* event handling. View is the base class for <em>widgets</em>, which are
* used to create interactive UI components (buttons, text fields, etc.). The
* @link android.view.ViewGroup subclass is the base class for <em>layouts</em>, which
* are invisible containers that hold other Views (or other ViewGroups) and define
* their layout properties.
大致意思是(翻译可能不标准,大家相互理解):View这个类代表了用户界面组件的基本构建块。一个视图在屏幕上占据一个矩形区域,并负责绘图和事件处理。视图是窗口小部件的基类,它是用于创建交互式的用户界面组件(按钮,文本等)。这类布局的基类,它是看不见的容器持有其他Views(或其他viewgroup)和定义他们的layout的属性。
其次为什么要理解View的绘制原理?个人认为只有理解View的绘制原理,才能学会如何去自定义一个View。我们知道开发中需要用到很多组件,很多时候android给出的组建并不能满足我们的开发需求,于是我们开始组合组件来使用,然而,发现有些特定的需求还是得不到满足,于是自定义View成为解决的首要期望。
接下来我上个特别简单效果,给TextView加个边框
需要说明的是,这个例子没什么实际意义,只是一种假设
看一下代码
public class MyTextView extends TextView
protected Paint mPaint = new Paint();
public MyTextView(Context context, AttributeSet attrs, int defStyle)
super(context, attrs, defStyle);
public MyTextView(Context context, AttributeSet attrs)
super(context, attrs);
public MyTextView(Context context)
super(context);
@Override
protected void onDraw(Canvas canvas)
canvas.save();
mPaint.setColor(Color.RED);
//文本
String text = getText().toString();
//文本宽度
int textWidth = (int) mPaint.measureText(text);
//文本高度
int textHeight = (int) (mPaint.descent() - mPaint.ascent());
//drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
//绘制矩形的上边
canvas.drawLine(0, 0, textWidth, 0, mPaint);
//绘制矩形的左边
canvas.drawLine(0, 0, 0, textHeight, mPaint);
//绘制矩形的下边
canvas.drawLine(0, textHeight, textWidth, textHeight, mPaint);
//绘制矩形的右边
canvas.drawLine(textWidth, 0, textWidth, textHeight, mPaint);
mPaint.setColor(Color.BLACK);
//文本开始的高,相当于baseLine
int y= textHeight+(int)(mPaint.descent() + mPaint.ascent()/2);
//绘制文本
canvas.drawText(text, 0, baseLine, mPaint);
//保存绘制的状态,一定不能忘记
canvas.restore();
xml引用
<com.example.testview.MyTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
说了那么多,好像没提到View的绘制原理,其实已经说了,当然,并没有着重去说,接下来我谈谈自己的理解:
View的绘制主要是三部曲:
onMeasure:测量过程,计算视图的大小,通过setMeasuredDimension保存计算结果。
onLayout:保存位置
onDraw:绘制过程,可以绘制背景,视图本身等
开发中,我们必须去实现onMeasure,onDraw这两个方法。可能有人会问刚刚的MyTextView只实现了onDraw方法呀,额,貌似是的。但是,你要看清楚,MyTextView继承的是View的子类TextView,而不是直接继承View,TextView已经实现onMeasure方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
...
setMeasuredDimension(width, height);
最后我认为还需要理解的有MeasureSpec和Canvas (这个类大家应该都掌握)这两个类
MeasureSpec这个类定义了有三种测量模式,EXACTLY(精确),AT_MOST(可获取最大尺寸),UNSPECIFIED(不限制)。这个类在onMeasure中使用。
在面试中我们经常遇到这个问题,我们可以说一下什么是View,然后着重讲一下View绘制的过程,开发中自己如何完成自定View的,再来个总结,这样面试官应该觉得至少自己掌握自定义View。我觉得照自己理解的去说给面试官听就好。。关于View的绘制原理,以后我会剖析源码,有时间再更新。最后,有问题的地方还请大家指出。
以上是关于Android View绘制原理的初步理解的主要内容,如果未能解决你的问题,请参考以下文章