理解Android的layout和measure
在Android UI开发中,总会有情况需要自定义View和View Group.
什么是View?就是Android中一个基本视图单位,一个Button是一个view, 一个Layout, 也是一个View
什么是ViewGroup, ViewGroup本身也是一种View. 但是ViewGroup能够包含子View. 可以理解为ViewGroup往往是一个容器。比如说LinearLayout, FrameLayout就是属于ViewGroup.
measure和layout是非常重要的两个概念
measure设置view的大小,如果有child view, 循环调用其measure函数
layout摆放child view的位置
举一个例子,我需要在程序中显示一个页面A, 该页面包括两个子view A1, A2.
那么我就需要为A创建一个ViewGroup的继承类。在里面重写OnMeasure函数。伪代码如下:
OnMeasure(){
设置A自身大小
A1.measure //调用子view的measure函数
A2.measure//调用子view的measure函数
}
然后重写OnLayout函数。伪代码如下:
OnLayout(){
设置A1位置
设置A2位置。
}
然后在A1和A2中,重写OnMeasure函数,设置自身大小
A1:
OnMeasure{
设置自身大小
}
A2:
OnMeasure{
设置自身大小
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
但是疑问就来了,为毛要这么麻烦?位置和大小难道不能在xml布局中就指定吗?
我只能回答:擦!我也这样看
但是安卓的设计师们,心怀天下,一心想干出个能应对世界无数种尺寸,面对无数种环境,灵活性伸缩性好比小弟弟的UI框架来。于是......
比如说,他们认为有一种容器,叫LinearLayout。于是就创造了它。 这种神奇的容器,在把子view放入里面的时候,不需要指定其大小,只需要说一句:我和俺爹一样大。于是“啪”,这个字View被贴上一个"Match_parent"标签
也不需要指定位置。因为你的位置总是接在前面一个子View的后面。
哇色!!!!,如果你第一次看到这么神奇的容器,把东西扔进去不需要指定长宽和位置就直接摆放,觉得真的真的好牛逼哦。
但其实不然,一个View如果被放进来,并且标注自身为Match_parent的时候,就会在OnMeasure里面被一顿计算,因为parent大小总是知道的吧,最大不过屏幕嘛,结合margin和padding,就可以被计算出长宽。关于位置。由于所有View都是顺序摆放的,在layout过程中也会结合margin和Padding,给计算出准确的位置。
这么麻烦?绕这么大个圈?那是不是可以直接指定大小和位置呢?
No. 大小可以直接指定,位置不可以直接指定。
为啥位置不能直接指定?
因为这个是LinearLayout,如果你想随意指定位置的,用其他的layout嘛,或者你自己自定义嘛
= =~,再也不想哇色了,我还不如像其他平台一样,直接画一个View出来,往里面随便摆放东西,自己指定大小位置。也不分什么View和ViewGroup了。这些伟大的白痴们,精心设计了一团复杂无比的垃圾
为啥需要measure和layout?为啥不在xml布局阶段就指定大小位置?
别告诉我是为了扩展性的需要,
别告诉我是为了灵活性的需要,
别告诉我是因为手机屏幕尺寸各式各样
No.
只是因为。。。。
把简单的事情搞复杂,是展现下限的方式
理解Android的layout和measure的更多相关文章
- 深入理解 Android 之 View 的绘制流程
概述 本篇文章会从源码(基于Android 6.0)角度分析Android中View的绘制流程,侧重于对整体流程的分析,对一些难以理解的点加以重点阐述,目的是把View绘制的整个流程把握好,而对于特定 ...
- 深入理解Android中ViewGroup
文章目录 [隐藏] 一.ViewGroup是什么? 二.ViewGroup这个容器 2.1 添加View的算法 2.1.1 我们先来分析addViewInner方法: 2.1.2 addInArr ...
- 深入理解Android中View
文章目录 [隐藏] 一.View是什么? 二.View创建的一个概述: 三.View的标志(Flag)系统 四.MeasureSpec 五.几个重要方法简介 5.1 onFinishInflate ...
- 理解Android绘制视图的方式
在创建自定义ViewGroup前,读者首先需要理解Android绘制视图的方式.我不会涉及过多细节,但是需要读者理解Android开发文档(见3.5节)中的一段话,这段话解释如何绘制一个布局.内容如下 ...
- 《深入理解Android 卷III》第六章 深入理解控件(ViewRoot)系统
<深入理解Android 卷III>即将公布,作者是张大伟.此书填补了深入理解Android Framework卷中的一个主要空白,即Android Framework中和UI相关的部分. ...
- Android-深入理解android自定义属性(AttributeSet,TypedArray)
属性 自定义属性,首先要定义出来属性,我们新建一个attrs.xml: <?xml version="1.0" encoding="utf-8"?> ...
- 理解Android系统的进程间通信原理(二)----RPC机制
理解Android系统中的轻量级解决方案RPC的原理,需要先回顾一下JAVA中的RMI(Remote Method Invocation)这个易于使用的纯JAVA方案(用来实现分布式应用).有关RMI ...
- 深入理解Android 自定义attr Style styleable以及其应用
相信每一位从事Android开发的猿都遇到过需要自己去自定义View的需求,如果想通过xml指定一些我们自己需要的参数,就需要自己声明一个styleable,并在里面自己定义一些attr属性,这个过程 ...
- 【转】Android菜单详解——理解android中的Menu--不错
原文网址:http://www.cnblogs.com/qingblog/archive/2012/06/08/2541709.html 前言 今天看了pro android 3中menu这一章,对A ...
随机推荐
- 关于scp 不需要密码
运行 ssh-keygen -t rsa 会在用户目录~/.ssh/产生两个文件,id_rsa,id_rsa.pub // cat id_rsa.pub >~/.ssh/autho ...
- svn 同步到web目录
windows hook 下 @echo offSET REPOS=%1SET REV=%2SET DIR=%REPOS%/hooksSET PATH=%PATH%;SET WORKING=D:/w ...
- libcurl编译
下载: git://github.com/bagder/curl.git openssl: openssl编译 for linux or mingw:./buildconf./configure ...
- [android]清单文件中MAIN与LAUNCHER的区别
原文:[android]清单文件中MAIN与LAUNCHER的区别 MAIN 和 LAUNCHER,之前一直不注意这两个有区别,写程序的时候都放到一个filter中,前两天面试问到了,总结一下: MA ...
- Android学习笔记:利用httpclient和AsyncTask 发起网络http post操作
1.在android4中,发起网络http操作,不能在Activity的事件(即主线程)中进行,必须在单独的线程中操作. 另外进行网络操作,需要在manifest文件中增加如下的权限: <use ...
- poj 3259 (Bellman_Ford判断负环)
题意:John的农场里n块地,m条路连接两块地,k个虫洞,虫洞是一条单向路,不但会把你传送到目的地,而且时间会倒退Ts.我们的任务是知道会不会在从某块地出发后又回来,看到了离开之前的自己. 思路:虫洞 ...
- CentOS7 vs centos6
The CentOS Project has announced general availability of CentOS-7, the first release of the free Lin ...
- SDL介绍
SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成.SDL提供了数种控制图像.声音.输出入的函数,让开发者只要用相同或是相似的代码就可以开发 ...
- ssh login nova vm
$ sudo cat >> /usr/bin/nova-ssh << END FIRST=$1 IDX=`expr index $1 "@"`if [[ ...
- 解决ArcSDE图层名被占用的问题
点击文章查看 当你发现上面那篇文章时你已经接近成功了,但还差最后一步! <!- -delete from sde.GDB_OBJECTCLASSES where NAME = upper(' ...