Android View绘制原理的初步理解

来源:互联网 发布:淘宝上的自行车怎么样 编辑:程序博客网 时间:2024/04/25 18:41

在理解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的绘制原理,以后我会剖析源码,有时间再更新。最后,有问题的地方还请大家指出。

0 0
原创粉丝点击