本篇文章主要介绍了"Android开发之自定义控件二---onLayout详解",主要涉及到方面的内容,对于Android开发感兴趣的同学可以参考一下:
话说一个乞丐在看一个程序员写程序,程序员遇到一个问题怎么都解决不了,这时乞丐说这少个分号,程序员照做结果问题解决了,就问:你怎么知道?乞丐笑笑说:我之前就是干这...
话说一个乞丐在看一个程序员写程序,程序员遇到一个问题怎么都解决不了,这时乞丐说这少个分号,程序员照做结果问题解决了,就问:你怎么知道?乞丐笑笑说:我之前就是干这个的。通过这个笑话我们学到了不会唱歌的主播不是好司机,那么问题来了今天我们要学习什么呢?
通过本篇博客你将学到
①自定义控件中onLayout的源码分析
②getLeft,getRight,getWidth,getHeight表示的意义
③一个例子来理解自定义控件的onLayout的过程
④getMeasureWidth和getWidth的区别
如有谬误欢迎批评指正,如有疑问欢迎留言,谢谢
1.简单回顾
在上一篇我们详细讲解了onMeasure方法,我们首先来回顾一下上一篇的内容如果你还没有阅读请先阅读(Android开发之自定义控件(一)---onMeasure详解),上一篇我们说到onMeasure的过程,在onMeasure方法中最终调用setMeasuredDimension方法来确定控件的大小,假如是自定义一个View的话,测量一下其大小就行了,如果是ViewGroup呢,则需要遍历其所有的子View来,并为每个子View测量它的大小。在测量子View时需要两个参数,measureWidth和measureHeight这两个值是根布局传过来的,也就是说是父View和子View本身共同决定子View的大小。
2.源码分析
今天呢,就和大家一起来探讨自定义控件的第二步onLayout即确定控件的位置,上篇文章我们说到performTraversals方法中会调用host.measure方法,在调用完host.measure方法后,就会调用host.layout对View进行定位,这也是今天我们要讨论的内容。
首先我们来看看layout的源码
[java] view
plain copy
- public final void layout(int l, int t, int r, int b) {
- boolean changed = setFrame(l, t, r, b);
- if (changed || (mPrivateFlags & LAYOUT_REQUIRED) == LAYOUT_REQUIRED) {
- if (ViewDebug.TRACE_HIERARCHY) {
- ViewDebug.trace(this, ViewDebug.HierarchyTraceType.ON_LAYOUT);
- }
- onLayout(changed, l, t, r, b);
- mPrivateFlags &= ~LAYOUT_REQUIRED;
- }
- mPrivateFlags &= ~FORCE_LAYOUT;
- }
在其中调用了setFrame方法的源码如下
[java] view
plain copy
- protected boolean setFrame(int left, int top, int right, int bottom) {
- boolean changed = false;
- if (mLeft != left || mRight != right || mTop != top || mBottom != bottom) {
- changed = true;
-
- 。。。省略部分代码。。。
-
- mLeft = left;
- mTop = top;
- mRight = right;
- mBottom = bottom;
-
- 。。。省略部分代码。。。
-
- }
- return changed;
- }
在setFrame方法中将left,top,right,bottom这四个值保存下来。也就是说在layout中的setFrame方法中会将子View相对于父View的左,上,右,下这四个值保存下来,这四个值就会确定子View在父View中的位置。仔细的看layout方法的源码你会发现和measure方法一样在layout中调用了onLayout方法,赶紧先去看看View的onLayout的逻辑
View——onLayout
[java] view
plain copy