您的位置:

Android View绘制流程

一、安卓绘图流程

在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即可实现各种视图的绘制和显示。当然,对于一些对视图的自定义更多的应用,需要掌握更多的内容和技巧。