一、安卓绘图流程
在Android平台上,图形的渲染和显示过程是非常复杂的。主要包括以下几个处理步骤:
1、将显示内容从应用程序发送到系统框架 ,
2、把图形数据传递到OpenGL ES图形引擎去处理,
3、OpenGL ES返回一组最终的像素值,此时保存在图像缓冲区里
4、Android系统把这些像素复制到显示缓存区,完成最终的显示操作。
整个过程除了第1个步骤,都是通过系统内部多个进程进行的,因此这个过程实际上并不需要开发人员额外关心。
二、Android View绘制流程
View是Android应用程序的界面元素,任何绘制单元在屏幕上的显示都必须通过它才能实现。它在Android的绘制流程中是非常重要的一个环节。以下是Android View绘制流程的详细介绍:
1、构建视图层次
视图层次是指View的树形结构,由一个或多个View和 ViewGroup组成。当应用程序启动时,Android运行时系统会创建一个视图层次,即Activity / Fragment 中的setContentView()中指定的布局。在Android中视图的层次结构可以通过findViewById方法获取。
View view = findViewById(R.id.view_id);
2、测量过程
View被绘制之前,需要先测量出它的尺寸和大小。在测量过程中,系统会要求每一个View通过onMeasure()来计算自己的宽度和高度,该方法在View对象中实现,是View类的抽象方法之一。在每次事件分发的开始时,会自动触发View的测量过程。
举个例子,我们在Activity中创建一个TextView,然后通过日志来输出它的宽度和高度:
TextView textView = findViewById(R.id.textview_id); int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); textView.measure(widthMeasureSpec, heightMeasureSpec); Log.d("TAG", "TextView width: " + textView.getMeasuredWidth() + " height: " + textView.getMeasuredHeight());
3、布局过程
布局过程是指确定View在视图层次中的位置和大小。在这个过程中,会通过onLayout()方法确定View的四个顶点坐标,即left、top、right、bottom。如果是ViewGroup,会在这个方法中对自己的子View进行布局。
下面是一个简单的自定义ViewGroup的例子,自定义ViewGroup通过LayoutParams添加子View,重写onLayout()方法对子View进行布局。
public class CustomLayout extends ViewGroup { public CustomLayout(Context context) { this(context, null); } public CustomLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); setMeasuredDimension(width, height); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final int count = getChildCount(); int curWidth, curHeight, curLeft, curTop, maxHeight; final int childLeft = this.getPaddingLeft(); final int childTop = this.getPaddingTop(); maxHeight = 0; curLeft = childLeft; curTop = childTop; for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (child.getVisibility() == View.GONE) return; curWidth = child.getMeasuredWidth(); curHeight = child.getMeasuredHeight(); if (curLeft + curWidth >= r) { curLeft = childLeft; curTop += maxHeight; maxHeight = 0; } child.layout(curLeft, curTop, curLeft + curWidth, curTop + curHeight); if (maxHeight < curHeight) maxHeight = curHeight; curLeft += curWidth; } } }
4、绘制过程
绘制过程是指在View的结构确定后,将View及其子View绘制到屏幕上的机制。在这个过程中,会通过onDraw()方法,将View显示到屏幕上。最后会把所有View的绘制结果合并,并复制到Frame Buffer中,通过Surface给显示屏幕显示。
下面是一个简单的自定义View的例子,通过onDraw()方法绘制一个矩形和圆形:
public class CustomView extends View { private Paint mPaint = new Paint(); private int mWidth; private int mHeight; public CustomView(Context context) { this(context, null); } public CustomView(Context context, AttributeSet attrs) { super(context, attrs); mPaint.setColor(Color.BLACK); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(4); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawRect(mWidth / 4, mHeight / 4, mWidth * 3 / 4, mHeight * 3 / 4, mPaint); canvas.drawCircle(mWidth / 2, mHeight / 2, mWidth / 4, mPaint); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mWidth = MeasureSpec.getSize(widthMeasureSpec); mHeight = MeasureSpec.getSize(heightMeasureSpec); } }
三、结论
因为Android平台的绘制和显示过程是非常复杂而且固定的。所以很多开发人员不需要了解细节,只需要知道Android提供的一系列API即可实现各种视图的绘制和显示。当然,对于一些对视图的自定义更多的应用,需要掌握更多的内容和技巧。