对 AbsoluteLayout 的一点理解
菜鸟记录一下,把之前的笔记抄到这里
/*** A layout that lets you specify exact locations (x/y coordinates) of its* children. Absolute layouts are less flexible and harder to maintain than* other types of layouts without absolute positioning.** <p><strong>XML attributes</strong></p> <p> See {@link* android.R.styleable#ViewGroup ViewGroup Attributes}, {@link* android.R.styleable#View View Attributes}</p>* * @deprecated Use {@link android.widget.FrameLayout}, {@link android.widget.RelativeLayout}* or a custom layout instead.*/
@Deprecated
@RemoteView
public class AbsoluteLayout extends ViewGroup {
1、哈哈,首先,AbsoluteLayout 继承自 ViewGroup;
2、同样,AbsoluteLayout 需要通过onMeasure 和 onLayout:
a、首先,需要通过 attrs 获取 AbsoluteLayout 的自定义属性,不难理解;
/*** Creates a new set of layout parameters. The values are extracted from* the supplied attributes set and context. The XML attributes mapped* to this set of layout parameters are:** <ul>* <li><code>layout_x</code>: the X location of the child</li>* <li><code>layout_y</code>: the Y location of the child</li>* <li>All the XML attributes from* {@link android.view.ViewGroup.LayoutParams}</li>* </ul>** @param c the application environment* @param attrs the set of attributes from which to extract the layout* parameters values*/public LayoutParams(Context c, AttributeSet attrs) {super(c, attrs);TypedArray a = c.obtainStyledAttributes(attrs,com.android.internal.R.styleable.AbsoluteLayout_Layout);x = a.getDimensionPixelOffset(com.android.internal.R.styleable.AbsoluteLayout_Layout_layout_x, 0);y = a.getDimensionPixelOffset(com.android.internal.R.styleable.AbsoluteLayout_Layout_layout_y, 0);a.recycle();}
b、onMeasure
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int count = getChildCount();int maxHeight = 0;int maxWidth = 0;// Find out how big everyone wants to bemeasureChildren(widthMeasureSpec, heightMeasureSpec);// Find rightmost and bottom-most childfor (int i = 0; i < count; i++) {View child = getChildAt(i);if (child.getVisibility() != GONE) {int childRight;int childBottom;AbsoluteLayout.LayoutParams lp= (AbsoluteLayout.LayoutParams) child.getLayoutParams();childRight = lp.x + child.getMeasuredWidth();childBottom = lp.y + child.getMeasuredHeight();maxWidth = Math.max(maxWidth, childRight);maxHeight = Math.max(maxHeight, childBottom);}}// Account for padding toomaxWidth += mPaddingLeft + mPaddingRight;maxHeight += mPaddingTop + mPaddingBottom;// Check against minimum height and widthmaxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, 0),resolveSizeAndState(maxHeight, heightMeasureSpec, 0));}
1)首先,通过 getChildCount() 获取 子控件的个数;
2)由注释 Find out how big everyone wants to be 可知,第二步通过measureChildren(widthMeasureSpec, heightMeasureSpec);
对子控件进行测量;
3)接下来进入了一个 for 循环,通过注释 // Find rightmost and bottom-most child
可知,需要找出最右边和最下边的子控件,如下
从左上角开始,使用 wrap_content,通过上图可以知道,需要找出 最右边 和 最下边的 子view的 right 或者 bottom,所以接下来 for 循环中 便是 通过 每次获取 以及 比较来找到想要的结果:
1)首先,获取每个 子view,同样,当 child.getVisibility() 为 GONE 的时候,我们可以直接忽略,所以判断条件为 不是 GONE;
2)通过 AbsoluteLayout.LayoutParams 获取每个子view的 layoutParams,layoutParams 封装了view 的 x 以及 y
public static class LayoutParams extends ViewGroup.LayoutParams {/*** The horizontal, or X, location of the child within the view group.*/public int x;/*** The vertical, or Y, location of the child within the view group.*/public int y;
上面是 AbsoluteLayout 的 LayoutParams ,对比一下 RelativeLayout 的 LayoutParams,
public static class LayoutParams extends ViewGroup.MarginLayoutParams {@ViewDebug.ExportedProperty(category = "layout", resolveId = true, indexMapping = {@ViewDebug.IntToString(from = ABOVE, to = "above"),@ViewDebug.IntToString(from = ALIGN_BASELINE, to = "alignBaseline"),
通过对比可知,AbsoluteLayout 的 LayoutParams 直接继承了 ViewGroup 的 LayoutParams ,而 RelativeLayout 的 继承的 是 MarginLayoutParams,可以得知 AbsoluteLayout 不支持 margin 属性,所以 在 onmeasure 的 for 循环中对每个子View 进行测量无需考虑 margin;
3)接下来,通过 每个 子View 的 x 以及 y 坐标,以及子View 宽高,获得最大的 height 和 width
childRight = lp.x + child.getMeasuredWidth();childBottom = lp.y + child.getMeasuredHeight();maxWidth = Math.max(maxWidth, childRight);maxHeight = Math.max(maxHeight, childBottom);
4)for 循环之后,执行以下代码:
// Account for padding toomaxWidth += mPaddingLeft + mPaddingRight;maxHeight += mPaddingTop + mPaddingBottom;// Check against minimum height and widthmaxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, 0),resolveSizeAndState(maxHeight, heightMeasureSpec, 0));
主要是通过 for 循环计算得出的最大的 height 以及 width,并且加上 最外层 AbsoluteLayout 的 padding,如下:
AbsoluteLayout 添加了 mPaddingLeft 和 mPaddingBottom 之后,子View的坐标轴会 向右 移动 mPaddingLeft 以及向下移动 mPaddingBottom,所以 for 循环之后需要 加上 这两个参数;
c、onLayout
onLayout 代码如下:
@Overrideprotected void onLayout(boolean changed, int l, int t,int r, int b) {int count = getChildCount();for (int i = 0; i < count; i++) {View child = getChildAt(i);if (child.getVisibility() != GONE) {AbsoluteLayout.LayoutParams lp =(AbsoluteLayout.LayoutParams) child.getLayoutParams();int childLeft = mPaddingLeft + lp.x;int childTop = mPaddingTop + lp.y;child.layout(childLeft, childTop,childLeft + child.getMeasuredWidth(),childTop + child.getMeasuredHeight());}}}
同样,通过 getChildCount() 获取数目之后,在for循环中摆放 子View的位置,AbsoluteLayout 通过 x和 y 来确定 位置,所以 通过 x、y 以及 子view 的height 以及 width 即可,调用 child.layout();四个参数分别为 子view 的 x、子view 的y、子view 的 width、子view 的height;
3、接下来,有一个方法
@Overridepublic ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {return new AbsoluteLayout.LayoutParams(getContext(), attrs);}`
我们首先在 类 LayoutInflater 中可以看到如下代码:
final View temp = createViewFromTag(root, name, inflaterContext, attrs);ViewGroup.LayoutParams params = null;// Create layout params that match root, if suppliedparams = root.generateLayoutParams(attrs);
可以知道,generateLayoutParams 方法将我们自定义 的属性转换成 父布局的 LayoutParams,所以我们在 xml 中使用属性也是通过这个方法转换。
以上便是个人对 AbsoluteLayout 的一点理解,不对之处欢迎吐槽。
对 AbsoluteLayout 的一点理解相关推荐
- 谈谈对APC的一点理解
谈谈对APC的一点理解 异步过程调用(APCs) 是NT异步处理体系结构中的一个基础部分,理解了它,对于了解NT怎样操作和执行几个核心的系统操作很有帮助. 1) APCs允许用户程序和系统元件在一个进 ...
- python 3列表推导式的的一点理解!
python 3列表推导式的的一点理解! Python的列表推导式对于新手来说一般都难以理解,简单看个例子: [x * x for x in range(1,100)] 上面是一个很简单的列表推导式, ...
- TSYS2.0对动态碎片的一点理解
最近好多人对tsys很感兴趣,其实大家不知道的是tsys的asp版本早就已经停止开发了,为了不想让如此优秀的东西被埋没所以我在tsys的asp版 本的基础上使用PHP重新开发了一个功能更强的cms,名 ...
- 对事件循环的一点理解
最近工作需要学习了解webworker-threads以应对Javascript多线程处理CPU密集型的可能性:参考文档JavaScript多线程之二 Node.js中的Web Worker; 以下是 ...
- Hyperledger Fabric 网络环境的一点理解
Hyperledger Fabric 开发链码,一般都是测试网络开发,然后部署到生产网络. 下面介绍测试网络.生产网络的一点理解. 1 测试网络 使用cryptogen等工具建立测试网络,开发环境使用 ...
- Tecplot中用excel表格绘制xy图的一点理解
原文地址:Tecplot中用excel表格绘制xy图的一点理解作者:又见谷雨 在画图的时候遇到一些问题,比如想用excel中的数据画xy图,那么应该怎样加载这些数据呢.在网上查找了下,也没有详细的说法 ...
- 2.深入一点理解C源程序的编译过程
2.深入一点理解C源程序的编译过程 本文章的大多数灵感及知识来源于南京大学的计算机系统基础教材,如果希望更加深入地对相关知识做进一步了解,可以移步上述相关资源.在网上可以轻易获得上述资源,mooc也有 ...
- negroni包和mux包的一点理解
codegangsta/negroni包和gorilla/mux包的一点理解 Negroni是一个http.Handle,因为他实现了 func (n *Negroni) ServeHTTP(rw h ...
- 对PCIE设备访问及其配置空间的一点理解
讲讲对PCIE总线协议的一点理解吧.感觉每一年又会多一点理解,但不懂得地方仍很多. PCI总线是拓扑结构,PCI总线从0开始,不超过256(但一般不会一层一层挂太多).Device不超过32,Func ...
最新文章
- 针对复杂***的情报分析实例
- 比特币现金支持者为网络的未来六个月做准备
- 运行单个源文件_使用一个命令执行单个Java源文件
- 将GPIO外设挂到Cortex_M3 AHB总线上详细流程扩展外设步骤总结
- 一线互联网公司薪资情况,可供你参考!
- python 小案例
- [转载] Python元组操作及方法总结
- gom引擎登录器_GOM传奇引擎微端配置详细架设语音教程
- mysql中clear怎么用_MySQL 入门篇
- 【转】鼠标右键菜单设置大全
- simulink积分器报错
- 同源、跨域、跨站、SameSite与withCredentials
- WordPress强大多功能主题模板The7 v9.16.0 已激活版本完全兼容大多数插件
- 微信公众号迁移时同一个公司两个微信号公证问题
- 连连看消除算法和最佳路径推荐
- c语言单价英文,英文词汇大全:常见价格及费用词语
- 年薪翻倍的100篇面经:如何转型AI拿到阿里等大厂的40万offer
- Python 裁剪九宫格图片 —— 筑梦之路
- 杨振宁 莫言 范曾 《开讲啦》
- 田忌赛马 贪心 注意细节