1、
public class

View

extends Object
implements Drawable.Callback KeyEvent.Callback AccessibilityEventSource

java.lang.Object
   ↳ android.view.View

Class Overview

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 forwidgets, which are used to create interactive UI components (buttons, text fields, etc.).

public abstract class
View是Android中所有控件的基类,Button/TextView/RelativeLayout/ListView等,其共同基类都是View。View是界面层的控件的一种抽象,待变一个控件。

ViewGroup

extends View
implements ViewManager ViewParent
java.lang.Object
   ↳ android.view.View
     ↳ android.view.ViewGroup

Class Overview

A ViewGroup is a special view that can contain other views (called children.) The view group is the base class for layouts and views containers.

ViewGroup内部包含一组View,ViewGroup也继承自View,这就说明View本身就可以使单个控件或多个控件组成的一组控件。

UI界面架构图:

每个Activity都包含一个Window对象,Window对象通常由PhoneWindow来实现。PhoneWindow将一个DecorWindow设置为整个窗口的根View。DecView里有所有View的监听事件,通过WindowManagerService进行接收,并通过Activity对象回调相应的onClickListener。显示界面上,将屏幕分为两部分,分别为TitleView和ContentView。ContentView是一个ID为content的FrameLayout,布局文件activity_main.xml就是设置在这样一个FrameLayout中。

2、

View的位置参数:

View根据上图得到View的宽高和坐标(相对于ViewGroup,而不是原点)的关系:

width = right - left;

height = bottom - top;

获取这几个参数的方法如下:

mLeft = getLeft();
mRight = getRight();
mTop = getTop();
mBottom = getBottpm();

Android3.0开始View增加了几个参数:x,y,translationX,translationY,其中x,y是View左上角的坐标,translationX,translationY是View左上角相对于父容器的偏移量:

x = left + translationX;

y = top + translationY;

需要注意:View在平移过程中,top/left表示的是原始左上角的位置信息,其值在移动期间不会发生改变,变化的是x,y,translationX,translationY.

3、View的三大流程(measure,layout,draw)之View的测量

View的绘制流程从ViewRoot的performTraversals方法开始,ViewRoot对应于ViewRootImpl类,是连接WindowManager和DecorView的纽带,View的三大流程均是通过ViewRoot来完成。在ActivityThread中,当Activity对象被创建完毕后,会将DecorView添加到Window中,同时会创建ViewRootImpl对象,并将ViewRootImpl对象与DecorView相关联:

root = new ViewRootImpl(view.getContext(),display);
root.setView(view,wparams,panelParentView);

View的绘制流程从ViewRoot的performTraversals方法开始,经过measure,layout,draw三个过程将一个View绘制出来。

performTraversals会依次调用performMeasure,performLayout,performDraw三个方法,分别完成顶级View的measure,layout,draw三大流程,其中performMeasure中会调用measure方法,在measure方法中又调用onMeasure方法,在inMeasure方法中会对所有子元素进行measure过程,此时measure流程就从父元素传到子元素了,这样完成了一次measure过程。接着子元素会重复父容器的measure过程,如此反复完成整个View树的遍历。performLayout与performDraw与之类似,不同的是performDraw的传递过程是在draw方法中通过dispatchDraw来实现。

测量过程在onMeasure()方法中进行。

Android提供了一个功能强大的类--MeasureSpec类。

public static class

View.MeasureSpec

extends Object

java.lang.Object
   ↳ android.view.View.MeasureSpec
Summary: Constants |Ctors | Methods | Inherited Methods | [Expand All]
Added in API level 1
public static class

View.MeasureSpec

extends Object

java.lang.Object
   ↳ android.view.View.MeasureSpec

Class Overview

A MeasureSpec encapsulates the layout requirements passed from parent to child. Each MeasureSpec represents a requirement for either the width or the height. A MeasureSpec is comprised of a size and a mode. There are three possible modes:

UNSPECIFIED
The parent has not imposed any constraint on the child. It can be whatever size it wants.
EXACTLY
The parent has determined an exact size for the child. The child is going to be given those bounds regardless of how big it wants to be.
AT_MOST
The child can be as large as it wants up to the specified size.

MeasureSpec是一个32位的int值,高2位为测量模式(SpecMode),低30位是测量大小(SpecSize).

View默认的onMeasure()方法只支持EXACTLY模式,因此如果让自定义View支持wrap_content属性,就必须重写onMeasure()方法来指定wrap_content大小(进一步说明,由源码得出,wrap_content下的SpecMode是AT_MOST,此时的specSize是parentSize,即如果不指定wrap_content,在布局中使用wrap_content就相当于使用match_parent).

解决方法:

protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec){super.onMeasure(widthMeasureSpec, heightMeasureSpec);int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);if(widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){setMeasureDimension(mWidth,mHeight);}else if(widthSpecMode == MeasureSpec.AT_MOST){setMeasureDimension(mWidth,heightSpecSize);}else if(heightSpecMode == MeasureSpec.AT_MOST){setMeasureDimension(widthSoecSize,mHeight)}
}

在上面代码中指定View的默认宽高(mWidth/mHeight),并在wrap_content时设置此宽高。
Demo:

MeasureView.java

package sunny.example.ahthreeviewmeasure;import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;public class MeasureView extends View{public MeasureView(Context context) {super(context);// TODO Auto-generated constructor stub}public MeasureView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}public MeasureView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stub}@Overrideprotected void onMeasure(int widthMeasureSpec,int heightMeasureSpec){super.onMeasure(widthMeasureSpec, heightMeasureSpec);int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);if(widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST){setMeasuredDimension(400,400);//指定宽高}else if(widthSpecMode == MeasureSpec.AT_MOST){setMeasuredDimension(400,heightSpecSize);}else if(heightSpecMode == MeasureSpec.AT_MOST){setMeasuredDimension(widthSpecSize,400);}}}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="sunny.example.ahthreeviewmeasure.MainActivity" ><sunny.example.ahthreeviewmeasure.MeasureViewandroid:id="@+id/measureView"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="#09acda" /></RelativeLayout>

MainActivity.java

package sunny.example.ahthreeviewmeasure;import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;public class MainActivity extends ActionBarActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//MeasureView mView = (MeasureView)findViewById(R.id.measureView);}}

View的三大流程之View的测量相关推荐

  1. Android自定义View之实现流式布局

    Android自定义View之实现流式布局 运行效果 流式布局 把子控件从左到右摆放,如果一行放不下,自动放到下一行 自定义布局流程 1. 自定义属性:声明,设置,解析获取自定义值 在attr.xml ...

  2. Android View的绘制流程(1) -- 测量onMeasure

    鉴于是首篇讲解自定义view流程,之前也在网上搜了一些博主的博客看了看,都是大同小异,今天抽时间自己总结一下,分享一下自己的感悟,也算是一篇笔记. (本篇为开头篇,稍微讲述一下有关的东西) View的 ...

  3. Android自定义View系列之详解View的绘制流程

    目录 一.开场白 二.View的绘制流程 2.1测量的过程 2.2布局的过程 2.3绘制的过程 一.开场白 开讲之前我们先预设一种自定义ViewGroup的场景:我们知道LinearLayout.Fr ...

  4. 源码详解Android 9.0(P) 系统启动流程之SystemServer

    源码详解Android 9.0(P) 系统启动流程目录: 源码详解Android 9.0(P)系统启动流程之init进程(第一阶段) 源码详解Android 9.0(P)系统启动流程之init进程(第 ...

  5. View 体系详解:View 的工作流程

    1.View 树的加载流程 当我们调用 startActivity() 方法的时候,会调用到 ActivityThread 中的 performLaunchActivity() 获取一个 Activi ...

  6. android 自定义view 动画效果,Android自定义view实现阻尼效果的加载动画

    效果: 需要知识: 1. 二次贝塞尔曲线 2. 动画知识 3. 基础自定义view知识 先来解释下什么叫阻尼运动 阻尼振动是指,由于振动系统受到摩擦和介质阻力或其他能耗而使振幅随时间逐渐衰减的振动,又 ...

  7. Android自定义View之(一)View绘制流程详解——向源码要答案

    前言 View作为整个app的颜值担当,在Android体系中占有重要的地位.深入理解Android View的绘制流程,对正确使用View来构建赏心悦目的外观,以及用自定义View来设计理想中的酷炫 ...

  8. activiti自己定义流程之Spring整合activiti-modeler5.16实例(四):部署流程定义

    注:(1)环境搭建:activiti自己定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建         (2)创建流程模型:activiti自己定义流程之Spr ...

  9. 什么是数据库视图(view),视图(view)优缺点是什么?

    什么是数据库视图(view),视图(view)优缺点是什么? 什么是数据库视图(view)? 在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表. 视图包含行和列,就像一个真实的表.视图中的 ...

最新文章

  1. axios请求接口http_Vue实战038:api接口模块化统一管理
  2. boost::range_mutable_iterator相关的测试程序
  3. python paramiko sftp_Python学习—paramiko模块实现简单的ssh与sftp
  4. 用busybox制作文件系统
  5. 北京54、西安80、CGCS2000、WGS84坐标系及区别
  6. Android HttpURLConnection 获取下载文件大小
  7. excel科学计数法还原成字符串方法
  8. java导入excel数据为树形处理
  9. 【实战】在qgis上查看街景照片( go2streetview谷歌街景、go2mapillary)
  10. CryEngine3 调试Shader方法
  11. mysql 语言 总结
  12. 给未来写封信app服务器维护中,‎App Store 上的“给未来写封信”
  13. 这三种人不适合“裸辞”!
  14. CCleaner如何注册激活
  15. WebStorm 最新激活码 license server
  16. linux下安装realplayer
  17. 日常水文章之rk3188 5.0最简单的视频图片混播
  18. 苹果手机php怎么更新,Apple Watch固件系统怎么更新升级?
  19. Google Chrome谷歌浏览器安装最新版Elasticsearch插件 图文教程 【一看就懂】
  20. 利用FFmpeg制作视频序列

热门文章

  1. RabbitMQ:计划邮件传递
  2. delphi查看源码版本_[Mybatis]-IDEA导入Mybatis源码
  3. 程序代码移植和烧录需要注意什么_购买建站模板需要注意什么问题
  4. c语言小游戏 精简_一个简易的贪吃蛇小游戏C语言源码
  5. C++ 11 深度学习(七)位运算常见操作
  6. 学计算机编程200字感想,计算机学习心得体会
  7. linux中多进程调试,linux下用gdb调试多进程
  8. 工业交换机和工控交换机有什么区别?
  9. 【渝粤教育】国家开放大学2018年秋季 8038-22T实用管理基础 参考试题
  10. 21秋期末考试管理学基础10241k2