android 百分比layout布局

来源:互联网 发布:人工智能概念股 编辑:程序博客网 时间:2024/05/14 16:17
http://blog.csdn.net/lmj623565791/article/details/46695347; 

本文出自:【张鸿洋的博客】

一、概述

周末游戏打得过猛,于是周天熬夜码代码,周一早上浑浑噩噩的发现android-percent-support-lib-sample这个项目,Google终于开始支持百分比的方式布局了,瞬间脉动回来,啊咧咧。对于这种历史性的时刻,不出篇博客难以表达我内心的激动。

还记得不久前,发了篇博客:Android 屏幕适配方案,这篇博客以Web页面设计引出一种适配方案,最终的目的就是可以通过百分比控制控件的大小。当然了,存在一些问题,比如:

  • 对于没有考虑到屏幕尺寸,可能会出现意外的情况;
  • apk的大小会增加;

当然了android-percent-support这个库,基本可以解决上述问题,是不是有点小激动,稍等,我们先描述下这个support-lib。

这个库提供了:

  • 两种布局供大家使用: 
    PercentRelativeLayoutPercentFrameLayout,通过名字就可以看出,这是继承自FrameLayoutRelativeLayout两个容器类;

  • 支持的属性有:

layout_widthPercentlayout_heightPercent、 
layout_marginPercentlayout_marginLeftPercent、 
layout_marginTopPercentlayout_marginRightPercent、 
layout_marginBottomPercentlayout_marginStartPercentlayout_marginEndPercent

可以看到支持宽高,以及margin。

也就是说,大家只要在开发过程中使用PercentRelativeLayoutPercentFrameLayout替换FrameLayoutRelativeLayout即可。

是不是很简单,不过貌似没有LinearLayout,有人会说LinearLayout有weight属性呀。但是,weight属性只能支持一个方向呀~~哈,没事,刚好给我们一个机会去自定义一个PercentLinearLayout

好了,本文分为3个部分:

  • PercentRelativeLayoutPercentFrameLayout的使用
  • 对上述控件源码分析
  • 自定义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项目,以及上述源码。


0 0
原创粉丝点击