Android 视图绘画机制分析

原创 2013年12月03日 22:39:46
、在我们平时开发和面试中总会有问道View绘画流程,这个在平时开发中重写组件很重要,View绘图流程是核心在ViewRoot.java(2.3或ViewRootImpl(2.3以上)类的performTraversals()函数展开的,该函数做的执行过程可简单概况为:

                                                                                                   步骤其实为host.layout() 

        

                        图来之http://blog.csdn.net/qinjuning/article/details/7110211中,仅供学习参考。

二、下面我从以下四方面流程分析按onMesarue-》onFinishInflate-》onLayout-》onDraw过程。

  一:mesarue()过程

        主要作用:为整个View树计算实际的大小,即设置实际的高(对应属性:mMeasuredHeight)和宽(对应属性:

  mMeasureWidth),每个View的控件的实际宽高都是由父视图和本身视图决定的。 

     具体的调用链如下

          ViewRoot根对象地属性mView(其类型一般为ViewGroup类型)调用measure()方法去计算View树的大小,回调

View/ViewGroup对象的onMeasure()方法,该方法实现的功能如下:    

         1、设置本View视图的最终大小,该功能的实现通过调用setMeasuredDimension()方法去设置实际的高(对应属性:  

                mMeasuredHeight)和宽(对应属性:mMeasureWidth)   ;

         2 、如果该View对象是个ViewGroup类型,需要重写该onMeasure()方法,对其子视图进行遍历的measure()过程。

         3、  对每个子视图的measure()过程,是通过调用父类ViewGroup.java类里的measureChildWithMargins()方法去

          实现,该方法内部只是简单地调用了View对象的measure()方法。(由于measureChildWithMargins()方法只是一个过渡

          层更简单的做法是直接调用View对象的measure()方法)。

    1.1实例重写设置自身大小如下:

	@Override
	public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
		final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
		final int heightSize = MeasureSpec.getSize(高度值);//高度值你可以设根据实际开发传入
		setMeasuredDimension(widthSize, heightSize);
	}

 

二、 layout布局过程:

     主要作用 :自身视图通过mesarue 设置了大小,而可以通过onLayout设置子视图位置。

   具体的调用链如下:

       host.layout()开始View树的布局,继而回调给View/ViewGroup类中的layout()方法。具体流程如下

        1 、layout方法会设置该View视图位于父视图的坐标轴,即mLeft,mTop,mLeft,mBottom(调用setFrame()函数去实现)

  接下来回调onLayout()方法(如果该View是ViewGroup对象,需要实现该方法,对每个子视图进行布局) ;   

       2、如果该View是个ViewGroup类型,需要遍历每个子视图chiildView,调用该子视图的layout()方法去设置它的坐标值。

  2.1实例View子视图设置位置如下:

   

@Override
	protected void onLayout(boolean changed, int left, int top, int right,
			int bottom) {
		final View[] buttons = mButtons;
		final View parent = (View) getParent();// fill parent mode
		final int height = parent.getHeight();
		final int width = parent.getWidth();
		final int paddingLeft = 10;
	//	final int paddingLeft = mPaddingLeft;
		int buttonWidth;
		int buttonHeight;
		int widthInc;
		int heightInc;
		//mPaddingTop
		if (ROWS * mButtonHeight + (ROWS - 1) * 10< height) {
			//mPaddingLeft
			buttonWidth = (width - 10 * (COLUMNS - 1)) / COLUMNS;
			//mPaddingTop
			buttonHeight = (height - 10 * (ROWS - 1)) / ROWS;
			widthInc = width / COLUMNS;
			heightInc = height / ROWS;
			mWidth = width;
			mHeight = height;
		} else {
			buttonWidth = mButtonWidth;
			buttonHeight = mButtonHeight;
			widthInc = mWidthInc;
			heightInc = mHeightInc;
		}

		int i = 0;
		// The last row is bottom aligned.
		//int y = (bottom - top) - mHeight + mPaddingTop;
		int y = (bottom - top) - mHeight + 10;
		for (int row = 0; row < ROWS; row++) {
			int x = paddingLeft;
			for (int col = 0; col < COLUMNS && i < NUM_CHILDREN; col++) {
				View button = buttons[i];
				button.layout(x, y, x + buttonWidth, y + buttonHeight);
				/*
				 * if(button instanceof Button){ Button btn = (Button)button;
				 * int size = buttonHeight/6; btn.setTextSize(size > 32 ? 32 :
				 * size); btn.setGravity(Gravity.CENTER); }
				 */
				x += widthInc;
				i++;
			}
			y += heightInc;
		}
	}


    三 onDraw绘画流程详解:

     由ViewRoot对象的performTraversals()方法调用draw()方法发起绘制该View树,值得注意的是每次发起绘图时,并不

  会重新绘制每个View树的视图,而只会重新绘制那些“需要重绘”的视图,View类内部变量包含了一个标志位DRAWN,当该

视图需要重绘时,就会为该View添加该标志位,draw方法可以去重新父类,实现绘画动作。

        3.1实例View子视图设置位置如下:

	@Override
	protected void onDraw(Canvas cns) {
		// TODO Auto-generated method stub
		Drawable drawable = getDrawable();
		Log.i("ZYN", "--->onDraw");
		super.onDraw(cns);//调用系统用游标绘画
		
	}

  四 onFinishInflate绘画流程详解:

      在View绘画结束会回传View通过onFinishInflate通知,在实际开发中你可以在这里设置每个子View大小和数值。

     4.1实例View子视图设置位置如下:

   

	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();
		COLUMNS=3;
		if (mButtons == null) {
			NUM_CHILDREN = getChildCount();
			mButtons = new View[NUM_CHILDREN];
			//得到行数
			ROWS = NUM_CHILDREN / COLUMNS
					+ (NUM_CHILDREN % COLUMNS > 0 ? 1 : 0);
		}
		final View[] buttons = mButtons;
		for (int i = 0; i < NUM_CHILDREN; i++) {
			buttons[i] = getChildAt(i);
			// Measure the button to get initialized.
			buttons[i]
					.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
		}
		// Cache the measurements.
		final View child = buttons[0];
		mButtonWidth = child.getMeasuredWidth();
		mButtonHeight = child.getMeasuredHeight();
		mWidthInc = mButtonWidth + 10 + 10;
		mHeightInc = mButtonHeight + 10 + 10;
//		mWidthInc = mButtonWidth + mPaddingLeft + mPaddingRight;
//		mHeightInc = mButtonHeight + mPaddingTop + mPaddingBottom;
		mWidth = COLUMNS * mWidthInc;
		mHeight = ROWS * mHeightInc;
	}


 

    

浅分析android绘画机制

上篇文章探讨了android事件分发机制,这一篇简单的介绍一下,android的绘画机制。首先,先写一个类继承于LinearLayout,并且重新相应的方法。 然后在使用这个布局,看看日志的输出...

几行代码看懂android View的事件传递机制(视图逻辑)

安卓的视图事件传递机制。

Android视图架构及事件分发处理机制

1、在Android系统中,视图的结构是一种树形结构,这种树形结构称为View树或控件树。 2、Android中的触摸事件处理机制主要由dispatchTouchEvent、onIntercept-T...

Android性能优化之视图篇(渲染机制)

**本篇重点是——–如何解决过度绘制** 众所周知的Android系统每隔16ms重新绘制一次activity,也就是说你的app必须在16ms内完成屏幕刷新的所有逻辑操作,这样才能达到60帧/s。...

Android 动画机制 之 视图动画

视图动画使用比较简单!共有四种动画方式 AlphaAnimation 透明度动画 RotateAnimation 旋转动画 TranslateAnimation ...

Android组件学习笔记(简易绘画板)

自学Android中,根据一位前辈的代码进行学习,理解,在其基础上做了一些改进 功能简述:1,画图2.清空3.改变画笔大小4.全屏渲染5.改变颜色 源代码: package com.example.h...

Android绘画之边框渐淡的Button

先看效果图实现代码如下/** * Button with click-animation effect. */ public class ColorButton extends Button im...

Android 函数绘画思路 Y=sinX 绘制过程;

代码解决一切废话,内部注解详细: package com.example.administrator.demo.widget; import android.content.Context...

【Android】图形图像处理之"自定义绘画"

点击这里可以查看我所有关于图形图像处理的文章在Android应用中,Canvas和Paint是两个绘图的基本类,使用这两个类几乎可以完成所有的绘制工作。 Canvas:画布,2D图形系统最核心的一个...

【Android游戏开发之一】设置全屏以及绘画简单的图形

转载自【黑米GameDev街区】原文链接: http://www.himigame.com/android-game/263.html 这一章简单讲述些简单的Android-UI: 直...
  • yc1404
  • yc1404
  • 2013年02月27日 17:21
  • 206
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 视图绘画机制分析
举报原因:
原因补充:

(最多只允许输入30个字)