android 百分比layout布局
来源:互联网 发布:人工智能概念股 编辑:程序博客网 时间:2024/05/14 16:17
本文出自:【张鸿洋的博客】
一、概述
周末游戏打得过猛,于是周天熬夜码代码,周一早上浑浑噩噩的发现android-percent-support-lib-sample这个项目,Google终于开始支持百分比的方式布局了,瞬间脉动回来,啊咧咧。对于这种历史性的时刻,不出篇博客难以表达我内心的激动。
还记得不久前,发了篇博客:Android 屏幕适配方案,这篇博客以Web页面设计引出一种适配方案,最终的目的就是可以通过百分比控制控件的大小。当然了,存在一些问题,比如:
- 对于没有考虑到屏幕尺寸,可能会出现意外的情况;
- apk的大小会增加;
当然了android-percent-support这个库,基本可以解决上述问题,是不是有点小激动,稍等,我们先描述下这个support-lib。
这个库提供了:
两种布局供大家使用:
PercentRelativeLayout
、PercentFrameLayout
,通过名字就可以看出,这是继承自FrameLayout
和RelativeLayout
两个容器类;支持的属性有:
layout_widthPercent
、layout_heightPercent
、 layout_marginPercent
、layout_marginLeftPercent
、 layout_marginTopPercent
、layout_marginRightPercent
、 layout_marginBottomPercent
、layout_marginStartPercent
、layout_marginEndPercent
。
可以看到支持宽高,以及margin。
也就是说,大家只要在开发过程中使用PercentRelativeLayout
、PercentFrameLayout
替换FrameLayout
、RelativeLayout
即可。
是不是很简单,不过貌似没有LinearLayout,有人会说LinearLayout有weight属性呀。但是,weight属性只能支持一个方向呀~~哈,没事,刚好给我们一个机会去自定义一个PercentLinearLayout
。
好了,本文分为3个部分:
PercentRelativeLayout
、PercentFrameLayout
的使用- 对上述控件源码分析
- 自定义
PercentLinearLayout
二、使用
关于使用,其实及其简单,并且github上也有例子,android-percent-support-lib-sample。我们就简单过一下:
首先记得在build.gradle添加:
<code class="language-xml hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "> compile 'com.android.support:percent:22.2.0'</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li></ul>
(一)PercentFrameLayout
<code class="language-xml hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-pi" style="color: rgb(0, 102, 102); box-sizing: border-box; "><?xml version="1.0" encoding="utf-8"?></span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">android.support.percent.PercentFrameLayout</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">xmlns:app</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"http://schemas.android.com/apk/res-auto"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"match_parent"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"match_parent"</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">TextView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"left|top"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#44ff0000"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"width:30%,height:20%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_heightPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"20%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"center"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_widthPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"30%"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">TextView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"right|top"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"center"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#4400ff00"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"width:70%,height:20%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_heightPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"20%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_widthPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"70%"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">TextView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"bottom"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#770000ff"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"width:100%,height:10%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"center"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_heightPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"10%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_widthPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"100%"</span>/></span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">android.support.percent.PercentFrameLayout</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li><li style="box-sizing: border-box; padding: 0px 5px; ">6</li><li style="box-sizing: border-box; padding: 0px 5px; ">7</li><li style="box-sizing: border-box; padding: 0px 5px; ">8</li><li style="box-sizing: border-box; padding: 0px 5px; ">9</li><li style="box-sizing: border-box; padding: 0px 5px; ">10</li><li style="box-sizing: border-box; padding: 0px 5px; ">11</li><li style="box-sizing: border-box; padding: 0px 5px; ">12</li><li style="box-sizing: border-box; padding: 0px 5px; ">13</li><li style="box-sizing: border-box; padding: 0px 5px; ">14</li><li style="box-sizing: border-box; padding: 0px 5px; ">15</li><li style="box-sizing: border-box; padding: 0px 5px; ">16</li><li style="box-sizing: border-box; padding: 0px 5px; ">17</li><li style="box-sizing: border-box; padding: 0px 5px; ">18</li><li style="box-sizing: border-box; padding: 0px 5px; ">19</li><li style="box-sizing: border-box; padding: 0px 5px; ">20</li><li style="box-sizing: border-box; padding: 0px 5px; ">21</li><li style="box-sizing: border-box; padding: 0px 5px; ">22</li><li style="box-sizing: border-box; padding: 0px 5px; ">23</li><li style="box-sizing: border-box; padding: 0px 5px; ">24</li><li style="box-sizing: border-box; padding: 0px 5px; ">25</li><li style="box-sizing: border-box; padding: 0px 5px; ">26</li><li style="box-sizing: border-box; padding: 0px 5px; ">27</li><li style="box-sizing: border-box; padding: 0px 5px; ">28</li><li style="box-sizing: border-box; padding: 0px 5px; ">29</li><li style="box-sizing: border-box; padding: 0px 5px; ">30</li><li style="box-sizing: border-box; padding: 0px 5px; ">31</li><li style="box-sizing: border-box; padding: 0px 5px; ">32</li><li style="box-sizing: border-box; padding: 0px 5px; ">33</li><li style="box-sizing: border-box; padding: 0px 5px; ">34</li><li style="box-sizing: border-box; padding: 0px 5px; ">35</li><li style="box-sizing: border-box; padding: 0px 5px; ">36</li><li style="box-sizing: border-box; padding: 0px 5px; ">37</li><li style="box-sizing: border-box; padding: 0px 5px; ">38</li><li style="box-sizing: border-box; padding: 0px 5px; ">39</li><li style="box-sizing: border-box; padding: 0px 5px; ">40</li><li style="box-sizing: border-box; padding: 0px 5px; ">41</li></ul>
3个TextView,很简单,直接看效果图:
(二) PercentRelativeLayout
<code class="language-xml hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-pi" style="color: rgb(0, 102, 102); box-sizing: border-box; "><?xml version="1.0" encoding="utf-8"?></span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">android.support.percent.PercentRelativeLayout</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">xmlns:app</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"http://schemas.android.com/apk/res-auto"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"match_parent"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"match_parent"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:clickable</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"true"</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">TextView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"@+id/row_one_item_one"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_alignParentTop</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"true"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#7700ff00"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"w:70%,h:20%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"center"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_heightPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"20%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_widthPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"70%"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">TextView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"@+id/row_one_item_two"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_toRightOf</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"@+id/row_one_item_one"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#396190"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"w:30%,h:20%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_heightPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"20%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"center"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_widthPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"30%"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">ImageView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:id</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"@+id/row_two_item_one"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"match_parent"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:src</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"@drawable/tangyan"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:scaleType</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"centerCrop"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_below</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"@+id/row_one_item_one"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#d89695"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_heightPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"70%"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">TextView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_below</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"@id/row_two_item_one"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#770000ff"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"center"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"width:100%,height:10%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_heightPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"10%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_widthPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"100%"</span>/></span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">android.support.percent.PercentRelativeLayout</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li><li style="box-sizing: border-box; padding: 0px 5px; ">6</li><li style="box-sizing: border-box; padding: 0px 5px; ">7</li><li style="box-sizing: border-box; padding: 0px 5px; ">8</li><li style="box-sizing: border-box; padding: 0px 5px; ">9</li><li style="box-sizing: border-box; padding: 0px 5px; ">10</li><li style="box-sizing: border-box; padding: 0px 5px; ">11</li><li style="box-sizing: border-box; padding: 0px 5px; ">12</li><li style="box-sizing: border-box; padding: 0px 5px; ">13</li><li style="box-sizing: border-box; padding: 0px 5px; ">14</li><li style="box-sizing: border-box; padding: 0px 5px; ">15</li><li style="box-sizing: border-box; padding: 0px 5px; ">16</li><li style="box-sizing: border-box; padding: 0px 5px; ">17</li><li style="box-sizing: border-box; padding: 0px 5px; ">18</li><li style="box-sizing: border-box; padding: 0px 5px; ">19</li><li style="box-sizing: border-box; padding: 0px 5px; ">20</li><li style="box-sizing: border-box; padding: 0px 5px; ">21</li><li style="box-sizing: border-box; padding: 0px 5px; ">22</li><li style="box-sizing: border-box; padding: 0px 5px; ">23</li><li style="box-sizing: border-box; padding: 0px 5px; ">24</li><li style="box-sizing: border-box; padding: 0px 5px; ">25</li><li style="box-sizing: border-box; padding: 0px 5px; ">26</li><li style="box-sizing: border-box; padding: 0px 5px; ">27</li><li style="box-sizing: border-box; padding: 0px 5px; ">28</li><li style="box-sizing: border-box; padding: 0px 5px; ">29</li><li style="box-sizing: border-box; padding: 0px 5px; ">30</li><li style="box-sizing: border-box; padding: 0px 5px; ">31</li><li style="box-sizing: border-box; padding: 0px 5px; ">32</li><li style="box-sizing: border-box; padding: 0px 5px; ">33</li><li style="box-sizing: border-box; padding: 0px 5px; ">34</li><li style="box-sizing: border-box; padding: 0px 5px; ">35</li><li style="box-sizing: border-box; padding: 0px 5px; ">36</li><li style="box-sizing: border-box; padding: 0px 5px; ">37</li><li style="box-sizing: border-box; padding: 0px 5px; ">38</li><li style="box-sizing: border-box; padding: 0px 5px; ">39</li><li style="box-sizing: border-box; padding: 0px 5px; ">40</li><li style="box-sizing: border-box; padding: 0px 5px; ">41</li><li style="box-sizing: border-box; padding: 0px 5px; ">42</li><li style="box-sizing: border-box; padding: 0px 5px; ">43</li><li style="box-sizing: border-box; padding: 0px 5px; ">44</li><li style="box-sizing: border-box; padding: 0px 5px; ">45</li><li style="box-sizing: border-box; padding: 0px 5px; ">46</li><li style="box-sizing: border-box; padding: 0px 5px; ">47</li><li style="box-sizing: border-box; padding: 0px 5px; ">48</li><li style="box-sizing: border-box; padding: 0px 5px; ">49</li><li style="box-sizing: border-box; padding: 0px 5px; ">50</li><li style="box-sizing: border-box; padding: 0px 5px; ">51</li><li style="box-sizing: border-box; padding: 0px 5px; ">52</li><li style="box-sizing: border-box; padding: 0px 5px; ">53</li><li style="box-sizing: border-box; padding: 0px 5px; ">54</li><li style="box-sizing: border-box; padding: 0px 5px; ">55</li></ul>
ok,依然是直接看效果图:
使用没什么好说的,就是直观的看一下。
三、源码分析
其实细想一下,Google只是对我们原本熟悉的RelativeLayout和FrameLayout进行的功能的扩展,使其支持了percent相关的属性。
那么,我们考虑下,如果是我们添加这种扩展,我们会怎么做:
- 通过LayoutParams获取child设置的percent相关属性的值
- onMeasure的时候,将child的width,height的值,通过获取的自定义属性的值进行计算(eg:容器的宽 * fraction ),计算后传入给child.measure(w,h);
ok,有了上面的猜想,我们直接看PercentFrameLayout
的源码。
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-class" style="box-sizing: border-box; "><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">PercentFrameLayout</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">FrameLayout</span> {</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">final</span> PercentLayoutHelper mHelper = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">new</span> PercentLayoutHelper(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">this</span>); <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box; ">//省略了,两个构造方法</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-title" style="box-sizing: border-box; ">PercentFrameLayout</span>(Context context, AttributeSet attrs) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>(context, attrs); } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; ">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> LayoutParams <span class="hljs-title" style="box-sizing: border-box; ">generateLayoutParams</span>(AttributeSet attrs) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">new</span> LayoutParams(getContext(), attrs); } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; ">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">void</span> <span class="hljs-title" style="box-sizing: border-box; ">onMeasure</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> widthMeasureSpec, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> heightMeasureSpec) { mHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>.onMeasure(widthMeasureSpec, heightMeasureSpec); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (mHelper.handleMeasuredStateTooSmall()) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>.onMeasure(widthMeasureSpec, heightMeasureSpec); } } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; ">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">void</span> <span class="hljs-title" style="box-sizing: border-box; ">onLayout</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">boolean</span> changed, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> left, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> top, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> right, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> bottom) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>.onLayout(changed, left, top, right, bottom); mHelper.restoreOriginalParams(); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">static</span> <span class="hljs-class" style="box-sizing: border-box; "><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">LayoutParams</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">FrameLayout</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">LayoutParams</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">implements</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">PercentLayoutHelper</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">PercentLayoutParams</span> {</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">private</span> PercentLayoutHelper.PercentLayoutInfo mPercentLayoutInfo; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-title" style="box-sizing: border-box; ">LayoutParams</span>(Context c, AttributeSet attrs) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>(c, attrs); mPercentLayoutInfo = PercentLayoutHelper.getPercentLayoutInfo(c, attrs); } <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box; ">//省略了一些代码...</span> <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; ">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> PercentLayoutHelper.PercentLayoutInfo <span class="hljs-title" style="box-sizing: border-box; ">getPercentLayoutInfo</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">return</span> mPercentLayoutInfo; } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; ">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">void</span> <span class="hljs-title" style="box-sizing: border-box; ">setBaseAttributes</span>(TypedArray a, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> widthAttr, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> heightAttr) { PercentLayoutHelper.fetchWidthAndHeight(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">this</span>, a, widthAttr, heightAttr); } }}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li><li style="box-sizing: border-box; padding: 0px 5px; ">6</li><li style="box-sizing: border-box; padding: 0px 5px; ">7</li><li style="box-sizing: border-box; padding: 0px 5px; ">8</li><li style="box-sizing: border-box; padding: 0px 5px; ">9</li><li style="box-sizing: border-box; padding: 0px 5px; ">10</li><li style="box-sizing: border-box; padding: 0px 5px; ">11</li><li style="box-sizing: border-box; padding: 0px 5px; ">12</li><li style="box-sizing: border-box; padding: 0px 5px; ">13</li><li style="box-sizing: border-box; padding: 0px 5px; ">14</li><li style="box-sizing: border-box; padding: 0px 5px; ">15</li><li style="box-sizing: border-box; padding: 0px 5px; ">16</li><li style="box-sizing: border-box; padding: 0px 5px; ">17</li><li style="box-sizing: border-box; padding: 0px 5px; ">18</li><li style="box-sizing: border-box; padding: 0px 5px; ">19</li><li style="box-sizing: border-box; padding: 0px 5px; ">20</li><li style="box-sizing: border-box; padding: 0px 5px; ">21</li><li style="box-sizing: border-box; padding: 0px 5px; ">22</li><li style="box-sizing: border-box; padding: 0px 5px; ">23</li><li style="box-sizing: border-box; padding: 0px 5px; ">24</li><li style="box-sizing: border-box; padding: 0px 5px; ">25</li><li style="box-sizing: border-box; padding: 0px 5px; ">26</li><li style="box-sizing: border-box; padding: 0px 5px; ">27</li><li style="box-sizing: border-box; padding: 0px 5px; ">28</li><li style="box-sizing: border-box; padding: 0px 5px; ">29</li><li style="box-sizing: border-box; padding: 0px 5px; ">30</li><li style="box-sizing: border-box; padding: 0px 5px; ">31</li><li style="box-sizing: border-box; padding: 0px 5px; ">32</li><li style="box-sizing: border-box; padding: 0px 5px; ">33</li><li style="box-sizing: border-box; padding: 0px 5px; ">34</li><li style="box-sizing: border-box; padding: 0px 5px; ">35</li><li style="box-sizing: border-box; padding: 0px 5px; ">36</li><li style="box-sizing: border-box; padding: 0px 5px; ">37</li><li style="box-sizing: border-box; padding: 0px 5px; ">38</li><li style="box-sizing: border-box; padding: 0px 5px; ">39</li><li style="box-sizing: border-box; padding: 0px 5px; ">40</li><li style="box-sizing: border-box; padding: 0px 5px; ">41</li><li style="box-sizing: border-box; padding: 0px 5px; ">42</li><li style="box-sizing: border-box; padding: 0px 5px; ">43</li><li style="box-sizing: border-box; padding: 0px 5px; ">44</li><li style="box-sizing: border-box; padding: 0px 5px; ">45</li><li style="box-sizing: border-box; padding: 0px 5px; ">46</li><li style="box-sizing: border-box; padding: 0px 5px; ">47</li><li style="box-sizing: border-box; padding: 0px 5px; ">48</li><li style="box-sizing: border-box; padding: 0px 5px; ">49</li><li style="box-sizing: border-box; padding: 0px 5px; ">50</li><li style="box-sizing: border-box; padding: 0px 5px; ">51</li><li style="box-sizing: border-box; padding: 0px 5px; ">52</li></ul>
代码是相当的短,可以看到PercentFrameLayout
里面首先重写了generateLayoutParams方法,当然了,由于支持了一些新的layout_属性,那么肯定需要定义对应的LayoutParams。
(一)percent相关属性的获取
可以看到PercentFrameLayout.LayoutParams在原有的FrameLayout.LayoutParams基础上,实现了PercentLayoutHelper.PercentLayoutParams接口。
这个接口很简单,只有一个方法:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-class" style="box-sizing: border-box; "><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">interface</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">PercentLayoutParams</span> {</span> PercentLayoutInfo getPercentLayoutInfo(); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li></ul>
而,这个方法的实现呢,也只有一行:return mPercentLayoutInfo;
,那么这个mPercentLayoutInfo在哪完成赋值呢?
看PercentFrameLayout.LayoutParams的构造方法:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-title" style="box-sizing: border-box; ">LayoutParams</span>(Context c, AttributeSet attrs) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>(c, attrs); mPercentLayoutInfo = PercentLayoutHelper.getPercentLayoutInfo(c, attrs); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li></ul>
可以看到,将attrs传入给getPercentLayoutInfo方法,那么不用说,这个方法的内部,肯定是获取自定义属性的值,然后将其封装到PercentLayoutInfo对象中,最后返回。
代码如下:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">static</span> PercentLayoutInfo <span class="hljs-title" style="box-sizing: border-box; ">getPercentLayoutInfo</span>(Context context, AttributeSet attrs) { PercentLayoutInfo info = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">null</span>; TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.PercentLayout_Layout); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">float</span> value = array.getFraction(R.styleable.PercentLayout_Layout_layout_widthPercent, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (value != -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"percent width: "</span> + value); } info = info != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">null</span> ? info : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">new</span> PercentLayoutInfo(); info.widthPercent = value; } value = array.getFraction(R.styleable.PercentLayout_Layout_layout_heightPercent, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (value != -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"percent height: "</span> + value); } info = info != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">null</span> ? info : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">new</span> PercentLayoutInfo(); info.heightPercent = value; } value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginPercent, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (value != -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"percent margin: "</span> + value); } info = info != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">null</span> ? info : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">new</span> PercentLayoutInfo(); info.leftMarginPercent = value; info.topMarginPercent = value; info.rightMarginPercent = value; info.bottomMarginPercent = value; } value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginLeftPercent, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (value != -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"percent left margin: "</span> + value); } info = info != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">null</span> ? info : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">new</span> PercentLayoutInfo(); info.leftMarginPercent = value; } value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginTopPercent, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (value != -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"percent top margin: "</span> + value); } info = info != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">null</span> ? info : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">new</span> PercentLayoutInfo(); info.topMarginPercent = value; } value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginRightPercent, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (value != -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"percent right margin: "</span> + value); } info = info != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">null</span> ? info : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">new</span> PercentLayoutInfo(); info.rightMarginPercent = value; } value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginBottomPercent, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (value != -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"percent bottom margin: "</span> + value); } info = info != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">null</span> ? info : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">new</span> PercentLayoutInfo(); info.bottomMarginPercent = value; } value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginStartPercent, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (value != -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"percent start margin: "</span> + value); } info = info != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">null</span> ? info : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">new</span> PercentLayoutInfo(); info.startMarginPercent = value; } value = array.getFraction(R.styleable.PercentLayout_Layout_layout_marginEndPercent, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>, -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (value != -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">1</span>f) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"percent end margin: "</span> + value); } info = info != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">null</span> ? info : <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">new</span> PercentLayoutInfo(); info.endMarginPercent = value; } array.recycle(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"constructed: "</span> + info); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">return</span> info; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li><li style="box-sizing: border-box; padding: 0px 5px; ">6</li><li style="box-sizing: border-box; padding: 0px 5px; ">7</li><li style="box-sizing: border-box; padding: 0px 5px; ">8</li><li style="box-sizing: border-box; padding: 0px 5px; ">9</li><li style="box-sizing: border-box; padding: 0px 5px; ">10</li><li style="box-sizing: border-box; padding: 0px 5px; ">11</li><li style="box-sizing: border-box; padding: 0px 5px; ">12</li><li style="box-sizing: border-box; padding: 0px 5px; ">13</li><li style="box-sizing: border-box; padding: 0px 5px; ">14</li><li style="box-sizing: border-box; padding: 0px 5px; ">15</li><li style="box-sizing: border-box; padding: 0px 5px; ">16</li><li style="box-sizing: border-box; padding: 0px 5px; ">17</li><li style="box-sizing: border-box; padding: 0px 5px; ">18</li><li style="box-sizing: border-box; padding: 0px 5px; ">19</li><li style="box-sizing: border-box; padding: 0px 5px; ">20</li><li style="box-sizing: border-box; padding: 0px 5px; ">21</li><li style="box-sizing: border-box; padding: 0px 5px; ">22</li><li style="box-sizing: border-box; padding: 0px 5px; ">23</li><li style="box-sizing: border-box; padding: 0px 5px; ">24</li><li style="box-sizing: border-box; padding: 0px 5px; ">25</li><li style="box-sizing: border-box; padding: 0px 5px; ">26</li><li style="box-sizing: border-box; padding: 0px 5px; ">27</li><li style="box-sizing: border-box; padding: 0px 5px; ">28</li><li style="box-sizing: border-box; padding: 0px 5px; ">29</li><li style="box-sizing: border-box; padding: 0px 5px; ">30</li><li style="box-sizing: border-box; padding: 0px 5px; ">31</li><li style="box-sizing: border-box; padding: 0px 5px; ">32</li><li style="box-sizing: border-box; padding: 0px 5px; ">33</li><li style="box-sizing: border-box; padding: 0px 5px; ">34</li><li style="box-sizing: border-box; padding: 0px 5px; ">35</li><li style="box-sizing: border-box; padding: 0px 5px; ">36</li><li style="box-sizing: border-box; padding: 0px 5px; ">37</li><li style="box-sizing: border-box; padding: 0px 5px; ">38</li><li style="box-sizing: border-box; padding: 0px 5px; ">39</li><li style="box-sizing: border-box; padding: 0px 5px; ">40</li><li style="box-sizing: border-box; padding: 0px 5px; ">41</li><li style="box-sizing: border-box; padding: 0px 5px; ">42</li><li style="box-sizing: border-box; padding: 0px 5px; ">43</li><li style="box-sizing: border-box; padding: 0px 5px; ">44</li><li style="box-sizing: border-box; padding: 0px 5px; ">45</li><li style="box-sizing: border-box; padding: 0px 5px; ">46</li><li style="box-sizing: border-box; padding: 0px 5px; ">47</li><li style="box-sizing: border-box; padding: 0px 5px; ">48</li><li style="box-sizing: border-box; padding: 0px 5px; ">49</li><li style="box-sizing: border-box; padding: 0px 5px; ">50</li><li style="box-sizing: border-box; padding: 0px 5px; ">51</li><li style="box-sizing: border-box; padding: 0px 5px; ">52</li><li style="box-sizing: border-box; padding: 0px 5px; ">53</li><li style="box-sizing: border-box; padding: 0px 5px; ">54</li><li style="box-sizing: border-box; padding: 0px 5px; ">55</li><li style="box-sizing: border-box; padding: 0px 5px; ">56</li><li style="box-sizing: border-box; padding: 0px 5px; ">57</li><li style="box-sizing: border-box; padding: 0px 5px; ">58</li><li style="box-sizing: border-box; padding: 0px 5px; ">59</li><li style="box-sizing: border-box; padding: 0px 5px; ">60</li><li style="box-sizing: border-box; padding: 0px 5px; ">61</li><li style="box-sizing: border-box; padding: 0px 5px; ">62</li><li style="box-sizing: border-box; padding: 0px 5px; ">63</li><li style="box-sizing: border-box; padding: 0px 5px; ">64</li><li style="box-sizing: border-box; padding: 0px 5px; ">65</li><li style="box-sizing: border-box; padding: 0px 5px; ">66</li><li style="box-sizing: border-box; padding: 0px 5px; ">67</li><li style="box-sizing: border-box; padding: 0px 5px; ">68</li><li style="box-sizing: border-box; padding: 0px 5px; ">69</li><li style="box-sizing: border-box; padding: 0px 5px; ">70</li><li style="box-sizing: border-box; padding: 0px 5px; ">71</li><li style="box-sizing: border-box; padding: 0px 5px; ">72</li><li style="box-sizing: border-box; padding: 0px 5px; ">73</li><li style="box-sizing: border-box; padding: 0px 5px; ">74</li><li style="box-sizing: border-box; padding: 0px 5px; ">75</li><li style="box-sizing: border-box; padding: 0px 5px; ">76</li><li style="box-sizing: border-box; padding: 0px 5px; ">77</li><li style="box-sizing: border-box; padding: 0px 5px; ">78</li><li style="box-sizing: border-box; padding: 0px 5px; ">79</li><li style="box-sizing: border-box; padding: 0px 5px; ">80</li><li style="box-sizing: border-box; padding: 0px 5px; ">81</li><li style="box-sizing: border-box; padding: 0px 5px; ">82</li><li style="box-sizing: border-box; padding: 0px 5px; ">83</li><li style="box-sizing: border-box; padding: 0px 5px; ">84</li><li style="box-sizing: border-box; padding: 0px 5px; ">85</li><li style="box-sizing: border-box; padding: 0px 5px; ">86</li><li style="box-sizing: border-box; padding: 0px 5px; ">87</li><li style="box-sizing: border-box; padding: 0px 5px; ">88</li><li style="box-sizing: border-box; padding: 0px 5px; ">89</li><li style="box-sizing: border-box; padding: 0px 5px; ">90</li><li style="box-sizing: border-box; padding: 0px 5px; ">91</li><li style="box-sizing: border-box; padding: 0px 5px; ">92</li></ul>
是不是和我们平时的取值很类似,所有的值最终封装到PercentLayoutInfo对象中。
ok,到此我们的属性获取就介绍完成,有了这些属性,是不是onMeasure里面要进行使用呢?
(二) onMeasue中重新计算child的尺寸
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; ">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">void</span> <span class="hljs-title" style="box-sizing: border-box; ">onMeasure</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> widthMeasureSpec, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> heightMeasureSpec) { mHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>.onMeasure(widthMeasureSpec, heightMeasureSpec); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (mHelper.handleMeasuredStateTooSmall()) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>.onMeasure(widthMeasureSpec, heightMeasureSpec); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li><li style="box-sizing: border-box; padding: 0px 5px; ">6</li><li style="box-sizing: border-box; padding: 0px 5px; ">7</li><li style="box-sizing: border-box; padding: 0px 5px; ">8</li></ul>
可以看到onMeasure中的代码页很少,看来核心的代码都被封装在mHelper的方法中,我们直接看mHelper.adjustChildren方法。
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box; ">/** * Iterates over children and changes their width and height to one calculated from percentage * values. *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box; "> @param</span> widthMeasureSpec Width MeasureSpec of the parent ViewGroup. *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); box-sizing: border-box; "> @param</span> heightMeasureSpec Height MeasureSpec of the parent ViewGroup. */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">void</span> <span class="hljs-title" style="box-sizing: border-box; ">adjustChildren</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> widthMeasureSpec, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> heightMeasureSpec) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box; ">//...</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> widthHint = View.MeasureSpec.getSize(widthMeasureSpec); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> heightHint = View.MeasureSpec.getSize(heightMeasureSpec); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">0</span>, N = mHost.getChildCount(); i < N; i++) { View view = mHost.getChildAt(i); ViewGroup.LayoutParams params = view.getLayoutParams(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (params <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">instanceof</span> PercentLayoutParams) { PercentLayoutInfo info = ((PercentLayoutParams) params).getPercentLayoutInfo(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"using "</span> + info); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (info != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">null</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (params <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">instanceof</span> ViewGroup.MarginLayoutParams) { info.fillMarginLayoutParams((ViewGroup.MarginLayoutParams) params, widthHint, heightHint); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">else</span> { info.fillLayoutParams(params, widthHint, heightHint); } } } } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li><li style="box-sizing: border-box; padding: 0px 5px; ">6</li><li style="box-sizing: border-box; padding: 0px 5px; ">7</li><li style="box-sizing: border-box; padding: 0px 5px; ">8</li><li style="box-sizing: border-box; padding: 0px 5px; ">9</li><li style="box-sizing: border-box; padding: 0px 5px; ">10</li><li style="box-sizing: border-box; padding: 0px 5px; ">11</li><li style="box-sizing: border-box; padding: 0px 5px; ">12</li><li style="box-sizing: border-box; padding: 0px 5px; ">13</li><li style="box-sizing: border-box; padding: 0px 5px; ">14</li><li style="box-sizing: border-box; padding: 0px 5px; ">15</li><li style="box-sizing: border-box; padding: 0px 5px; ">16</li><li style="box-sizing: border-box; padding: 0px 5px; ">17</li><li style="box-sizing: border-box; padding: 0px 5px; ">18</li><li style="box-sizing: border-box; padding: 0px 5px; ">19</li><li style="box-sizing: border-box; padding: 0px 5px; ">20</li><li style="box-sizing: border-box; padding: 0px 5px; ">21</li><li style="box-sizing: border-box; padding: 0px 5px; ">22</li><li style="box-sizing: border-box; padding: 0px 5px; ">23</li><li style="box-sizing: border-box; padding: 0px 5px; ">24</li><li style="box-sizing: border-box; padding: 0px 5px; ">25</li><li style="box-sizing: border-box; padding: 0px 5px; ">26</li><li style="box-sizing: border-box; padding: 0px 5px; ">27</li><li style="box-sizing: border-box; padding: 0px 5px; ">28</li><li style="box-sizing: border-box; padding: 0px 5px; ">29</li><li style="box-sizing: border-box; padding: 0px 5px; ">30</li><li style="box-sizing: border-box; padding: 0px 5px; ">31</li><li style="box-sizing: border-box; padding: 0px 5px; ">32</li></ul>
通过注释也能看出,此方法中遍历所有的孩子,通过百分比的属性重新设置其宽度和高度。
首先在widthHint、heightHint保存容器的宽、高,然后遍历所有的孩子,判断其LayoutParams是否是PercentLayoutParams类型,如果是,通过params.getPercentLayoutInfo拿出info对象。
是否还记得,上面的分析中,PercentLayoutInfo保存了percent相关属性的值。
如果info不为null,则判断是否需要处理margin;我们直接看fillLayoutParams方法(处理margin也是类似的)。
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "> <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box; ">/** * Fills {@code ViewGroup.LayoutParams} dimensions based on percentage values. */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">void</span> <span class="hljs-title" style="box-sizing: border-box; ">fillLayoutParams</span>(ViewGroup.LayoutParams params, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> widthHint, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> heightHint) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box; ">// Preserve the original layout params, so we can restore them after the measure step.</span> mPreservedParams.width = params.width; mPreservedParams.height = params.height; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (widthPercent >= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">0</span>) { params.width = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span>) (widthHint * widthPercent); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (heightPercent >= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">0</span>) { params.height = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span>) (heightHint * heightPercent); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"after fillLayoutParams: ("</span> + params.width + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">", "</span> + params.height + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">")"</span>); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li><li style="box-sizing: border-box; padding: 0px 5px; ">6</li><li style="box-sizing: border-box; padding: 0px 5px; ">7</li><li style="box-sizing: border-box; padding: 0px 5px; ">8</li><li style="box-sizing: border-box; padding: 0px 5px; ">9</li><li style="box-sizing: border-box; padding: 0px 5px; ">10</li><li style="box-sizing: border-box; padding: 0px 5px; ">11</li><li style="box-sizing: border-box; padding: 0px 5px; ">12</li><li style="box-sizing: border-box; padding: 0px 5px; ">13</li><li style="box-sizing: border-box; padding: 0px 5px; ">14</li><li style="box-sizing: border-box; padding: 0px 5px; ">15</li><li style="box-sizing: border-box; padding: 0px 5px; ">16</li><li style="box-sizing: border-box; padding: 0px 5px; ">17</li><li style="box-sizing: border-box; padding: 0px 5px; ">18</li><li style="box-sizing: border-box; padding: 0px 5px; ">19</li></ul>
首先保存原本的width和height,然后重置params的width和height为(int) (widthHint * widthPercent)
和(int) (heightHint * heightPercent);
。
到此,其实我们的百分比转换就结束了,理论上就已经实现了对于百分比的支持,不过Google还考虑了一些细节。
我们回到onMeasure方法:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; ">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">void</span> <span class="hljs-title" style="box-sizing: border-box; ">onMeasure</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> widthMeasureSpec, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> heightMeasureSpec) { mHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>.onMeasure(widthMeasureSpec, heightMeasureSpec); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (mHelper.handleMeasuredStateTooSmall()) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>.onMeasure(widthMeasureSpec, heightMeasureSpec); } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li><li style="box-sizing: border-box; padding: 0px 5px; ">6</li><li style="box-sizing: border-box; padding: 0px 5px; ">7</li><li style="box-sizing: border-box; padding: 0px 5px; ">8</li></ul>
下面还有个mHelper.handleMeasuredStateTooSmall的判断,也就是说,如果你设置的百分比,最终计算出来的MeasuredSize过小的话,会进行一些操作。
代码如下:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">boolean</span> <span class="hljs-title" style="box-sizing: border-box; ">handleMeasuredStateTooSmall</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">boolean</span> needsSecondMeasure = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">false</span>; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">0</span>, N = mHost.getChildCount(); i < N; i++) { View view = mHost.getChildAt(i); ViewGroup.LayoutParams params = view.getLayoutParams(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"should handle measured state too small "</span> + view + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">" "</span> + params); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (params <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">instanceof</span> PercentLayoutParams) { PercentLayoutInfo info = ((PercentLayoutParams) params).getPercentLayoutInfo(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (info != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">null</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (shouldHandleMeasuredWidthTooSmall(view, info)) { needsSecondMeasure = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">true</span>; params.width = ViewGroup.LayoutParams.WRAP_CONTENT; } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (shouldHandleMeasuredHeightTooSmall(view, info)) { needsSecondMeasure = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">true</span>; params.height = ViewGroup.LayoutParams.WRAP_CONTENT; } } } } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"should trigger second measure pass: "</span> + needsSecondMeasure); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">return</span> needsSecondMeasure; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li><li style="box-sizing: border-box; padding: 0px 5px; ">6</li><li style="box-sizing: border-box; padding: 0px 5px; ">7</li><li style="box-sizing: border-box; padding: 0px 5px; ">8</li><li style="box-sizing: border-box; padding: 0px 5px; ">9</li><li style="box-sizing: border-box; padding: 0px 5px; ">10</li><li style="box-sizing: border-box; padding: 0px 5px; ">11</li><li style="box-sizing: border-box; padding: 0px 5px; ">12</li><li style="box-sizing: border-box; padding: 0px 5px; ">13</li><li style="box-sizing: border-box; padding: 0px 5px; ">14</li><li style="box-sizing: border-box; padding: 0px 5px; ">15</li><li style="box-sizing: border-box; padding: 0px 5px; ">16</li><li style="box-sizing: border-box; padding: 0px 5px; ">17</li><li style="box-sizing: border-box; padding: 0px 5px; ">18</li><li style="box-sizing: border-box; padding: 0px 5px; ">19</li><li style="box-sizing: border-box; padding: 0px 5px; ">20</li><li style="box-sizing: border-box; padding: 0px 5px; ">21</li><li style="box-sizing: border-box; padding: 0px 5px; ">22</li><li style="box-sizing: border-box; padding: 0px 5px; ">23</li><li style="box-sizing: border-box; padding: 0px 5px; ">24</li><li style="box-sizing: border-box; padding: 0px 5px; ">25</li><li style="box-sizing: border-box; padding: 0px 5px; ">26</li><li style="box-sizing: border-box; padding: 0px 5px; ">27</li><li style="box-sizing: border-box; padding: 0px 5px; ">28</li></ul>
首先遍历所有的孩子,拿出孩子的layoutparams,如果是PercentLayoutParams实例,则取出info。如果info不为null,调用shouldHandleMeasuredWidthTooSmall
判断:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">boolean</span> <span class="hljs-title" style="box-sizing: border-box; ">shouldHandleMeasuredWidthTooSmall</span>(View view, PercentLayoutInfo info) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> state = ViewCompat.getMeasuredWidthAndState(view) & ViewCompat.MEASURED_STATE_MASK; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">return</span> state == ViewCompat.MEASURED_STATE_TOO_SMALL && info.widthPercent >= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">0</span> && info.mPreservedParams.width == ViewGroup.LayoutParams.WRAP_CONTENT; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li></ul>
这里就是判断,如果你设置的measuredWidth或者measureHeight过小的话,并且你在布局文件中layout_w/h 设置的是WRAP_CONTENT的话,将params.width / height= ViewGroup.LayoutParams.WRAP_CONTENT,然后重新测量。
哈,onMeasure终于结束了~~~现在我觉得应该代码结束了吧,尺寸都设置好了,还需要干嘛么,but,你会发现onLayout也重写了,我们又不改变layout规则,在onLayout里面干什么毛线:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; ">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">void</span> <span class="hljs-title" style="box-sizing: border-box; ">onLayout</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">boolean</span> changed, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> left, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> top, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> right, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> bottom) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>.onLayout(changed, left, top, right, bottom); mHelper.restoreOriginalParams(); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li></ul>
继续看mHelper.restoreOriginalParams
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "> <span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box; ">/** * Iterates over children and restores their original dimensions that were changed for * percentage values. Calling this method only makes sense if you previously called * {@link PercentLayoutHelper#adjustChildren(int, int)}. */</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">void</span> <span class="hljs-title" style="box-sizing: border-box; ">restoreOriginalParams</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box; ">0</span>, N = mHost.getChildCount(); i < N; i++) { View view = mHost.getChildAt(i); ViewGroup.LayoutParams params = view.getLayoutParams(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"should restore "</span> + view + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">" "</span> + params); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (params <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">instanceof</span> PercentLayoutParams) { PercentLayoutInfo info = ((PercentLayoutParams) params).getPercentLayoutInfo(); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (Log.isLoggable(TAG, Log.DEBUG)) { Log.d(TAG, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box; ">"using "</span> + info); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (info != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">null</span>) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (params <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">instanceof</span> ViewGroup.MarginLayoutParams) { info.restoreMarginLayoutParams((ViewGroup.MarginLayoutParams) params); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">else</span> { info.restoreLayoutParams(params); } } } } }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li><li style="box-sizing: border-box; padding: 0px 5px; ">6</li><li style="box-sizing: border-box; padding: 0px 5px; ">7</li><li style="box-sizing: border-box; padding: 0px 5px; ">8</li><li style="box-sizing: border-box; padding: 0px 5px; ">9</li><li style="box-sizing: border-box; padding: 0px 5px; ">10</li><li style="box-sizing: border-box; padding: 0px 5px; ">11</li><li style="box-sizing: border-box; padding: 0px 5px; ">12</li><li style="box-sizing: border-box; padding: 0px 5px; ">13</li><li style="box-sizing: border-box; padding: 0px 5px; ">14</li><li style="box-sizing: border-box; padding: 0px 5px; ">15</li><li style="box-sizing: border-box; padding: 0px 5px; ">16</li><li style="box-sizing: border-box; padding: 0px 5px; ">17</li><li style="box-sizing: border-box; padding: 0px 5px; ">18</li><li style="box-sizing: border-box; padding: 0px 5px; ">19</li><li style="box-sizing: border-box; padding: 0px 5px; ">20</li><li style="box-sizing: border-box; padding: 0px 5px; ">21</li><li style="box-sizing: border-box; padding: 0px 5px; ">22</li><li style="box-sizing: border-box; padding: 0px 5px; ">23</li><li style="box-sizing: border-box; padding: 0px 5px; ">24</li><li style="box-sizing: border-box; padding: 0px 5px; ">25</li><li style="box-sizing: border-box; padding: 0px 5px; ">26</li><li style="box-sizing: border-box; padding: 0px 5px; ">27</li><li style="box-sizing: border-box; padding: 0px 5px; ">28</li><li style="box-sizing: border-box; padding: 0px 5px; ">29</li></ul>
噗,原来是重新恢复原本的尺寸值,也就是说onMeasure里面的对值进行了改变,测量完成后。在这个地方,将值又恢复成如果布局文件中的值,上面写的都是0。恢复很简单:
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">void</span> <span class="hljs-title" style="box-sizing: border-box; ">restoreLayoutParams</span>(ViewGroup.LayoutParams params) { params.width = mPreservedParams.width; params.height = mPreservedParams.height; }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li></ul>
你应该没有忘在哪存的把~忘了的话,麻烦Ctrl+F ‘mPreservedParams.width’ 。
也就是说,你去打印上面写法,布局文件中view的v.getLayoutParams().width
,这个值应该是0。
这里感觉略微不爽~这个0没撒用处呀,还不如不重置~~
好了,到此就分析完了,其实主要就几个步骤:
- LayoutParams中属性的获取
- onMeasure中,改变params.width为百分比计算结果,测量
- 如果测量值过小且设置的w/h是wrap_content,重新测量
- onLayout中,重置params.w/h为布局文件中编写的值
可以看到,有了RelativeLayout、FrameLayout的扩展,竟然没有LinearLayout几个意思。好在,我们的核心代码都由PercentLayoutHelper
封装了,自己扩展下LinearLayout也不复杂。
三、实现PercentLinearlayout
可能有人会说,有了weight呀,但是weight能做到宽、高同时百分比赋值嘛?
好了,代码很简单,如下:
(一)PercentLinearLayout
<code class="language-java hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">package</span> com.juliengenoud.percentsamples;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">import</span> android.content.Context;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">import</span> android.content.res.TypedArray;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">import</span> android.support.percent.PercentLayoutHelper;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">import</span> android.util.AttributeSet;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">import</span> android.view.ViewGroup;<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">import</span> android.widget.LinearLayout;<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box; ">/** * Created by zhy on 15/6/30. */</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-class" style="box-sizing: border-box; "><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">PercentLinearLayout</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">LinearLayout</span>{</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">private</span> PercentLayoutHelper mPercentLayoutHelper; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-title" style="box-sizing: border-box; ">PercentLinearLayout</span>(Context context, AttributeSet attrs) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>(context, attrs); mPercentLayoutHelper = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">new</span> PercentLayoutHelper(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">this</span>); } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; ">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">void</span> <span class="hljs-title" style="box-sizing: border-box; ">onMeasure</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> widthMeasureSpec, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> heightMeasureSpec) { mPercentLayoutHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>.onMeasure(widthMeasureSpec, heightMeasureSpec); <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">if</span> (mPercentLayoutHelper.handleMeasuredStateTooSmall()) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>.onMeasure(widthMeasureSpec, heightMeasureSpec); } } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; ">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">void</span> <span class="hljs-title" style="box-sizing: border-box; ">onLayout</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">boolean</span> changed, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> l, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> t, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> r, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> b) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>.onLayout(changed, l, t, r, b); mPercentLayoutHelper.restoreOriginalParams(); } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; ">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> LayoutParams <span class="hljs-title" style="box-sizing: border-box; ">generateLayoutParams</span>(AttributeSet attrs) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">new</span> LayoutParams(getContext(), attrs); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">static</span> <span class="hljs-class" style="box-sizing: border-box; "><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">LayoutParams</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">extends</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">LinearLayout</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">LayoutParams</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">implements</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">PercentLayoutHelper</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102); ">PercentLayoutParams</span> {</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">private</span> PercentLayoutHelper.PercentLayoutInfo mPercentLayoutInfo; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-title" style="box-sizing: border-box; ">LayoutParams</span>(Context c, AttributeSet attrs) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>(c, attrs); mPercentLayoutInfo = PercentLayoutHelper.getPercentLayoutInfo(c, attrs); } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; ">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> PercentLayoutHelper.PercentLayoutInfo <span class="hljs-title" style="box-sizing: border-box; ">getPercentLayoutInfo</span>() { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">return</span> mPercentLayoutInfo; } <span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box; ">@Override</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">void</span> <span class="hljs-title" style="box-sizing: border-box; ">setBaseAttributes</span>(TypedArray a, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> widthAttr, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> heightAttr) { PercentLayoutHelper.fetchWidthAndHeight(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">this</span>, a, widthAttr, heightAttr); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-title" style="box-sizing: border-box; ">LayoutParams</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> width, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">int</span> height) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>(width, height); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-title" style="box-sizing: border-box; ">LayoutParams</span>(ViewGroup.LayoutParams source) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>(source); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">public</span> <span class="hljs-title" style="box-sizing: border-box; ">LayoutParams</span>(MarginLayoutParams source) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box; ">super</span>(source); } }}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li><li style="box-sizing: border-box; padding: 0px 5px; ">6</li><li style="box-sizing: border-box; padding: 0px 5px; ">7</li><li style="box-sizing: border-box; padding: 0px 5px; ">8</li><li style="box-sizing: border-box; padding: 0px 5px; ">9</li><li style="box-sizing: border-box; padding: 0px 5px; ">10</li><li style="box-sizing: border-box; padding: 0px 5px; ">11</li><li style="box-sizing: border-box; padding: 0px 5px; ">12</li><li style="box-sizing: border-box; padding: 0px 5px; ">13</li><li style="box-sizing: border-box; padding: 0px 5px; ">14</li><li style="box-sizing: border-box; padding: 0px 5px; ">15</li><li style="box-sizing: border-box; padding: 0px 5px; ">16</li><li style="box-sizing: border-box; padding: 0px 5px; ">17</li><li style="box-sizing: border-box; padding: 0px 5px; ">18</li><li style="box-sizing: border-box; padding: 0px 5px; ">19</li><li style="box-sizing: border-box; padding: 0px 5px; ">20</li><li style="box-sizing: border-box; padding: 0px 5px; ">21</li><li style="box-sizing: border-box; padding: 0px 5px; ">22</li><li style="box-sizing: border-box; padding: 0px 5px; ">23</li><li style="box-sizing: border-box; padding: 0px 5px; ">24</li><li style="box-sizing: border-box; padding: 0px 5px; ">25</li><li style="box-sizing: border-box; padding: 0px 5px; ">26</li><li style="box-sizing: border-box; padding: 0px 5px; ">27</li><li style="box-sizing: border-box; padding: 0px 5px; ">28</li><li style="box-sizing: border-box; padding: 0px 5px; ">29</li><li style="box-sizing: border-box; padding: 0px 5px; ">30</li><li style="box-sizing: border-box; padding: 0px 5px; ">31</li><li style="box-sizing: border-box; padding: 0px 5px; ">32</li><li style="box-sizing: border-box; padding: 0px 5px; ">33</li><li style="box-sizing: border-box; padding: 0px 5px; ">34</li><li style="box-sizing: border-box; padding: 0px 5px; ">35</li><li style="box-sizing: border-box; padding: 0px 5px; ">36</li><li style="box-sizing: border-box; padding: 0px 5px; ">37</li><li style="box-sizing: border-box; padding: 0px 5px; ">38</li><li style="box-sizing: border-box; padding: 0px 5px; ">39</li><li style="box-sizing: border-box; padding: 0px 5px; ">40</li><li style="box-sizing: border-box; padding: 0px 5px; ">41</li><li style="box-sizing: border-box; padding: 0px 5px; ">42</li><li style="box-sizing: border-box; padding: 0px 5px; ">43</li><li style="box-sizing: border-box; padding: 0px 5px; ">44</li><li style="box-sizing: border-box; padding: 0px 5px; ">45</li><li style="box-sizing: border-box; padding: 0px 5px; ">46</li><li style="box-sizing: border-box; padding: 0px 5px; ">47</li><li style="box-sizing: border-box; padding: 0px 5px; ">48</li><li style="box-sizing: border-box; padding: 0px 5px; ">49</li><li style="box-sizing: border-box; padding: 0px 5px; ">50</li><li style="box-sizing: border-box; padding: 0px 5px; ">51</li><li style="box-sizing: border-box; padding: 0px 5px; ">52</li><li style="box-sizing: border-box; padding: 0px 5px; ">53</li><li style="box-sizing: border-box; padding: 0px 5px; ">54</li><li style="box-sizing: border-box; padding: 0px 5px; ">55</li><li style="box-sizing: border-box; padding: 0px 5px; ">56</li><li style="box-sizing: border-box; padding: 0px 5px; ">57</li><li style="box-sizing: border-box; padding: 0px 5px; ">58</li><li style="box-sizing: border-box; padding: 0px 5px; ">59</li><li style="box-sizing: border-box; padding: 0px 5px; ">60</li><li style="box-sizing: border-box; padding: 0px 5px; ">61</li><li style="box-sizing: border-box; padding: 0px 5px; ">62</li><li style="box-sizing: border-box; padding: 0px 5px; ">63</li><li style="box-sizing: border-box; padding: 0px 5px; ">64</li><li style="box-sizing: border-box; padding: 0px 5px; ">65</li><li style="box-sizing: border-box; padding: 0px 5px; ">66</li><li style="box-sizing: border-box; padding: 0px 5px; ">67</li><li style="box-sizing: border-box; padding: 0px 5px; ">68</li><li style="box-sizing: border-box; padding: 0px 5px; ">69</li><li style="box-sizing: border-box; padding: 0px 5px; ">70</li><li style="box-sizing: border-box; padding: 0px 5px; ">71</li><li style="box-sizing: border-box; padding: 0px 5px; ">72</li><li style="box-sizing: border-box; padding: 0px 5px; ">73</li><li style="box-sizing: border-box; padding: 0px 5px; ">74</li><li style="box-sizing: border-box; padding: 0px 5px; ">75</li><li style="box-sizing: border-box; padding: 0px 5px; ">76</li><li style="box-sizing: border-box; padding: 0px 5px; ">77</li><li style="box-sizing: border-box; padding: 0px 5px; ">78</li><li style="box-sizing: border-box; padding: 0px 5px; ">79</li><li style="box-sizing: border-box; padding: 0px 5px; ">80</li><li style="box-sizing: border-box; padding: 0px 5px; ">81</li><li style="box-sizing: border-box; padding: 0px 5px; ">82</li><li style="box-sizing: border-box; padding: 0px 5px; ">83</li><li style="box-sizing: border-box; padding: 0px 5px; ">84</li><li style="box-sizing: border-box; padding: 0px 5px; ">85</li><li style="box-sizing: border-box; padding: 0px 5px; ">86</li><li style="box-sizing: border-box; padding: 0px 5px; ">87</li><li style="box-sizing: border-box; padding: 0px 5px; ">88</li><li style="box-sizing: border-box; padding: 0px 5px; ">89</li><li style="box-sizing: border-box; padding: 0px 5px; ">90</li><li style="box-sizing: border-box; padding: 0px 5px; ">91</li></ul>
如果你详细看了上面的源码分析,这个代码是不是没撒解释的了~
(二)测试布局
<code class="language-xml hljs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial; "><span class="hljs-pi" style="color: rgb(0, 102, 102); box-sizing: border-box; "><?xml version="1.0" encoding="utf-8"?></span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">com.juliengenoud.percentsamples.PercentLinearLayout</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">xmlns:app</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"http://schemas.android.com/apk/res-auto"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"match_parent"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"match_parent"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:orientation</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"vertical"</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">TextView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#ff44aacc"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"width:60%,height:5%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:textColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#ffffff"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_heightPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"5%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_marginBottomPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"5%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_widthPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"60%"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">TextView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#ff4400cc"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"center"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:textColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#ffffff"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"width:70%,height:10%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_heightPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"10%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_marginBottomPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"5%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_widthPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"70%"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">TextView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#ff44aacc"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"center"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"width:80%,height:15%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:textColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#ffffff"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_heightPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"15%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_marginBottomPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"5%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_widthPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"80%"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">TextView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#ff4400cc"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"center"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"width:90%,height:5%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:textColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#ffffff"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_heightPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"20%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_marginBottomPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"10%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_widthPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"90%"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">TextView</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"match_parent"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:layout_height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"0dp"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:background</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#ff44aacc"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:gravity</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"center"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:text</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"width:100%,height:25%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">android:textColor</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"#ffffff"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_heightPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"25%"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102); ">app:layout_marginBottomPercent</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0); ">"5%"</span> /></span><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box; "></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136); ">com.juliengenoud.percentsamples.PercentLinearLayout</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; "><li style="box-sizing: border-box; padding: 0px 5px; ">1</li><li style="box-sizing: border-box; padding: 0px 5px; ">2</li><li style="box-sizing: border-box; padding: 0px 5px; ">3</li><li style="box-sizing: border-box; padding: 0px 5px; ">4</li><li style="box-sizing: border-box; padding: 0px 5px; ">5</li><li style="box-sizing: border-box; padding: 0px 5px; ">6</li><li style="box-sizing: border-box; padding: 0px 5px; ">7</li><li style="box-sizing: border-box; padding: 0px 5px; ">8</li><li style="box-sizing: border-box; padding: 0px 5px; ">9</li><li style="box-sizing: border-box; padding: 0px 5px; ">10</li><li style="box-sizing: border-box; padding: 0px 5px; ">11</li><li style="box-sizing: border-box; padding: 0px 5px; ">12</li><li style="box-sizing: border-box; padding: 0px 5px; ">13</li><li style="box-sizing: border-box; padding: 0px 5px; ">14</li><li style="box-sizing: border-box; padding: 0px 5px; ">15</li><li style="box-sizing: border-box; padding: 0px 5px; ">16</li><li style="box-sizing: border-box; padding: 0px 5px; ">17</li><li style="box-sizing: border-box; padding: 0px 5px; ">18</li><li style="box-sizing: border-box; padding: 0px 5px; ">19</li><li style="box-sizing: border-box; padding: 0px 5px; ">20</li><li style="box-sizing: border-box; padding: 0px 5px; ">21</li><li style="box-sizing: border-box; padding: 0px 5px; ">22</li><li style="box-sizing: border-box; padding: 0px 5px; ">23</li><li style="box-sizing: border-box; padding: 0px 5px; ">24</li><li style="box-sizing: border-box; padding: 0px 5px; ">25</li><li style="box-sizing: border-box; padding: 0px 5px; ">26</li><li style="box-sizing: border-box; padding: 0px 5px; ">27</li><li style="box-sizing: border-box; padding: 0px 5px; ">28</li><li style="box-sizing: border-box; padding: 0px 5px; ">29</li><li style="box-sizing: border-box; padding: 0px 5px; ">30</li><li style="box-sizing: border-box; padding: 0px 5px; ">31</li><li style="box-sizing: border-box; padding: 0px 5px; ">32</li><li style="box-sizing: border-box; padding: 0px 5px; ">33</li><li style="box-sizing: border-box; padding: 0px 5px; ">34</li><li style="box-sizing: border-box; padding: 0px 5px; ">35</li><li style="box-sizing: border-box; padding: 0px 5px; ">36</li><li style="box-sizing: border-box; padding: 0px 5px; ">37</li><li style="box-sizing: border-box; padding: 0px 5px; ">38</li><li style="box-sizing: border-box; padding: 0px 5px; ">39</li><li style="box-sizing: border-box; padding: 0px 5px; ">40</li><li style="box-sizing: border-box; padding: 0px 5px; ">41</li><li style="box-sizing: border-box; padding: 0px 5px; ">42</li><li style="box-sizing: border-box; padding: 0px 5px; ">43</li><li style="box-sizing: border-box; padding: 0px 5px; ">44</li><li style="box-sizing: border-box; padding: 0px 5px; ">45</li><li style="box-sizing: border-box; padding: 0px 5px; ">46</li><li style="box-sizing: border-box; padding: 0px 5px; ">47</li><li style="box-sizing: border-box; padding: 0px 5px; ">48</li><li style="box-sizing: border-box; padding: 0px 5px; ">49</li><li style="box-sizing: border-box; padding: 0px 5px; ">50</li><li style="box-sizing: border-box; padding: 0px 5px; ">51</li><li style="box-sizing: border-box; padding: 0px 5px; ">52</li><li style="box-sizing: border-box; padding: 0px 5px; ">53</li><li style="box-sizing: border-box; padding: 0px 5px; ">54</li><li style="box-sizing: border-box; padding: 0px 5px; ">55</li><li style="box-sizing: border-box; padding: 0px 5px; ">56</li><li style="box-sizing: border-box; padding: 0px 5px; ">57</li><li style="box-sizing: border-box; padding: 0px 5px; ">58</li><li style="box-sizing: border-box; padding: 0px 5px; ">59</li><li style="box-sizing: border-box; padding: 0px 5px; ">60</li><li style="box-sizing: border-box; padding: 0px 5px; ">61</li><li style="box-sizing: border-box; padding: 0px 5px; ">62</li><li style="box-sizing: border-box; padding: 0px 5px; ">63</li><li style="box-sizing: border-box; padding: 0px 5px; ">64</li><li style="box-sizing: border-box; padding: 0px 5px; ">65</li><li style="box-sizing: border-box; padding: 0px 5px; ">66</li></ul>
我们纵向排列的几个TextView,分别设置宽/高都为百分比,且之间的间隔为5%p。
(三)效果图
ok,到此,我们使用、源码分析、扩展PercentLinearLayout就结束了。
添加PercentLinearLayout后的地址:点击查看
扩展下载:android-percent-support-extend 包含android studio, eclipse项目,以及上述源码。
- android 百分比layout布局
- Android Percent Layout 安卓百分比布局
- Android 支持百分比布局
- Android支持百分比布局
- Android百分比布局初探
- Android百分比布局:PercentRelativeLayout
- Android百分比布局:PercentFrameLayout
- Android 百分比布局
- Android百分比布局
- android 百分比布局
- Android 百分比布局库
- Android 百分比布局揭秘
- Android 自定义百分比布局
- Android百分比布局
- android中的百分比布局
- Android百分比布局:PercentFrameLayout
- Android百分比布局:PercentRelativeLayout
- android百分比布局
- 4. Median of Two Sorted Arrays leetcode python New season for 2016
- JS分页案例
- 控制器的创建和view的创建
- s5k5e2ya MIPI 摄像头调试
- ubuntu环境下的用户添加 - 指定用户shell
- android 百分比layout布局
- Eclipse下debug过程中修改变量的值
- WebGIS选型
- MongoDB 驱动以及分布式集群读取优先级设置
- swift学习日志—— lazy懒加载
- Java全新高大尚HTML5 bootstrap后台框架源码
- Netty4学习笔记(3)-- ServerBootstrap
- #ifndef #define 中的头文件名为什么是__xxx_h
- LeakCanary的使用及Application类的使用