前言:

  自定义控件的三大方法:

测量: onMeasure():  测量自己的大小,为正式布局提供建议
布局: onLayout(): 使用layout()函数对所有子控件布局
绘制: onDraw(): 根据布局的位置绘图

onDraw() 里面是绘制的操作,可以看下其他的文章,下面来了解 onMeasure()和onLayout()方法。

一、onMeasure()、测量

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  

参数即父类传过来的两个宽高的"建议值",即把当前view的高设置为:heightMeasureSpec ;宽设置为:widthMeasureSpec

这个参数不是简单的整数类型,而是2位整数(模式类型)和30位整数(实际数值) 的组合

其中模式分为三种:

①、UNSPECIFIED(未指定),父元素部队自元素施加任何束缚,子元素可以得到任意想要的大小;UNSPECIFIED=00000000000000000000000000000000

②、EXACTLY(完全),父元素决定自元素的确切大小,子元素将被限定在给定的边界里而忽略它本身大小;EXACTLY =01000000000000000000000000000000
③、AT_MOST(至多),子元素至多达到指定大小的值。 他们对应的二进制值分别是: AT_MOST =10000000000000000000000000000000 

最前面两位代表模式,分别对应十进制的0,1,2;

获取模式int值 和 获取数值int值的方法:

  1. int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
  2. int measureHeight = MeasureSpec.getSize(heightMeasureSpec);
  3. int measureWidthMode = MeasureSpec.getMode(widthMeasureSpec);
  4. int measureHeightMode = MeasureSpec.getMode(heightMeasureSpec);

模式的值有:

MeasureSpec.AT_MOST       = 2
MeasureSpec.EXACTLY = 1
MeasureSpec.UNSPECIFIED = 0

上面我们知道了 onMeasure(int widthMeasureSpec, int heightMeasureSpec) 方法参数的意义

下面了解参数对应的三个模式分别对应的意义:

每一个模式都对应的xml布局中的一个值

wrap_content   --- MeasureSpec.AT_MOST
match_parent --- MeasureSpec.EXACTLY
具体值 --- MeasureSpec.UNSPECIFIED

注意:当模式是MeasureSpec.AT_MOST时,即wrap_content时,需要将大小设置一个数值。

二、onLayout() 、 布局

首先先了解几个需要用到的方法:

  (1)、

      这个方法和onMeasure()方法类似。其实这个方法的作用就是 设置当前View的宽高。

  (2)、

      这个方法就和方法类似了,不过少了第一个参数boolean changed

      这个方法的目的是用于当前ViewGroup中的子控件的布局

 

  再看方法,只要是继承ViewGroup的类都必须要重写该方法,来实现该控件内部子控件的布局情况。

  我们写一个自定义类继承ViewGroup实现Linearlayout垂直排列的效果看下:

  public class XViewGroup extends ViewGroup{
public XViewGroup(Context context) {
super(context);
}
public XViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
}
public XViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int measureWidth = MeasureSpec.getSize(widthMeasureSpec);
int measureHeight = MeasureSpec.getSize(heightMeasureSpec);
int measureWidthMode = MeasureSpec.getMode(widthMeasureSpec);
int measureHeightMode = MeasureSpec.getMode(heightMeasureSpec);
     
      
     // 计算所有子控件需要用到的宽高
int height = ; //记录根容器的高度
int width = ; //记录根容器的宽度
int count = getChildCount(); //记录容器内的子控件个数
for (int i=;i<count;i++) {
//测量子控件
View child = getChildAt(i);
measureChild(child, widthMeasureSpec, heightMeasureSpec);
//获得子控件的高度和宽度
int childHeight = child.getMeasuredHeight();
int childWidth = child.getMeasuredWidth();
//得到最大宽度,并且累加高度
height += childHeight;
width = Math.max(childWidth, width);
}
     // 设置当前View的宽高
setMeasuredDimension((measureWidthMode == MeasureSpec.EXACTLY) ? measureWidth: width, (measureHeightMode == MeasureSpec.EXACTLY) ? measureHeight: height);
} @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int top = ;
int count = getChildCount();
for (int i=;i<count;i++) {
View child = getChildAt(i);
int childHeight = child.getMeasuredHeight();
int childWidth = child.getMeasuredWidth();
//该子控件在父容器的位置 , 高度是之前所有子控件的高度和开始 ,从上往下排列,就实现了类似Linearlayout布局垂直排列的布局
child.layout(0, top, childWidth, top + childHeight); //以父容器左上角为原点进行布局
top += childHeight;
}
} }

最新文章

  1. upgrade to ubuntu14.04, ibus input
  2. Linux常用命令01
  3. 自定义EL
  4. 项目优化经验分享(八)TeamLeader经验总结
  5. android UI进阶之实现listview的下拉加载
  6. 使用Spring简化JDBC操作数据库
  7. 数学概念——F 概率(经典问题)birthday paradox
  8. JavaScript练习2
  9. bug终结者 团队作业第二周
  10. Block高级用法:Block传值UI_12(3)
  11. Zookeeper简介和安装(二)
  12. Linux下编译器的安装
  13. leetcode — binary-tree-level-order-traversal
  14. Python中的锁
  15. SQLServer &#183; 最佳实践 &#183; 透明数据加密TDE在SQLServer的应用
  16. 最短路(bellman)-hdu1217
  17. COM口总是有惊叹号怎么办
  18. vc让界面保持最上层
  19. object视频播放
  20. learning uboot bootargs panic parameter

热门文章

  1. JAVA基础语法——标识符、修饰符、关键字(个人整理总结)
  2. Win10下音频设备无法播放音乐问题定位
  3. Python又把GUI界面攻下了,今天就告诉你怎么玩
  4. Python基础教程(第3版) 笔记(三)
  5. Django--Auth 模块
  6. spring cloud(服务消费者(利用feign实现服务消费及负载均衡)——初学三)
  7. 高手速成android开源项目【developer篇】
  8. C#容器类,性能介绍
  9. eclipse配置ant开发环境,一键部署项目
  10. Django之模型层(单表操作)