├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── PercentSupportExtend.iml ├── README-orgin.md ├── README.md ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── zhy │ │ └── percentsupportextend │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ └── res │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ └── values │ ├── strings.xml │ └── styles.xml ├── backup.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── percent-support-extends-sample ├── .gitignore ├── build.gradle ├── percent-support-extends-sample.iml ├── proguard-rules.pro └── src │ ├── androidTest │ ├── androidTest.iml │ └── java │ │ └── com │ │ └── imooc │ │ └── android_percent_support │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── gen │ └── com │ │ └── imooc │ │ └── android_percent_support │ │ ├── BuildConfig.java │ │ ├── Manifest.java │ │ └── R.java │ ├── java │ └── com │ │ └── imooc │ │ └── android_percent_support │ │ ├── ItemActivity.java │ │ ├── ListViewTestActivity.java │ │ └── MainActivity.java │ ├── main.iml │ └── res │ ├── drawable-hdpi │ └── tangyan.jpeg │ ├── layout │ ├── activity_category.xml │ ├── activity_item.xml │ ├── activity_list_view_test.xml │ ├── activity_main.xml │ ├── item_category.xml │ ├── item_music_list.xml │ ├── percent_sc_sw.xml │ ├── view1.xml │ ├── view2.xml │ ├── view3.xml │ ├── view4.xml │ ├── view5.xml │ ├── view6.xml │ └── view7_padding.xml │ ├── menu │ ├── menu_item.xml │ ├── menu_list_view_test.xml │ └── menu_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── attrs.xml │ ├── dimens.xml │ ├── percent.xml │ ├── strings.xml │ └── styles.xml ├── percent-support-extends ├── .gitignore ├── build.gradle ├── percent-support-extends.iml ├── proguard-rules.pro └── src │ ├── androidTest │ ├── androidTest1.iml │ └── java │ │ └── com │ │ └── zhy │ │ └── android │ │ └── percent │ │ └── support │ │ └── ApplicationTest.java │ └── main │ ├── AndroidManifest.xml │ ├── gen │ └── com │ │ └── zhy │ │ └── android │ │ └── percent │ │ └── support │ │ ├── BuildConfig.java │ │ ├── Manifest.java │ │ └── R.java │ ├── java │ └── com │ │ └── zhy │ │ └── android │ │ └── percent │ │ └── support │ │ ├── PercentFrameLayout.java │ │ ├── PercentLayoutHelper.java │ │ ├── PercentLinearLayout.java │ │ └── PercentRelativeLayout.java │ ├── main1.iml │ └── res │ └── values │ ├── attrs.xml │ └── strings.xml ├── percent_04.gif ├── percent_sw_sh.png ├── percent_sw_sh_single.png ├── sc_02.png ├── sc_02_full.png ├── sc_03.png ├── sc_03_full.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /local.properties 3 | /.idea/workspace.xml 4 | /.idea/libraries 5 | .DS_Store 6 | /build 7 | /captures 8 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | PercentSupportExtend -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 20 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | 1.7 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /PercentSupportExtend.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /README-orgin.md: -------------------------------------------------------------------------------- 1 | Android Percent Support Lib Sample :triangular_ruler::triangular_ruler::triangular_ruler: 2 | =================================== 3 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-android--percent--support--lib--sample-green.svg?style=flat)](https://android-arsenal.com/details/3/2054) 4 | 5 | I made a sample of the new percent support library.
6 | It will be documented soon on android dev website so it's just a proof of concept :)
7 | You can check official docs reference [here](https://juliengenoud.github.io/android-percent-support-lib-sample/) 8 | 9 | This library provide percentage based layouts, 10 | horizontal and vertical at the same time. 11 | 12 | ## simple result 13 | ![PercentRelativeLayout](https://cloud.githubusercontent.com/assets/1808854/8392086/dd20ee1e-1cdd-11e5-852e-795a0d00cc89.png) 14 | ## complex result 15 | ![PercentRelativeLayout Complex](https://cloud.githubusercontent.com/assets/1808854/8398283/22bd374c-1de8-11e5-9e74-f19ea46b8086.png) 16 |
from https://gist.github.com/shekarshine/5458f697c02e5619b0e2 17 | 18 | 19 | 20 | 21 | 22 | ### How to use : 23 | just add percent support library to your project 24 | ```xml 25 | dependencies { 26 | compile 'com.android.support:percent:22.2.0' 27 | } 28 | ``` 29 | 30 | ###Supported Layouts : 31 | 32 | ####PercentRelativeLayout 33 | ```xml 34 | 39 | 40 | 48 | 49 | 58 | 59 | 60 | 67 | 68 | ``` 69 | 70 | ####PercentFrameLayout 71 | ```xml 72 | 77 | 78 | 79 | ``` 80 | 81 | ###Stylable : 82 | 83 | - heightPercent 84 | - widthPercent 85 | - marginBottomPercent 86 | - marginEndPercent 87 | - marginLeftPercent 88 | - marginPercent 89 | - marginRightPercent 90 | - marginStartPercent 91 | - marginTopPercent 92 | 93 | Pre-requisites 94 | -------------- 95 | 96 | - Android SDK v22 97 | - Android Build Tools v22.0.1 98 | - Android Percent Support Repository v22.2.0 99 | - Android Support v4 Repository v22.2.0 100 | 101 | according to the the manifest minsdk is v7 (android 2.1) 102 | 103 | ####License Mit 104 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # android-percent-support-extend 2 | 3 | >对于android-percent-support的扩展库。 4 | 5 | 目前支持: 6 | 7 | 1. 不改变原有库的用法 8 | 2. 添加了`PercentLinearLayout ` 9 | 3. 支持宽度高度百分比设置值 10 | 4. 支持margin百分比设置值 11 | 5. 支持padding百分比设置值 12 | 6. 支持minWidth , maxWidth , minHeight , maxHeight百分比设置值 13 | 7. 支持TextView、Button、EditText的textSize 14 | 8. 支持ScrollView内部为Linearlayout 15 | 9. 支持任何View的尺寸参照屏幕的宽或者高 16 | 17 | 目前最新版本为,尽可能使用最新版本,源码和demo在github中: 18 | 19 | ```xml 20 | compile 'com.zhy:percent-support-extends:1.1.1' 21 | ``` 22 | 23 | ## 一 扩展的功能 24 | 25 | 26 | 对于官方库,做了如下的改变: 27 | 28 | 1. 不改变原有库的用法 29 | 2. 添加了`PercentLinearLayout ` 30 | 3. 支持百分比指定特定的参考值,比如宽度或者高度。 31 | 32 | 例如: 33 | 34 | ```xml 35 | app:layout_heightPercent="50%w" 36 | app:layout_marginPercent="15%w" 37 | app:layout_marginBottomPercent="20%h" 38 | ``` 39 | 4. 支持通过app:layout_textSizePercent设置textView(button,editText)的textSize 40 | 41 | 例如: 42 | 43 | ```xml 44 | 47 | ``` 48 | 49 | 5. 对于外层套ScrollView的问题,目前可以在`PercentLinearLayout `的外层使用ScrollView,不过对于宽度的百分比参考的就是android.R.id.content的高度(因为,无法参考父控件的高度,父控件的高度理论上依赖于子View高度,且模式为UNSPECIFIED)。 50 | 6. 支持minWidth,maxWidth,minHeight,maxHeight的支持。 51 | 52 | 例如: 53 | 54 | ```xml 55 | app:layout_maxWidthPercent 56 | app:layout_maxHeightPercent 57 | app:layout_minWidthPercent 58 | app:layout_minWidthPercent 59 | ``` 60 | (注:用法和maxHeight等一致,如果使用:值会覆盖原本的maxHeight等属性)。 61 | 7. 支持padding百分比设置值 62 | 63 | 例如: 64 | 65 | ```xml 66 | app:layout_paddingBottomPercent="8%w" 67 | app:layout_paddingLeftPercent="2%w" 68 | app:layout_paddingRightPercent="4%w" 69 | app:layout_paddingTopPercent="6%w" 70 | ``` 71 | 8. 支持任何尺寸参考屏幕的宽或者高 72 | 73 | ```xml 74 | 78 | ``` 79 | 80 | 81 | 82 | ## 二 为什么要扩展这个库 83 | 84 | 首先我们回顾下百分比布局库的用法,提供了`PercentRelativeLayout`、`PercentFrameLayout`供大家在编写的时候,对于以下属性: 85 | 86 | `layout_widthPercent`、`layout_heightPercent`、 87 | `layout_marginPercent`、`layout_marginLeftPercent`、 88 | `layout_marginTopPercent`、`layout_marginRightPercent`、 89 | `layout_marginBottomPercent`、`layout_marginStartPercent`、`layout_marginEndPercent`。 90 | 91 | 可以使用百分比进行设置宽、高、边距,的确给我们在适配上提供了极大的便利,但是在使用过程中,觉得存在一些场景无法得到满足。什么场景呢?下面我举几个例子。 92 | 93 | 1. 当使用图片时,无法设置宽高的比例 94 | 95 | 比如我们的图片宽高是200*100的,我们在使用过程中我们设置宽高为20%、10%,这样会造成图片的比例失调。为什么呢?因为20%参考的是屏幕的宽度,而10%参考的是屏幕的高度。 96 | 97 | 2. 很难使用百分比定义一个正方形的控件 98 | 99 | 比如,我现在界面的右下角有一个`FloatingActionButton `,我希望其宽度和高度都为屏幕宽度的10%,很难做到。 100 | 101 | 3. 一个控件的margin四个方向值一致 102 | 103 | 有些时候,我设置margin,我希望四边的边距一致的,但是如果目前设置5%,会造成,上下为高度的5%,左右边距为宽度的5%。 104 | 105 | 综合上述这些问题,可以发现目前的percent-support-lib并不能完全满足我们的需求,所以我们考虑对其进行扩展。说白了,我们就希望在布局的时候可以自己设定参考看度还是高度,比如上述2,我们对于宽高可以写成10%w,10%w。也就是在不改变原库的用法的前提下,添加一些额外的支持。 106 | 107 | 108 | 109 | 110 | 111 | ## 三 用法 112 | 113 | ### Android Studio 114 | 115 | 对于如何导入,也是相当的简单,android studio的用户,直接: 116 | 117 | ```xml 118 | dependencies { 119 | //... 120 | compile 'com.zhy:percent-support-extends:1.0.7' 121 | } 122 | 123 | ``` 124 | 不需要导入官方的percent-support-lib了。 125 | 126 | 对于的三个类分别为: 127 | 128 | ```xml 129 | com.zhy.android.percent.support.PercentLinearLayout 130 | com.zhy.android.percent.support.PercentRelativeLayout 131 | com.zhy.android.percent.support.PercentFrameLayout 132 | ``` 133 | 134 | ###支持的属性 : 135 | 136 | - layout_heightPercent 137 | - layout_widthPercent 138 | - layout_marginBottomPercent 139 | - layout_marginEndPercent 140 | - layout_marginLeftPercent 141 | - layout_marginPercent 142 | - layout_marginRightPercent 143 | - layout_marginStartPercent 144 | - layout_marginTopPercent 145 | - layout_textSizePercent 146 | - layout_maxWidthPercent 147 | - layout_maxHeightPercent 148 | - layout_minWidthPercent 149 | - layout_minHeightPercent 150 | - layout_paddingPercent 151 | - layout_paddingTopPercent 152 | - layout_paddingBottomPercent 153 | - layout_paddingLeftPercent 154 | - layout_paddingRightPercent 155 | 156 | 对于值可以取:10%w , 10%h , 10% , 10%sw , 10%sh 157 | 158 | 159 | 160 | 161 | 162 | ## 四 具体的示例 163 | 164 | #### Demo 1 [基本用法,主要测试w,h后缀] 165 | 166 | 167 | 168 | 169 | 170 | xml: 171 | 172 | ```xml 173 | 174 | 175 | 176 | 182 | 183 | 190 | 191 | 198 | 199 | 208 | 209 | 210 | 211 | 212 | 213 | 222 | 223 | 224 | 225 | 226 | ``` 227 | 228 | #### Demo 2 [基本用法,主要测试w,h后缀] 229 | 230 | 231 | 232 | 233 | 234 | 235 | xml: 236 | 237 | ```xml 238 | 239 | 244 | 245 | 256 | 257 | 266 | 267 | 268 | 277 | 278 | 279 | 287 | 288 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | ``` 306 | 307 | ok,例子都比较简单,主要就一个布局文件,可以看出上述我们可以给宽度、高度,边距等指定参考值为宽度或者高度。这样的话,在保证图片宽、高比例、控件设置为正方形等需求就没问题了。 308 | 309 |
310 | 311 | 接下来还有个例子,功能主要是设置TextView对于textSize的百分比设置;以及对于ScrollView的支持。当然了,对于ScrollView的支持,这个理论上是不支持的,因为大家都清楚,如果`PercentLinearLayout`在ScrollView中,那么高度的模式肯定是`UNSPECIFIED`,那么理论上来说高度是无限制的,也就是依赖于子View的高度,而百分比布局的高度是依赖于父View的高度的,所有是互斥的。而我们支持是:考虑到编写代码的时候,大多参考的是屏幕高度(android.R.id.content)的高度,所以如果在ScrollView中,编写10%h,这个百分比是依赖于屏幕高度的(不包括ActionBar的高度)。 312 | 313 | #### Demo 3 [测试textSize、ScrollView] 314 | 315 | 316 | 317 | xml: 318 | 319 | ```xml 320 | 321 | 322 | 327 | 333 | 334 | 345 | 346 | 356 | 367 | 377 | 378 | 388 | 389 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | ``` 406 | 407 | 上面的第三个TextView的字体设置的就是5%(默认参考容器高度)。整个PercentLinearLayout在ScrollView中。ok~ 姑且这样,由于源码比较简单,大家可以根据自己的实际需求去修改,前提尽可能不要改变原有的功能。 408 | 409 | #### Demo 4 [参照屏幕的宽或者高进行布局] 410 | 411 | > thx for Sunday~ 412 | 413 | 414 | 415 | 416 | 417 | ```xml 418 | 419 | 424 | 425 | 436 | 437 | 446 | 447 | 448 | 457 | 458 | 459 | 467 | 468 | 479 | 480 | 481 | 482 | 483 | ``` 484 | 485 | 486 | ## About me 487 | 488 | * [博客](http://blog.csdn.net/lmj623565791) 489 | * [新浪微博](http://weibo.com/u/3165018720) 490 | * email: 623565791@qq.com 491 | * >微信公众号:hongyangAndroid 492 | (欢迎关注,第一时间推送博文信息) 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 |
501 | 502 | ==> 接下来是原库的用法: 503 | 504 | 505 | 506 | Android Percent Support Lib Sample :triangular_ruler::triangular_ruler::triangular_ruler: 507 | =================================== 508 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-android--percent--support--lib--sample-green.svg?style=flat)](https://android-arsenal.com/details/3/2054) 509 | 510 | I made a sample of the new percent support library.
511 | It will be documented soon on android dev website so it's just a proof of concept :)
512 | You can check official docs reference [here](https://juliengenoud.github.io/android-percent-support-lib-sample/) 513 | 514 | This library provide percentage based layouts, 515 | horizontal and vertical at the same time. 516 | 517 | ## simple result 518 | ![PercentRelativeLayout](https://cloud.githubusercontent.com/assets/1808854/8392086/dd20ee1e-1cdd-11e5-852e-795a0d00cc89.png) 519 | ## complex result 520 | ![PercentRelativeLayout Complex](https://cloud.githubusercontent.com/assets/1808854/8398283/22bd374c-1de8-11e5-9e74-f19ea46b8086.png) 521 |
from https://gist.github.com/shekarshine/5458f697c02e5619b0e2 522 | 523 | 524 | 525 | 526 | 527 | ### How to use : 528 | just add percent support library to your project 529 | ```xml 530 | dependencies { 531 | compile 'com.android.support:percent:22.2.0' 532 | } 533 | ``` 534 | 535 | ###Supported Layouts : 536 | 537 | ####PercentRelativeLayout 538 | ```xml 539 | 544 | 545 | 553 | 554 | 563 | 564 | 565 | 572 | 573 | ``` 574 | 575 | ####PercentFrameLayout 576 | ```xml 577 | 582 | 583 | 584 | ``` 585 | 586 | ###Stylable : 587 | 588 | - heightPercent 589 | - widthPercent 590 | - marginBottomPercent 591 | - marginEndPercent 592 | - marginLeftPercent 593 | - marginPercent 594 | - marginRightPercent 595 | - marginStartPercent 596 | - marginTopPercent 597 | 598 | Pre-requisites 599 | -------------- 600 | 601 | - Android SDK v22 602 | - Android Build Tools v22.0.1 603 | - Android Percent Support Repository v22.2.0 604 | - Android Support v4 Repository v22.2.0 605 | 606 | according to the the manifest minsdk is v7 (android 2.1) 607 | 608 | ####License Mit 609 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 21 5 | buildToolsVersion "23.0.0 rc3" 6 | 7 | defaultConfig { 8 | applicationId "com.zhy.percentsupportextend" 9 | minSdkVersion 10 10 | targetSdkVersion 21 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | compile 'com.android.support:appcompat-v7:22.2.1' 25 | } 26 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/zhy/android/sdk/android-sdk-macosx/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/zhy/percentsupportextend/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.zhy.percentsupportextend; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase 10 | { 11 | public ApplicationTest() 12 | { 13 | super(Application.class); 14 | } 15 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | PercentSupportExtend 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /backup.md: -------------------------------------------------------------------------------- 1 | # android-percent-support-extend 2 | >a extends lib for android-percent-support 3 | > 4 | >对于android-percent-support的扩展库。 5 | 6 | contains project for android studio and eclipse . 7 | 8 | 上面包含as和ec的项目,自行导入。 9 | 10 | * support for android-percent-support's orgin abilities 11 | * 支持该库的原有功能,且用法不变 12 | * add PercentLinearLayout 13 | * 添加了PercentLinearLayout 14 | * support for all attrs use fraction value based on specified width or height. 15 | * 支持百分比指定特定的参考值,比如宽度或者高度。 16 | * support for use app:layout_textSizePercent for textSize of textView 17 | 18 | >such as `app:layout_heightPercent="50%w"`, 19 | `app:layout_marginPercent="15%w"`, 20 | `app:layout_marginBottomPercent="20%h"`. 21 | * 支持通过app:layout_textSizePercent设置textView的textSize 22 | 23 | 24 | 25 | 26 | 27 | we not only support fraction value , but also we support use fraction value based on width or height , such as 10% , 10%w , 10%h 。 28 | 29 | 不仅支持百分比设置布局的值,并且可以指定百分比参考的是宽度还是高度。如果不指定宽度和高度,则默认和原本的库效果一致。 30 | 31 | Why I Why extend this library ? 32 | 33 | 为什么要扩展你这个库? 34 | 35 | Because , there are some views in my layout are square , such as FloatingActionButton , i wanna its' width and height both are 15% of width , since I add this ability , so that I can define as below : 36 | 37 | 因为,在我的布局中有部分View是正方形的大小,比如FloatingActionButton,我希望它的高度和宽度都是宽度的15%,因此我添加了该功能,以至于我可以按照下面的写法编写: 38 | 39 | ``` 40 | 47 | 48 | 57 | 58 | 59 | ``` 60 | 61 | also , I wanna View has same margin for all direction , if we use 5% , leftMargin and rightMagin are width'5% , topMargin and bottonMargin are height'5% . In this library , you can use : `app:layout_marginPercent="5%w"`. 62 | 63 | 有时候,我希望View的margin在4个方向的值是一致的,如果使用原本的库,5%会造成横向与纵向的值不一致。而根据添加的功能,你可以使用:`app:layout_marginPercent="5%w"`。 64 | 65 | 66 | ## How to use 67 | 68 | 对于Android Studio,只需要添加: 69 | 70 | ```xml 71 | compile 'com.zhy:percent-support-extends:1.0' 72 | ``` 73 | 74 | 就可以使用,所有的类名为,源码的话,大家直接下载这个库即可: 75 | 76 | ```java 77 | com.zhy.android.percent.support.PercentLinearLayout 78 | com.zhy.android.percent.support.PercentRelativeLayout 79 | com.zhy.android.percent.support.PercentFrameLayout 80 | ``` 81 | 82 | 83 | 84 | ##Some Example 85 | 86 | 87 | 88 | xml: 89 | 90 | ```xml 91 | 92 | 93 | 94 | 100 | 101 | 110 | 111 | 121 | 131 | 141 | 142 | 152 | 153 | 154 | 155 | 156 | ``` 157 | 158 | 159 | 160 | xml: 161 | 162 | ```xml 163 | 164 | 165 | 166 | 172 | 173 | 180 | 181 | 188 | 189 | 198 | 199 | 200 | 201 | 202 | 203 | 212 | 213 | 214 | 215 | 216 | 217 | ``` 218 | 219 | 220 | 221 | xml: 222 | 223 | ```xml 224 | 225 | 230 | 231 | 242 | 243 | 252 | 253 | 254 | 263 | 264 | 265 | 273 | 274 | 285 | 286 | 287 | 288 | 289 | ``` 290 | 291 | 292 | 293 | ## About me 294 | 295 | * [my blog](http://blog.csdn.net/lmj623565791) 296 | 297 | 298 | 299 | 300 | 301 | 302 |
303 |
304 | 305 | Here is the Readme of Android Percent Support Lib Sample : 306 | 307 | 308 | Android Percent Support Lib Sample :triangular_ruler::triangular_ruler::triangular_ruler: 309 | =================================== 310 | [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-android--percent--support--lib--sample-green.svg?style=flat)](https://android-arsenal.com/details/3/2054) 311 | 312 | I made a sample of the new percent support library.
313 | It will be documented soon on android dev website so it's just a proof of concept :)
314 | You can check official docs reference [here](https://juliengenoud.github.io/android-percent-support-lib-sample/) 315 | 316 | This library provide percentage based layouts, 317 | horizontal and vertical at the same time. 318 | 319 | ## simple result 320 | ![PercentRelativeLayout](https://cloud.githubusercontent.com/assets/1808854/8392086/dd20ee1e-1cdd-11e5-852e-795a0d00cc89.png) 321 | ## complex result 322 | ![PercentRelativeLayout Complex](https://cloud.githubusercontent.com/assets/1808854/8398283/22bd374c-1de8-11e5-9e74-f19ea46b8086.png) 323 |
from https://gist.github.com/shekarshine/5458f697c02e5619b0e2 324 | 325 | 326 | 327 | 328 | 329 | ### How to use : 330 | just add percent support library to your project 331 | ```xml 332 | dependencies { 333 | compile 'com.android.support:percent:22.2.0' 334 | } 335 | ``` 336 | 337 | ###Supported Layouts : 338 | 339 | ####PercentRelativeLayout 340 | ```xml 341 | 346 | 347 | 355 | 356 | 365 | 366 | 367 | 374 | 375 | ``` 376 | 377 | ####PercentFrameLayout 378 | ```xml 379 | 384 | 385 | 386 | ``` 387 | 388 | ###Stylable : 389 | 390 | - heightPercent 391 | - widthPercent 392 | - marginBottomPercent 393 | - marginEndPercent 394 | - marginLeftPercent 395 | - marginPercent 396 | - marginRightPercent 397 | - marginStartPercent 398 | - marginTopPercent 399 | 400 | Pre-requisites 401 | -------------- 402 | 403 | - Android SDK v22 404 | - Android Build Tools v22.0.1 405 | - Android Percent Support Repository v22.2.0 406 | - Android Support v4 Repository v22.2.0 407 | 408 | according to the the manifest minsdk is v7 (android 2.1) 409 | 410 | ####License Mit 411 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:1.2.3' 9 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0' 10 | classpath 'com.github.dcendents:android-maven-plugin:1.2' 11 | 12 | // NOTE: Do not place your application dependencies here; they belong 13 | // in the individual module build.gradle files 14 | } 15 | } 16 | 17 | allprojects { 18 | repositories { 19 | jcenter() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Sep 30 16:58:23 GMT+08:00 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /percent-support-extends-sample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /percent-support-extends-sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 22 5 | buildToolsVersion "22.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.imooc.android_percent_support" 9 | minSdkVersion 7 10 | targetSdkVersion 22 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | compile 'com.android.support:appcompat-v7:22.2.0' 25 | compile 'com.android.support:support-v4:22.2.0' 26 | compile project(':percent-support-extends') 27 | } 28 | -------------------------------------------------------------------------------- /percent-support-extends-sample/percent-support-extends-sample.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /percent-support-extends-sample/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/zhy/android/sdk/android-sdk-macosx/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/androidTest/androidTest.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/androidTest/java/com/imooc/android_percent_support/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.imooc.android_percent_support; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase 10 | { 11 | public ApplicationTest() 12 | { 13 | super(Application.class); 14 | } 15 | } -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/gen/com/imooc/android_percent_support/BuildConfig.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.imooc.android_percent_support; 4 | 5 | /* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */ 6 | public final class BuildConfig { 7 | public final static boolean DEBUG = Boolean.parseBoolean(null); 8 | } -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/gen/com/imooc/android_percent_support/Manifest.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.imooc.android_percent_support; 4 | 5 | /* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */ 6 | public final class Manifest { 7 | } -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/gen/com/imooc/android_percent_support/R.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.imooc.android_percent_support; 4 | 5 | /* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */ 6 | public final class R { 7 | } -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/java/com/imooc/android_percent_support/ItemActivity.java: -------------------------------------------------------------------------------- 1 | package com.imooc.android_percent_support; 2 | 3 | import android.support.v7.app.ActionBarActivity; 4 | import android.os.Bundle; 5 | import android.view.Menu; 6 | import android.view.MenuItem; 7 | 8 | 9 | public class ItemActivity extends ActionBarActivity 10 | { 11 | 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) 14 | { 15 | super.onCreate(savedInstanceState); 16 | setContentView(getIntent().getIntExtra("contentId", R.layout.activity_item)); 17 | 18 | setTitle(getIntent().getStringExtra("title")); 19 | 20 | } 21 | 22 | @Override 23 | public boolean onCreateOptionsMenu(Menu menu) 24 | { 25 | // Inflate the menu; this adds items to the action bar if it is present. 26 | getMenuInflater().inflate(R.menu.menu_item, menu); 27 | return true; 28 | } 29 | 30 | @Override 31 | public boolean onOptionsItemSelected(MenuItem item) 32 | { 33 | // Handle action bar item clicks here. The action bar will 34 | // automatically handle clicks on the Home/Up button, so long 35 | // as you specify a parent activity in AndroidManifest.xml. 36 | int id = item.getItemId(); 37 | 38 | //noinspection SimplifiableIfStatement 39 | if (id == R.id.action_settings) 40 | { 41 | return true; 42 | } 43 | 44 | return super.onOptionsItemSelected(item); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/java/com/imooc/android_percent_support/ListViewTestActivity.java: -------------------------------------------------------------------------------- 1 | package com.imooc.android_percent_support; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.view.LayoutInflater; 6 | import android.view.Menu; 7 | import android.view.MenuItem; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.ArrayAdapter; 11 | import android.widget.ListView; 12 | import android.widget.TextView; 13 | 14 | import java.util.Arrays; 15 | import java.util.List; 16 | 17 | /** 18 | * 对于ListView,必须将item最外层的高度设置为固定值, 19 | * 没有办法使用百分比,因为其父控件是ListView,不是Percent系列容器; 20 | * 该Item内部的控件,可以使用percent系类属性; 21 | */ 22 | public class ListViewTestActivity extends AppCompatActivity 23 | { 24 | private ListView mListView; 25 | private LayoutInflater mInflater; 26 | 27 | private List mStr = Arrays.asList("Helloworld", "盗墓笔记", "秦时明月", "嫌疑人", "辩护人"); 28 | 29 | @Override 30 | protected void onCreate(Bundle savedInstanceState) 31 | { 32 | super.onCreate(savedInstanceState); 33 | setContentView(R.layout.activity_list_view_test); 34 | 35 | mInflater = LayoutInflater.from(this); 36 | 37 | mListView = (ListView) findViewById(R.id.id_listview); 38 | mListView.setAdapter(new ArrayAdapter(this, -1, mStr) 39 | { 40 | @Override 41 | public View getView(int position, View convertView, ViewGroup parent) 42 | { 43 | if (convertView == null) 44 | { 45 | convertView = mInflater.inflate(R.layout.item_music_list, parent, false); 46 | } 47 | 48 | TextView tv = (TextView) convertView.findViewById(R.id.id_tv_name); 49 | tv.setText(mStr.get(position)); 50 | return convertView; 51 | } 52 | }); 53 | 54 | } 55 | 56 | @Override 57 | public boolean onCreateOptionsMenu(Menu menu) 58 | { 59 | // Inflate the menu; this adds items to the action bar if it is present. 60 | getMenuInflater().inflate(R.menu.menu_list_view_test, menu); 61 | return true; 62 | } 63 | 64 | @Override 65 | public boolean onOptionsItemSelected(MenuItem item) 66 | { 67 | // Handle action bar item clicks here. The action bar will 68 | // automatically handle clicks on the Home/Up button, so long 69 | // as you specify a parent activity in AndroidManifest.xml. 70 | int id = item.getItemId(); 71 | 72 | //noinspection SimplifiableIfStatement 73 | if (id == R.id.action_settings) 74 | { 75 | return true; 76 | } 77 | 78 | return super.onOptionsItemSelected(item); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/java/com/imooc/android_percent_support/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.imooc.android_percent_support; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.ActionBarActivity; 6 | import android.view.LayoutInflater; 7 | import android.view.Menu; 8 | import android.view.MenuItem; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | import android.widget.AdapterView; 12 | import android.widget.ArrayAdapter; 13 | import android.widget.ListView; 14 | import android.widget.TextView; 15 | 16 | 17 | public class MainActivity extends ActionBarActivity 18 | { 19 | private ListView mListView; 20 | private LayoutInflater mInflater; 21 | 22 | private static final int LISTVIEW_POS = 6; 23 | 24 | private String[] mTitle = { 25 | "PercentLinearLayout", 26 | "PercentW or PercentH", 27 | "PercentRelativeLayout 1", 28 | "PercentFrameLayout", 29 | "PercentRelativeLayout 2", 30 | "PercentLinearLayout in ScrollView2", 31 | "PercentInListView", 32 | "PercentPadding", 33 | "PercentScreen[Width|Height]" 34 | }; 35 | private int[] mContentIds = { 36 | R.layout.view5, 37 | R.layout.view1, 38 | R.layout.view2, 39 | R.layout.view3, 40 | R.layout.view4, 41 | R.layout.view6, 42 | -1, 43 | R.layout.view7_padding, 44 | R.layout.percent_sc_sw 45 | }; 46 | 47 | 48 | @Override 49 | protected void onCreate(Bundle savedInstanceState) 50 | { 51 | super.onCreate(savedInstanceState); 52 | setContentView(R.layout.activity_category); 53 | 54 | mInflater = LayoutInflater.from(this); 55 | mListView = (ListView) findViewById(R.id.id_listview); 56 | 57 | mListView.setAdapter(new ArrayAdapter(this, -1, mTitle) 58 | { 59 | @Override 60 | public View getView(int position, View convertView, ViewGroup parent) 61 | { 62 | if (convertView == null) 63 | { 64 | convertView = mInflater.inflate(R.layout.item_category, parent, false); 65 | } 66 | TextView tv = (TextView) convertView.findViewById(R.id.id_title); 67 | tv.setText(getItem(position)); 68 | return convertView; 69 | } 70 | }); 71 | 72 | mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() 73 | { 74 | @Override 75 | public void onItemClick(AdapterView parent, View view, int position, long id) 76 | { 77 | switch (position) 78 | { 79 | case LISTVIEW_POS: 80 | Intent intent = new Intent(MainActivity.this, ListViewTestActivity.class) ; 81 | startActivity(intent); 82 | return ; 83 | } 84 | 85 | 86 | Intent intent = new Intent(MainActivity.this, ItemActivity.class); 87 | intent.putExtra("contentId", mContentIds[position]); 88 | intent.putExtra("title",mTitle[position]); 89 | startActivity(intent); 90 | } 91 | }); 92 | } 93 | 94 | @Override 95 | public boolean onCreateOptionsMenu(Menu menu) 96 | { 97 | // Inflate the menu; this adds items to the action bar if it is present. 98 | getMenuInflater().inflate(R.menu.menu_main, menu); 99 | return true; 100 | } 101 | 102 | @Override 103 | public boolean onOptionsItemSelected(MenuItem item) 104 | { 105 | // Handle action bar item clicks here. The action bar will 106 | // automatically handle clicks on the Home/Up button, so long 107 | // as you specify a parent activity in AndroidManifest.xml. 108 | int id = item.getItemId(); 109 | 110 | //noinspection SimplifiableIfStatement 111 | if (id == R.id.action_settings) 112 | { 113 | return true; 114 | } 115 | 116 | return super.onOptionsItemSelected(item); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/drawable-hdpi/tangyan.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/percent-support-extends-sample/src/main/res/drawable-hdpi/tangyan.jpeg -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/layout/activity_category.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/layout/activity_item.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/layout/activity_list_view_test.xml: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 12 | 13 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/layout/item_category.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 15 | 16 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/layout/item_music_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 18 | 19 | 28 | 29 | 30 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/layout/percent_sc_sw.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 19 | 20 | 29 | 30 | 31 | 40 | 41 | 42 | 50 | 51 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/layout/view1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 18 | 19 | 26 | 27 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/layout/view2.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 15 | 16 | 23 | 24 | 25 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/layout/view3.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 19 | 20 | 29 | 30 | 31 | 40 | 41 | 42 | 50 | 51 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/layout/view4.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 20 | 21 | 31 | 32 | 33 | 42 | 43 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/layout/view5.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | 23 | 24 | 34 | 45 | 55 | 56 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/layout/view6.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 12 | 18 | 19 | 30 | 31 | 41 | 52 | 62 | 63 | 73 | 74 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/layout/view7_padding.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 20 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | 46 | 47 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/menu/menu_item.xml: -------------------------------------------------------------------------------- 1 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/menu/menu_list_view_test.xml: -------------------------------------------------------------------------------- 1 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/menu/menu_main.xml: -------------------------------------------------------------------------------- 1 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/percent-support-extends-sample/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/percent-support-extends-sample/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/percent-support-extends-sample/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/percent-support-extends-sample/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/values/percent.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 60%w 4 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Android-percent-support 3 | 4 | Hello world! 5 | Settings 6 | ItemActivity 7 | ListViewTestActivity 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /percent-support-extends-sample/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /percent-support-extends/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /percent-support-extends/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'com.github.dcendents.android-maven' 3 | apply plugin: 'com.jfrog.bintray' 4 | 5 | version = "1.1.1" 6 | 7 | android { 8 | compileSdkVersion 22 9 | buildToolsVersion "22.0.1" 10 | 11 | defaultConfig { 12 | minSdkVersion 7 13 | targetSdkVersion 22 14 | versionCode 1 15 | versionName "1.0" 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | } 24 | 25 | dependencies { 26 | compile fileTree(dir: 'libs', include: ['*.jar']) 27 | compile 'com.android.support:appcompat-v7:22.2.0' 28 | } 29 | 30 | def siteUrl = 'https://github.com/hongyangAndroid/android-percent-support-extend' // #CONFIG# // project homepage 31 | def gitUrl = 'https://github.com/hongyangAndroid/android-percent-support-extend.git' // #CONFIG# // project git 32 | group = "com.zhy" 33 | 34 | install { 35 | repositories.mavenInstaller { 36 | // This generates POM.xml with proper parameters 37 | pom { 38 | project { 39 | packaging 'aar' 40 | name 'Android Screen Support Extend' // #CONFIG# // project title 41 | url siteUrl 42 | // Set your license 43 | licenses { 44 | license { 45 | name 'The Apache Software License, Version 2.0' 46 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt' 47 | } 48 | } 49 | developers { 50 | developer { 51 | id 'hongyangAndroid' // #CONFIG# // your user id (you can write your nickname) 52 | name 'ZhangHongyang' // #CONFIG# // your user name 53 | email '623565791@qq.com' // #CONFIG# // your email 54 | } 55 | } 56 | scm { 57 | connection gitUrl 58 | developerConnection gitUrl 59 | url siteUrl 60 | } 61 | } 62 | } 63 | } 64 | } 65 | 66 | task sourcesJar(type: Jar) { 67 | from android.sourceSets.main.java.srcDirs 68 | classifier = 'sources' 69 | } 70 | 71 | task javadoc(type: Javadoc) { 72 | source = android.sourceSets.main.java.srcDirs 73 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 74 | } 75 | 76 | task javadocJar(type: Jar, dependsOn: javadoc) { 77 | classifier = 'javadoc' 78 | from javadoc.destinationDir 79 | } 80 | 81 | artifacts { 82 | archives javadocJar 83 | archives sourcesJar 84 | } 85 | 86 | Properties properties = new Properties() 87 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 88 | bintray { 89 | user = properties.getProperty("bintray.user") 90 | key = properties.getProperty("bintray.apikey") 91 | configurations = ['archives'] 92 | pkg { 93 | repo = "maven" 94 | name = "android-screen-support-ext" // #CONFIG# project name in jcenter 95 | websiteUrl = siteUrl 96 | vcsUrl = gitUrl 97 | licenses = ["Apache-2.0"] 98 | publish = true 99 | } 100 | } -------------------------------------------------------------------------------- /percent-support-extends/percent-support-extends.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /percent-support-extends/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/zhy/android/sdk/android-sdk-macosx/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /percent-support-extends/src/androidTest/androidTest1.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /percent-support-extends/src/androidTest/java/com/zhy/android/percent/support/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package com.zhy.android.percent.support; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase 10 | { 11 | public ApplicationTest() 12 | { 13 | super(Application.class); 14 | } 15 | } -------------------------------------------------------------------------------- /percent-support-extends/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /percent-support-extends/src/main/gen/com/zhy/android/percent/support/BuildConfig.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.zhy.android.percent.support; 4 | 5 | /* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */ 6 | public final class BuildConfig { 7 | public final static boolean DEBUG = Boolean.parseBoolean(null); 8 | } -------------------------------------------------------------------------------- /percent-support-extends/src/main/gen/com/zhy/android/percent/support/Manifest.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.zhy.android.percent.support; 4 | 5 | /* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */ 6 | public final class Manifest { 7 | } -------------------------------------------------------------------------------- /percent-support-extends/src/main/gen/com/zhy/android/percent/support/R.java: -------------------------------------------------------------------------------- 1 | /*___Generated_by_IDEA___*/ 2 | 3 | package com.zhy.android.percent.support; 4 | 5 | /* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */ 6 | public final class R { 7 | } -------------------------------------------------------------------------------- /percent-support-extends/src/main/java/com/zhy/android/percent/support/PercentFrameLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.zhy.android.percent.support; 18 | 19 | import android.content.Context; 20 | import android.content.res.TypedArray; 21 | import android.util.AttributeSet; 22 | import android.view.ViewGroup; 23 | import android.widget.FrameLayout; 24 | 25 | /** 26 | * Subclass of {@link FrameLayout} that supports percentage based dimensions and 27 | * margins. 28 | * 29 | * You can specify dimension or a margin of child by using attributes with "Percent" suffix. Follow 30 | * this example: 31 | * 32 | *
 33 |  * <android.support.percent.PercentFrameLayout
 34 |  *         xmlns:android="http://schemas.android.com/apk/res/android"
 35 |  *         xmlns:app="http://schemas.android.com/apk/res-auto"
 36 |  *         android:layout_width="match_parent"
 37 |  *         android:layout_height="match_parent"/>
 38 |  *     <ImageView
 39 |  *         app:layout_widthPercent="50%"
 40 |  *         app:layout_heightPercent="50%"
 41 |  *         app:layout_marginTopPercent="25%"
 42 |  *         app:layout_marginLeftPercent="25%"/>
 43 |  * </android.support.percent.PercentFrameLayout/>
 44 |  * 
45 | * 46 | * The attributes that you can use are: 47 | *
    48 | *
  • {@code layout_widthPercent} 49 | *
  • {@code layout_heightPercent} 50 | *
  • {@code layout_marginPercent} 51 | *
  • {@code layout_marginLeftPercent} 52 | *
  • {@code layout_marginTopPercent} 53 | *
  • {@code layout_marginRightPercent} 54 | *
  • {@code layout_marginBottomPercent} 55 | *
  • {@code layout_marginStartPercent} 56 | *
  • {@code layout_marginEndPercent} 57 | *
58 | * 59 | * It is not necessary to specify {@code layout_width/height} if you specify {@code 60 | * layout_widthPercent.} However, if you want the view to be able to take up more space than what 61 | * percentage value permits, you can add {@code layout_width/height="wrap_content"}. In that case 62 | * if the percentage size is too small for the View's content, it will be resized using 63 | * {@code wrap_content} rule. 64 | */ 65 | public class PercentFrameLayout extends FrameLayout { 66 | private final PercentLayoutHelper mHelper = new PercentLayoutHelper(this); 67 | 68 | public PercentFrameLayout(Context context) { 69 | super(context); 70 | } 71 | 72 | public PercentFrameLayout(Context context, AttributeSet attrs) { 73 | super(context, attrs); 74 | } 75 | 76 | public PercentFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { 77 | super(context, attrs, defStyleAttr); 78 | } 79 | 80 | @Override 81 | public LayoutParams generateLayoutParams(AttributeSet attrs) { 82 | return new LayoutParams(getContext(), attrs); 83 | } 84 | 85 | @Override 86 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 87 | mHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec); 88 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 89 | if (mHelper.handleMeasuredStateTooSmall()) { 90 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 91 | } 92 | } 93 | 94 | @Override 95 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 96 | super.onLayout(changed, left, top, right, bottom); 97 | mHelper.restoreOriginalParams(); 98 | } 99 | 100 | public static class LayoutParams extends FrameLayout.LayoutParams 101 | implements PercentLayoutHelper.PercentLayoutParams { 102 | private PercentLayoutHelper.PercentLayoutInfo mPercentLayoutInfo; 103 | 104 | public LayoutParams(Context c, AttributeSet attrs) { 105 | super(c, attrs); 106 | mPercentLayoutInfo = PercentLayoutHelper.getPercentLayoutInfo(c, attrs); 107 | } 108 | 109 | public LayoutParams(int width, int height) { 110 | super(width, height); 111 | } 112 | 113 | public LayoutParams(int width, int height, int gravity) { 114 | super(width, height, gravity); 115 | } 116 | 117 | public LayoutParams(ViewGroup.LayoutParams source) { 118 | super(source); 119 | } 120 | 121 | public LayoutParams(MarginLayoutParams source) { 122 | super(source); 123 | } 124 | 125 | public LayoutParams(FrameLayout.LayoutParams source) { 126 | super((MarginLayoutParams) source); 127 | gravity = source.gravity; 128 | } 129 | 130 | public LayoutParams(LayoutParams source) { 131 | this((FrameLayout.LayoutParams) source); 132 | mPercentLayoutInfo = source.mPercentLayoutInfo; 133 | } 134 | 135 | @Override 136 | public PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo() { 137 | return mPercentLayoutInfo; 138 | } 139 | 140 | @Override 141 | protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) { 142 | PercentLayoutHelper.fetchWidthAndHeight(this, a, widthAttr, heightAttr); 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /percent-support-extends/src/main/java/com/zhy/android/percent/support/PercentLayoutHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.zhy.android.percent.support; 18 | 19 | import android.content.Context; 20 | import android.content.res.TypedArray; 21 | import android.support.annotation.NonNull; 22 | import android.support.v4.view.MarginLayoutParamsCompat; 23 | import android.support.v4.view.ViewCompat; 24 | import android.util.AttributeSet; 25 | import android.util.DisplayMetrics; 26 | import android.util.Log; 27 | import android.util.TypedValue; 28 | import android.view.View; 29 | import android.view.ViewGroup; 30 | import android.view.WindowManager; 31 | import android.widget.TextView; 32 | 33 | import java.lang.reflect.InvocationTargetException; 34 | import java.lang.reflect.Method; 35 | import java.util.regex.Matcher; 36 | import java.util.regex.Pattern; 37 | 38 | 39 | /** 40 | * Helper for layouts that want to support percentage based dimensions. 41 | *

42 | *

This class collects utility methods that are involved in extracting percentage based dimension 43 | * attributes and applying them to ViewGroup's children. If you would like to implement a layout 44 | * that supports percentage based dimensions, you need to take several steps: 45 | *

46 | *

    47 | *
  1. You need a {@link ViewGroup.LayoutParams} subclass in your ViewGroup that implements 48 | * {@link com.zhy.android.percent.support.PercentLayoutHelper.PercentLayoutParams}. 49 | *
  2. In your {@code LayoutParams(Context c, AttributeSet attrs)} constructor create an instance 50 | * of {@link PercentLayoutHelper.PercentLayoutInfo} by calling 51 | * {@link PercentLayoutHelper#getPercentLayoutInfo(Context, AttributeSet)}. Return this 52 | * object from {@code public PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo()} 53 | * method that you implemented for {@link com.zhy.android.percent.support.PercentLayoutHelper.PercentLayoutParams} interface. 54 | *
  3. Override 55 | * {@link ViewGroup.LayoutParams#setBaseAttributes(TypedArray, int, int)} 56 | * with a single line implementation {@code PercentLayoutHelper.fetchWidthAndHeight(this, a, 57 | * widthAttr, heightAttr);} 58 | *
  4. In your ViewGroup override {@link ViewGroup#generateLayoutParams(AttributeSet)} to return 59 | * your LayoutParams. 60 | *
  5. In your {@link ViewGroup#onMeasure(int, int)} override, you need to implement following 61 | * pattern: 62 | *
     63 |  * protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     64 |  * mHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec);
     65 |  * super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     66 |  * if (mHelper.handleMeasuredStateTooSmall()) {
     67 |  * super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     68 |  * }
     69 |  * }
     70 |  * 
    71 | *
  6. In your {@link ViewGroup#onLayout(boolean, int, int, int, int)} override, you need to 72 | * implement following pattern: 73 | *
     74 |  * protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
     75 |  * super.onLayout(changed, left, top, right, bottom);
     76 |  * mHelper.restoreOriginalParams();
     77 |  * }
     78 |  * 
    79 | *
80 | */ 81 | public class PercentLayoutHelper 82 | { 83 | private static final String TAG = "PercentLayout"; 84 | 85 | private final ViewGroup mHost; 86 | 87 | private static int mWidthScreen; 88 | private static int mHeightScreen; 89 | 90 | public PercentLayoutHelper(ViewGroup host) 91 | { 92 | mHost = host; 93 | getScreenSize(); 94 | } 95 | 96 | private void getScreenSize() 97 | { 98 | WindowManager wm = (WindowManager) mHost.getContext().getSystemService(Context.WINDOW_SERVICE); 99 | DisplayMetrics outMetrics = new DisplayMetrics(); 100 | wm.getDefaultDisplay().getMetrics(outMetrics); 101 | mWidthScreen = outMetrics.widthPixels; 102 | mHeightScreen = outMetrics.heightPixels; 103 | } 104 | 105 | 106 | /** 107 | * Helper method to be called from {@link ViewGroup.LayoutParams#setBaseAttributes} override 108 | * that reads layout_width and layout_height attribute values without throwing an exception if 109 | * they aren't present. 110 | */ 111 | public static void fetchWidthAndHeight(ViewGroup.LayoutParams params, TypedArray array, 112 | int widthAttr, int heightAttr) 113 | { 114 | params.width = array.getLayoutDimension(widthAttr, 0); 115 | params.height = array.getLayoutDimension(heightAttr, 0); 116 | } 117 | 118 | /** 119 | * Iterates over children and changes their width and height to one calculated from percentage 120 | * values. 121 | * 122 | * @param widthMeasureSpec Width MeasureSpec of the parent ViewGroup. 123 | * @param heightMeasureSpec Height MeasureSpec of the parent ViewGroup. 124 | */ 125 | public void adjustChildren(int widthMeasureSpec, int heightMeasureSpec) 126 | { 127 | if (Log.isLoggable(TAG, Log.DEBUG)) 128 | { 129 | Log.d(TAG, "adjustChildren: " + mHost + " widthMeasureSpec: " 130 | + View.MeasureSpec.toString(widthMeasureSpec) + " heightMeasureSpec: " 131 | + View.MeasureSpec.toString(heightMeasureSpec)); 132 | } 133 | int widthHint = View.MeasureSpec.getSize(widthMeasureSpec); 134 | int heightHint = View.MeasureSpec.getSize(heightMeasureSpec); 135 | 136 | if (Log.isLoggable(TAG, Log.DEBUG)) 137 | Log.d(TAG, "widthHint = " + widthHint + " , heightHint = " + heightHint); 138 | 139 | for (int i = 0, N = mHost.getChildCount(); i < N; i++) 140 | { 141 | View view = mHost.getChildAt(i); 142 | ViewGroup.LayoutParams params = view.getLayoutParams(); 143 | 144 | if (Log.isLoggable(TAG, Log.DEBUG)) 145 | { 146 | Log.d(TAG, "should adjust " + view + " " + params); 147 | } 148 | 149 | if (params instanceof PercentLayoutParams) 150 | { 151 | PercentLayoutInfo info = 152 | ((PercentLayoutParams) params).getPercentLayoutInfo(); 153 | if (Log.isLoggable(TAG, Log.DEBUG)) 154 | { 155 | Log.d(TAG, "using " + info); 156 | } 157 | if (info != null) 158 | { 159 | supportTextSize(widthHint, heightHint, view, info); 160 | supportPadding(widthHint, heightHint, view, info); 161 | supportMinOrMaxDimesion(widthHint, heightHint, view, info); 162 | 163 | if (params instanceof ViewGroup.MarginLayoutParams) 164 | { 165 | info.fillMarginLayoutParams((ViewGroup.MarginLayoutParams) params, 166 | widthHint, heightHint); 167 | } else 168 | { 169 | info.fillLayoutParams(params, widthHint, heightHint); 170 | } 171 | } 172 | } 173 | } 174 | 175 | 176 | } 177 | 178 | private void supportPadding(int widthHint, int heightHint, View view, PercentLayoutInfo info) 179 | { 180 | int left = view.getPaddingLeft(), right = view.getPaddingRight(), top = view.getPaddingTop(), bottom = view.getPaddingBottom(); 181 | PercentLayoutInfo.PercentVal percentVal = info.paddingLeftPercent; 182 | if (percentVal != null) 183 | { 184 | int base = getBaseByModeAndVal(widthHint, heightHint, percentVal.basemode); 185 | left = (int) (base * percentVal.percent); 186 | } 187 | percentVal = info.paddingRightPercent; 188 | if (percentVal != null) 189 | { 190 | int base = getBaseByModeAndVal(widthHint, heightHint, percentVal.basemode); 191 | right = (int) (base * percentVal.percent); 192 | } 193 | 194 | percentVal = info.paddingTopPercent; 195 | if (percentVal != null) 196 | { 197 | int base = getBaseByModeAndVal(widthHint, heightHint, percentVal.basemode); 198 | top = (int) (base * percentVal.percent); 199 | } 200 | 201 | percentVal = info.paddingBottomPercent; 202 | if (percentVal != null) 203 | { 204 | int base = getBaseByModeAndVal(widthHint, heightHint, percentVal.basemode); 205 | bottom = (int) (base * percentVal.percent); 206 | } 207 | view.setPadding(left, top, right, bottom); 208 | 209 | 210 | } 211 | 212 | private void supportMinOrMaxDimesion(int widthHint, int heightHint, View view, PercentLayoutInfo info) 213 | { 214 | try 215 | { 216 | Class clazz = view.getClass(); 217 | invokeMethod("setMaxWidth", widthHint, heightHint, view, clazz, info.maxWidthPercent); 218 | invokeMethod("setMaxHeight", widthHint, heightHint, view, clazz, info.maxHeightPercent); 219 | invokeMethod("setMinWidth", widthHint, heightHint, view, clazz, info.minWidthPercent); 220 | invokeMethod("setMinHeight", widthHint, heightHint, view, clazz, info.minHeightPercent); 221 | 222 | } catch (NoSuchMethodException e) 223 | { 224 | e.printStackTrace(); 225 | } catch (InvocationTargetException e) 226 | { 227 | e.printStackTrace(); 228 | } catch (IllegalAccessException e) 229 | { 230 | e.printStackTrace(); 231 | } 232 | 233 | } 234 | 235 | private void invokeMethod(String methodName, int widthHint, int heightHint, View view, Class clazz, PercentLayoutInfo.PercentVal percentVal) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException 236 | { 237 | if (Log.isLoggable(TAG, Log.DEBUG)) 238 | Log.d(TAG, methodName + " ==> " + percentVal); 239 | if (percentVal != null) 240 | { 241 | Method setMaxWidthMethod = clazz.getMethod(methodName, int.class); 242 | setMaxWidthMethod.setAccessible(true); 243 | int base = getBaseByModeAndVal(widthHint, heightHint, percentVal.basemode); 244 | setMaxWidthMethod.invoke(view, (int) (base * percentVal.percent)); 245 | } 246 | } 247 | 248 | private void supportTextSize(int widthHint, int heightHint, View view, PercentLayoutInfo info) 249 | { 250 | //textsize percent support 251 | 252 | PercentLayoutInfo.PercentVal textSizePercent = info.textSizePercent; 253 | if (textSizePercent == null) return; 254 | 255 | int base = getBaseByModeAndVal(widthHint, heightHint, textSizePercent.basemode); 256 | float textSize = (int) (base * textSizePercent.percent); 257 | 258 | //Button 和 EditText 是TextView的子类 259 | if (view instanceof TextView) 260 | { 261 | ((TextView) view).setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize); 262 | } 263 | } 264 | 265 | private static int getBaseByModeAndVal(int widthHint, int heightHint, PercentLayoutInfo.BASEMODE basemode) 266 | { 267 | switch (basemode) 268 | { 269 | case BASE_HEIGHT: 270 | return heightHint; 271 | case BASE_WIDTH: 272 | return widthHint; 273 | case BASE_SCREEN_WIDTH: 274 | return mWidthScreen; 275 | case BASE_SCREEN_HEIGHT: 276 | return mHeightScreen; 277 | } 278 | return 0; 279 | } 280 | 281 | 282 | /** 283 | * Constructs a PercentLayoutInfo from attributes associated with a View. Call this method from 284 | * {@code LayoutParams(Context c, AttributeSet attrs)} constructor. 285 | */ 286 | public static PercentLayoutInfo getPercentLayoutInfo(Context context, 287 | AttributeSet attrs) 288 | { 289 | PercentLayoutInfo info = null; 290 | TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.PercentLayout_Layout); 291 | 292 | info = setWidthAndHeightVal(array, info); 293 | 294 | info = setMarginRelatedVal(array, info); 295 | 296 | info = setTextSizeSupportVal(array, info); 297 | 298 | info = setMinMaxWidthHeightRelatedVal(array, info); 299 | 300 | info = setPaddingRelatedVal(array, info); 301 | 302 | 303 | array.recycle(); 304 | 305 | if (Log.isLoggable(TAG, Log.DEBUG)) 306 | { 307 | Log.d(TAG, "constructed: " + info); 308 | } 309 | return info; 310 | } 311 | 312 | private static PercentLayoutInfo setWidthAndHeightVal(TypedArray array, PercentLayoutInfo info) 313 | { 314 | PercentLayoutInfo.PercentVal percentVal = getPercentVal(array, R.styleable.PercentLayout_Layout_layout_widthPercent, true); 315 | if (percentVal != null) 316 | { 317 | if (Log.isLoggable(TAG, Log.VERBOSE)) 318 | { 319 | Log.v(TAG, "percent width: " + percentVal.percent); 320 | } 321 | info = checkForInfoExists(info); 322 | info.widthPercent = percentVal; 323 | } 324 | percentVal = getPercentVal(array, R.styleable.PercentLayout_Layout_layout_heightPercent, false); 325 | 326 | if (percentVal != null) 327 | { 328 | if (Log.isLoggable(TAG, Log.VERBOSE)) 329 | { 330 | Log.v(TAG, "percent height: " + percentVal.percent); 331 | } 332 | info = checkForInfoExists(info); 333 | info.heightPercent = percentVal; 334 | } 335 | 336 | return info; 337 | } 338 | 339 | private static PercentLayoutInfo setTextSizeSupportVal(TypedArray array, PercentLayoutInfo info) 340 | { 341 | //textSizePercent 默认以高度作为基准 342 | PercentLayoutInfo.PercentVal percentVal = getPercentVal(array, R.styleable.PercentLayout_Layout_layout_textSizePercent, false); 343 | if (percentVal != null) 344 | { 345 | if (Log.isLoggable(TAG, Log.VERBOSE)) 346 | { 347 | Log.v(TAG, "percent text size: " + percentVal.percent); 348 | } 349 | info = checkForInfoExists(info); 350 | info.textSizePercent = percentVal; 351 | } 352 | 353 | return info; 354 | } 355 | 356 | private static PercentLayoutInfo setMinMaxWidthHeightRelatedVal(TypedArray array, PercentLayoutInfo info) 357 | { 358 | //maxWidth 359 | PercentLayoutInfo.PercentVal percentVal = getPercentVal(array, 360 | R.styleable.PercentLayout_Layout_layout_maxWidthPercent, 361 | true); 362 | if (percentVal != null) 363 | { 364 | info = checkForInfoExists(info); 365 | info.maxWidthPercent = percentVal; 366 | } 367 | //maxHeight 368 | percentVal = getPercentVal(array, 369 | R.styleable.PercentLayout_Layout_layout_maxHeightPercent, 370 | false); 371 | if (percentVal != null) 372 | { 373 | info = checkForInfoExists(info); 374 | info.maxHeightPercent = percentVal; 375 | } 376 | //minWidth 377 | percentVal = getPercentVal(array, 378 | R.styleable.PercentLayout_Layout_layout_minWidthPercent, 379 | true); 380 | if (percentVal != null) 381 | { 382 | info = checkForInfoExists(info); 383 | info.minWidthPercent = percentVal; 384 | } 385 | //minHeight 386 | percentVal = getPercentVal(array, 387 | R.styleable.PercentLayout_Layout_layout_minHeightPercent, 388 | false); 389 | if (percentVal != null) 390 | { 391 | info = checkForInfoExists(info); 392 | info.minHeightPercent = percentVal; 393 | } 394 | 395 | return info; 396 | } 397 | 398 | private static PercentLayoutInfo setMarginRelatedVal(TypedArray array, PercentLayoutInfo info) 399 | { 400 | //默认margin参考宽度 401 | PercentLayoutInfo.PercentVal percentVal = 402 | getPercentVal(array, 403 | R.styleable.PercentLayout_Layout_layout_marginPercent, 404 | true); 405 | 406 | if (percentVal != null) 407 | { 408 | if (Log.isLoggable(TAG, Log.VERBOSE)) 409 | { 410 | Log.v(TAG, "percent margin: " + percentVal.percent); 411 | } 412 | info = checkForInfoExists(info); 413 | info.leftMarginPercent = percentVal; 414 | info.topMarginPercent = percentVal; 415 | info.rightMarginPercent = percentVal; 416 | info.bottomMarginPercent = percentVal; 417 | } 418 | 419 | percentVal = getPercentVal(array, R.styleable.PercentLayout_Layout_layout_marginLeftPercent, true); 420 | if (percentVal != null) 421 | { 422 | if (Log.isLoggable(TAG, Log.VERBOSE)) 423 | { 424 | Log.v(TAG, "percent left margin: " + percentVal.percent); 425 | } 426 | info = checkForInfoExists(info); 427 | info.leftMarginPercent = percentVal; 428 | } 429 | 430 | percentVal = getPercentVal(array, R.styleable.PercentLayout_Layout_layout_marginTopPercent, false); 431 | if (percentVal != null) 432 | { 433 | if (Log.isLoggable(TAG, Log.VERBOSE)) 434 | { 435 | Log.v(TAG, "percent top margin: " + percentVal.percent); 436 | } 437 | info = checkForInfoExists(info); 438 | info.topMarginPercent = percentVal; 439 | } 440 | 441 | percentVal = getPercentVal(array, R.styleable.PercentLayout_Layout_layout_marginRightPercent, true); 442 | if (percentVal != null) 443 | { 444 | if (Log.isLoggable(TAG, Log.VERBOSE)) 445 | { 446 | Log.v(TAG, "percent right margin: " + percentVal.percent); 447 | } 448 | info = checkForInfoExists(info); 449 | info.rightMarginPercent = percentVal; 450 | } 451 | 452 | percentVal = getPercentVal(array, R.styleable.PercentLayout_Layout_layout_marginBottomPercent, false); 453 | if (percentVal != null) 454 | { 455 | if (Log.isLoggable(TAG, Log.VERBOSE)) 456 | { 457 | Log.v(TAG, "percent bottom margin: " + percentVal.percent); 458 | } 459 | info = checkForInfoExists(info); 460 | info.bottomMarginPercent = percentVal; 461 | } 462 | percentVal = getPercentVal(array, R.styleable.PercentLayout_Layout_layout_marginStartPercent, true); 463 | if (percentVal != null) 464 | { 465 | if (Log.isLoggable(TAG, Log.VERBOSE)) 466 | { 467 | Log.v(TAG, "percent start margin: " + percentVal.percent); 468 | } 469 | info = checkForInfoExists(info); 470 | info.startMarginPercent = percentVal; 471 | } 472 | 473 | percentVal = getPercentVal(array, R.styleable.PercentLayout_Layout_layout_marginEndPercent, true); 474 | if (percentVal != null) 475 | { 476 | if (Log.isLoggable(TAG, Log.VERBOSE)) 477 | { 478 | Log.v(TAG, "percent end margin: " + percentVal.percent); 479 | } 480 | info = checkForInfoExists(info); 481 | info.endMarginPercent = percentVal; 482 | } 483 | 484 | return info; 485 | } 486 | 487 | /** 488 | * 设置paddingPercent相关属性 489 | * 490 | * @param array 491 | * @param info 492 | */ 493 | private static PercentLayoutInfo setPaddingRelatedVal(TypedArray array, PercentLayoutInfo info) 494 | { 495 | //默认padding以宽度为标准 496 | PercentLayoutInfo.PercentVal percentVal = getPercentVal(array, 497 | R.styleable.PercentLayout_Layout_layout_paddingPercent, 498 | true); 499 | if (percentVal != null) 500 | { 501 | info = checkForInfoExists(info); 502 | info.paddingLeftPercent = percentVal; 503 | info.paddingRightPercent = percentVal; 504 | info.paddingBottomPercent = percentVal; 505 | info.paddingTopPercent = percentVal; 506 | } 507 | 508 | 509 | percentVal = getPercentVal(array, 510 | R.styleable.PercentLayout_Layout_layout_paddingLeftPercent, 511 | true); 512 | if (percentVal != null) 513 | { 514 | info = checkForInfoExists(info); 515 | info.paddingLeftPercent = percentVal; 516 | } 517 | 518 | percentVal = getPercentVal(array, 519 | R.styleable.PercentLayout_Layout_layout_paddingRightPercent, 520 | true); 521 | if (percentVal != null) 522 | { 523 | info = checkForInfoExists(info); 524 | info.paddingRightPercent = percentVal; 525 | } 526 | 527 | percentVal = getPercentVal(array, 528 | R.styleable.PercentLayout_Layout_layout_paddingTopPercent, 529 | true); 530 | if (percentVal != null) 531 | { 532 | info = checkForInfoExists(info); 533 | info.paddingTopPercent = percentVal; 534 | } 535 | 536 | percentVal = getPercentVal(array, 537 | R.styleable.PercentLayout_Layout_layout_paddingBottomPercent, 538 | true); 539 | if (percentVal != null) 540 | { 541 | info = checkForInfoExists(info); 542 | info.paddingBottomPercent = percentVal; 543 | } 544 | 545 | return info; 546 | } 547 | 548 | private static PercentLayoutInfo.PercentVal getPercentVal(TypedArray array, int index, boolean baseWidth) 549 | { 550 | String sizeStr = array.getString(index); 551 | PercentLayoutInfo.PercentVal percentVal = getPercentVal(sizeStr, baseWidth); 552 | return percentVal; 553 | } 554 | 555 | 556 | @NonNull 557 | private static PercentLayoutInfo checkForInfoExists(PercentLayoutInfo info) 558 | { 559 | info = info != null ? info : new PercentLayoutInfo(); 560 | return info; 561 | } 562 | 563 | 564 | private static final String REGEX_PERCENT = "^(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)%([s]?[wh]?)$"; 565 | 566 | /** 567 | * widthStr to PercentVal 568 | *
569 | * eg: 35%w => new PercentVal(35, true) 570 | * 571 | * @param percentStr 572 | * @param isOnWidth 573 | * @return 574 | */ 575 | private static PercentLayoutInfo.PercentVal getPercentVal(String percentStr, boolean isOnWidth) 576 | { 577 | //valid param 578 | if (percentStr == null) 579 | { 580 | return null; 581 | } 582 | Pattern p = Pattern.compile(REGEX_PERCENT); 583 | Matcher matcher = p.matcher(percentStr); 584 | if (!matcher.matches()) 585 | { 586 | throw new RuntimeException("the value of layout_xxxPercent invalid! ==>" + percentStr); 587 | } 588 | int len = percentStr.length(); 589 | //extract the float value 590 | String floatVal = matcher.group(1); 591 | String lastAlpha = percentStr.substring(len - 1); 592 | 593 | float percent = Float.parseFloat(floatVal) / 100f; 594 | 595 | PercentLayoutInfo.PercentVal percentVal = new PercentLayoutInfo.PercentVal(); 596 | percentVal.percent = percent; 597 | if (percentStr.endsWith(PercentLayoutInfo.BASEMODE.SW)) 598 | { 599 | percentVal.basemode = PercentLayoutInfo.BASEMODE.BASE_SCREEN_WIDTH; 600 | } else if (percentStr.endsWith(PercentLayoutInfo.BASEMODE.SH)) 601 | { 602 | percentVal.basemode = PercentLayoutInfo.BASEMODE.BASE_SCREEN_HEIGHT; 603 | } else if (percentStr.endsWith(PercentLayoutInfo.BASEMODE.PERCENT)) 604 | { 605 | if (isOnWidth) 606 | { 607 | percentVal.basemode = PercentLayoutInfo.BASEMODE.BASE_WIDTH; 608 | } else 609 | { 610 | percentVal.basemode = PercentLayoutInfo.BASEMODE.BASE_HEIGHT; 611 | } 612 | } else if (percentStr.endsWith(PercentLayoutInfo.BASEMODE.W)) 613 | { 614 | percentVal.basemode = PercentLayoutInfo.BASEMODE.BASE_WIDTH; 615 | } else if (percentStr.endsWith(PercentLayoutInfo.BASEMODE.H)) 616 | { 617 | percentVal.basemode = PercentLayoutInfo.BASEMODE.BASE_HEIGHT; 618 | } else 619 | { 620 | throw new IllegalArgumentException("the " + percentStr + " must be endWith [%|w|h|sw|sh]"); 621 | } 622 | 623 | return percentVal; 624 | } 625 | 626 | /** 627 | * Iterates over children and restores their original dimensions that were changed for 628 | * percentage values. Calling this method only makes sense if you previously called 629 | * {@link PercentLayoutHelper#adjustChildren(int, int)}. 630 | */ 631 | 632 | public void restoreOriginalParams() 633 | { 634 | for (int i = 0, N = mHost.getChildCount(); i < N; i++) 635 | { 636 | View view = mHost.getChildAt(i); 637 | ViewGroup.LayoutParams params = view.getLayoutParams(); 638 | if (Log.isLoggable(TAG, Log.DEBUG)) 639 | { 640 | Log.d(TAG, "should restore " + view + " " + params); 641 | } 642 | if (params instanceof PercentLayoutParams) 643 | { 644 | PercentLayoutInfo info = 645 | ((PercentLayoutParams) params).getPercentLayoutInfo(); 646 | if (Log.isLoggable(TAG, Log.DEBUG)) 647 | { 648 | Log.d(TAG, "using " + info); 649 | } 650 | if (info != null) 651 | { 652 | if (params instanceof ViewGroup.MarginLayoutParams) 653 | { 654 | info.restoreMarginLayoutParams((ViewGroup.MarginLayoutParams) params); 655 | } else 656 | { 657 | info.restoreLayoutParams(params); 658 | } 659 | } 660 | } 661 | } 662 | } 663 | 664 | /** 665 | * Iterates over children and checks if any of them would like to get more space than it 666 | * received through the percentage dimension. 667 | *

668 | * If you are building a layout that supports percentage dimensions you are encouraged to take 669 | * advantage of this method. The developer should be able to specify that a child should be 670 | * remeasured by adding normal dimension attribute with {@code wrap_content} value. For example 671 | * he might specify child's attributes as {@code app:layout_widthPercent="60%p"} and 672 | * {@code android:layout_width="wrap_content"}. In this case if the child receives too little 673 | * space, it will be remeasured with width set to {@code WRAP_CONTENT}. 674 | * 675 | * @return True if the measure phase needs to be rerun because one of the children would like 676 | * to receive more space. 677 | */ 678 | public boolean handleMeasuredStateTooSmall() 679 | { 680 | boolean needsSecondMeasure = false; 681 | for (int i = 0, N = mHost.getChildCount(); i < N; i++) 682 | { 683 | View view = mHost.getChildAt(i); 684 | ViewGroup.LayoutParams params = view.getLayoutParams(); 685 | if (Log.isLoggable(TAG, Log.DEBUG)) 686 | { 687 | Log.d(TAG, "should handle measured state too small " + view + " " + params); 688 | } 689 | if (params instanceof PercentLayoutParams) 690 | { 691 | PercentLayoutInfo info = 692 | ((PercentLayoutParams) params).getPercentLayoutInfo(); 693 | if (info != null) 694 | { 695 | if (shouldHandleMeasuredWidthTooSmall(view, info)) 696 | { 697 | needsSecondMeasure = true; 698 | params.width = ViewGroup.LayoutParams.WRAP_CONTENT; 699 | } 700 | if (shouldHandleMeasuredHeightTooSmall(view, info)) 701 | { 702 | needsSecondMeasure = true; 703 | params.height = ViewGroup.LayoutParams.WRAP_CONTENT; 704 | } 705 | } 706 | } 707 | } 708 | if (Log.isLoggable(TAG, Log.DEBUG)) 709 | { 710 | Log.d(TAG, "should trigger second measure pass: " + needsSecondMeasure); 711 | } 712 | return needsSecondMeasure; 713 | } 714 | 715 | private static boolean shouldHandleMeasuredWidthTooSmall(View view, PercentLayoutInfo info) 716 | { 717 | int state = ViewCompat.getMeasuredWidthAndState(view) & ViewCompat.MEASURED_STATE_MASK; 718 | if (info == null || info.widthPercent == null) 719 | { 720 | return false; 721 | } 722 | return state == ViewCompat.MEASURED_STATE_TOO_SMALL && info.widthPercent.percent >= 0 && 723 | info.mPreservedParams.width == ViewGroup.LayoutParams.WRAP_CONTENT; 724 | } 725 | 726 | private static boolean shouldHandleMeasuredHeightTooSmall(View view, PercentLayoutInfo info) 727 | { 728 | int state = ViewCompat.getMeasuredHeightAndState(view) & ViewCompat.MEASURED_STATE_MASK; 729 | if (info == null || info.heightPercent == null) 730 | { 731 | return false; 732 | } 733 | return state == ViewCompat.MEASURED_STATE_TOO_SMALL && info.heightPercent.percent >= 0 && 734 | info.mPreservedParams.height == ViewGroup.LayoutParams.WRAP_CONTENT; 735 | } 736 | 737 | 738 | /** 739 | * Container for information about percentage dimensions and margins. It acts as an extension 740 | * for {@code LayoutParams}. 741 | */ 742 | public static class PercentLayoutInfo 743 | { 744 | 745 | private enum BASEMODE 746 | { 747 | 748 | BASE_WIDTH, BASE_HEIGHT, BASE_SCREEN_WIDTH, BASE_SCREEN_HEIGHT; 749 | 750 | /** 751 | * width_parent 752 | */ 753 | public static final String PERCENT = "%"; 754 | /** 755 | * width_parent 756 | */ 757 | public static final String W = "w"; 758 | /** 759 | * height_parent 760 | */ 761 | public static final String H = "h"; 762 | /** 763 | * width_screen 764 | */ 765 | public static final String SW = "sw"; 766 | /** 767 | * height_screen 768 | */ 769 | public static final String SH = "sh"; 770 | } 771 | 772 | public static class PercentVal 773 | { 774 | 775 | public float percent = -1; 776 | public BASEMODE basemode; 777 | 778 | public PercentVal() 779 | { 780 | } 781 | 782 | public PercentVal(float percent, BASEMODE baseMode) 783 | { 784 | this.percent = percent; 785 | this.basemode = baseMode; 786 | } 787 | 788 | @Override 789 | public String toString() 790 | { 791 | return "PercentVal{" + 792 | "percent=" + percent + 793 | ", basemode=" + basemode.name() + 794 | '}'; 795 | } 796 | } 797 | 798 | public PercentVal widthPercent; 799 | public PercentVal heightPercent; 800 | 801 | public PercentVal leftMarginPercent; 802 | public PercentVal topMarginPercent; 803 | public PercentVal rightMarginPercent; 804 | public PercentVal bottomMarginPercent; 805 | public PercentVal startMarginPercent; 806 | public PercentVal endMarginPercent; 807 | 808 | public PercentVal textSizePercent; 809 | 810 | //1.0.4 those attr for some views' setMax/min Height/Width method 811 | public PercentVal maxWidthPercent; 812 | public PercentVal maxHeightPercent; 813 | public PercentVal minWidthPercent; 814 | public PercentVal minHeightPercent; 815 | 816 | //1.0.6 add padding supprot 817 | public PercentVal paddingLeftPercent; 818 | public PercentVal paddingRightPercent; 819 | public PercentVal paddingTopPercent; 820 | public PercentVal paddingBottomPercent; 821 | 822 | 823 | /* package */ final ViewGroup.MarginLayoutParams mPreservedParams; 824 | 825 | 826 | public PercentLayoutInfo() 827 | { 828 | mPreservedParams = new ViewGroup.MarginLayoutParams(0, 0); 829 | } 830 | 831 | /** 832 | * Fills {@code ViewGroup.LayoutParams} dimensions based on percentage values. 833 | */ 834 | public void fillLayoutParams(ViewGroup.LayoutParams params, int widthHint, 835 | int heightHint) 836 | { 837 | // Preserve the original layout params, so we can restore them after the measure step. 838 | mPreservedParams.width = params.width; 839 | mPreservedParams.height = params.height; 840 | 841 | if (widthPercent != null) 842 | { 843 | int base = getBaseByModeAndVal(widthHint, heightHint, widthPercent.basemode); 844 | params.width = (int) (base * widthPercent.percent); 845 | } 846 | if (heightPercent != null) 847 | { 848 | int base = getBaseByModeAndVal(widthHint, heightHint, heightPercent.basemode); 849 | params.height = (int) (base * heightPercent.percent); 850 | } 851 | 852 | if (Log.isLoggable(TAG, Log.DEBUG)) 853 | { 854 | Log.d(TAG, "after fillLayoutParams: (" + params.width + ", " + params.height + ")"); 855 | } 856 | } 857 | 858 | /** 859 | * Fills {@code ViewGroup.MarginLayoutParams} dimensions and margins based on percentage 860 | * values. 861 | */ 862 | public void fillMarginLayoutParams(ViewGroup.MarginLayoutParams params, int widthHint, 863 | int heightHint) 864 | { 865 | fillLayoutParams(params, widthHint, heightHint); 866 | 867 | // Preserver the original margins, so we can restore them after the measure step. 868 | mPreservedParams.leftMargin = params.leftMargin; 869 | mPreservedParams.topMargin = params.topMargin; 870 | mPreservedParams.rightMargin = params.rightMargin; 871 | mPreservedParams.bottomMargin = params.bottomMargin; 872 | MarginLayoutParamsCompat.setMarginStart(mPreservedParams, 873 | MarginLayoutParamsCompat.getMarginStart(params)); 874 | MarginLayoutParamsCompat.setMarginEnd(mPreservedParams, 875 | MarginLayoutParamsCompat.getMarginEnd(params)); 876 | 877 | if (leftMarginPercent != null) 878 | { 879 | int base = getBaseByModeAndVal(widthHint, heightHint, leftMarginPercent.basemode); 880 | params.leftMargin = (int) (base * leftMarginPercent.percent); 881 | } 882 | if (topMarginPercent != null) 883 | { 884 | int base = getBaseByModeAndVal(widthHint, heightHint, topMarginPercent.basemode); 885 | params.topMargin = (int) (base * topMarginPercent.percent); 886 | } 887 | if (rightMarginPercent != null) 888 | { 889 | int base = getBaseByModeAndVal(widthHint, heightHint, rightMarginPercent.basemode); 890 | params.rightMargin = (int) (base * rightMarginPercent.percent); 891 | } 892 | if (bottomMarginPercent != null) 893 | { 894 | int base = getBaseByModeAndVal(widthHint, heightHint, bottomMarginPercent.basemode); 895 | params.bottomMargin = (int) (base * bottomMarginPercent.percent); 896 | } 897 | if (startMarginPercent != null) 898 | { 899 | int base = getBaseByModeAndVal(widthHint, heightHint, startMarginPercent.basemode); 900 | MarginLayoutParamsCompat.setMarginStart(params, 901 | (int) (base * startMarginPercent.percent)); 902 | } 903 | if (endMarginPercent != null) 904 | { 905 | int base = getBaseByModeAndVal(widthHint, heightHint, endMarginPercent.basemode); 906 | MarginLayoutParamsCompat.setMarginEnd(params, 907 | (int) (base * endMarginPercent.percent)); 908 | } 909 | if (Log.isLoggable(TAG, Log.DEBUG)) 910 | { 911 | Log.d(TAG, "after fillMarginLayoutParams: (" + params.width + ", " + params.height 912 | + ")"); 913 | } 914 | } 915 | 916 | @Override 917 | public String toString() 918 | { 919 | return "PercentLayoutInfo{" + 920 | "widthPercent=" + widthPercent + 921 | ", heightPercent=" + heightPercent + 922 | ", leftMarginPercent=" + leftMarginPercent + 923 | ", topMarginPercent=" + topMarginPercent + 924 | ", rightMarginPercent=" + rightMarginPercent + 925 | ", bottomMarginPercent=" + bottomMarginPercent + 926 | ", startMarginPercent=" + startMarginPercent + 927 | ", endMarginPercent=" + endMarginPercent + 928 | ", textSizePercent=" + textSizePercent + 929 | ", maxWidthPercent=" + maxWidthPercent + 930 | ", maxHeightPercent=" + maxHeightPercent + 931 | ", minWidthPercent=" + minWidthPercent + 932 | ", minHeightPercent=" + minHeightPercent + 933 | ", paddingLeftPercent=" + paddingLeftPercent + 934 | ", paddingRightPercent=" + paddingRightPercent + 935 | ", paddingTopPercent=" + paddingTopPercent + 936 | ", paddingBottomPercent=" + paddingBottomPercent + 937 | ", mPreservedParams=" + mPreservedParams + 938 | '}'; 939 | } 940 | 941 | /** 942 | * Restores original dimensions and margins after they were changed for percentage based 943 | * values. Calling this method only makes sense if you previously called 944 | * {@link PercentLayoutHelper.PercentLayoutInfo#fillMarginLayoutParams}. 945 | */ 946 | public void restoreMarginLayoutParams(ViewGroup.MarginLayoutParams params) 947 | { 948 | restoreLayoutParams(params); 949 | params.leftMargin = mPreservedParams.leftMargin; 950 | params.topMargin = mPreservedParams.topMargin; 951 | params.rightMargin = mPreservedParams.rightMargin; 952 | params.bottomMargin = mPreservedParams.bottomMargin; 953 | MarginLayoutParamsCompat.setMarginStart(params, 954 | MarginLayoutParamsCompat.getMarginStart(mPreservedParams)); 955 | MarginLayoutParamsCompat.setMarginEnd(params, 956 | MarginLayoutParamsCompat.getMarginEnd(mPreservedParams)); 957 | } 958 | 959 | /** 960 | * Restores original dimensions after they were changed for percentage based values. Calling 961 | * this method only makes sense if you previously called 962 | * {@link PercentLayoutHelper.PercentLayoutInfo#fillLayoutParams}. 963 | */ 964 | public void restoreLayoutParams(ViewGroup.LayoutParams params) 965 | { 966 | params.width = mPreservedParams.width; 967 | params.height = mPreservedParams.height; 968 | } 969 | } 970 | 971 | /** 972 | * If a layout wants to support percentage based dimensions and use this helper class, its 973 | * {@code LayoutParams} subclass must implement this interface. 974 | *

975 | * Your {@code LayoutParams} subclass should contain an instance of {@code PercentLayoutInfo} 976 | * and the implementation of this interface should be a simple accessor. 977 | */ 978 | public interface PercentLayoutParams 979 | { 980 | PercentLayoutInfo getPercentLayoutInfo(); 981 | } 982 | } 983 | -------------------------------------------------------------------------------- /percent-support-extends/src/main/java/com/zhy/android/percent/support/PercentLinearLayout.java: -------------------------------------------------------------------------------- 1 | package com.zhy.android.percent.support; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.res.TypedArray; 6 | import android.util.AttributeSet; 7 | import android.util.DisplayMetrics; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.view.WindowManager; 11 | import android.widget.LinearLayout; 12 | import android.widget.ScrollView; 13 | 14 | /** 15 | * Created by zhy on 15/6/30. 16 | */ 17 | public class PercentLinearLayout extends LinearLayout 18 | { 19 | 20 | private static final String TAG = "PercentLinearLayout"; 21 | private PercentLayoutHelper mPercentLayoutHelper; 22 | 23 | public PercentLinearLayout(Context context, AttributeSet attrs) 24 | { 25 | super(context, attrs); 26 | 27 | mPercentLayoutHelper = new PercentLayoutHelper(this); 28 | } 29 | 30 | 31 | @Override 32 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 33 | { 34 | 35 | int heightSize = View.MeasureSpec.getSize(heightMeasureSpec); 36 | int heightMode = View.MeasureSpec.getMode(heightMeasureSpec); 37 | int tmpHeightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode); 38 | 39 | int widthSize = View.MeasureSpec.getSize(widthMeasureSpec); 40 | int widthMode = View.MeasureSpec.getMode(widthMeasureSpec); 41 | int tmpWidthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode); 42 | 43 | //fixed scrollview height problems 44 | if (heightMode == MeasureSpec.UNSPECIFIED && getParent() != null && (getParent() instanceof ScrollView)) 45 | { 46 | int baseHeight = 0; 47 | Context context = getContext(); 48 | if (context instanceof Activity) 49 | { 50 | Activity act = (Activity) context; 51 | int measuredHeight = act.findViewById(android.R.id.content).getMeasuredHeight(); 52 | baseHeight = measuredHeight; 53 | } else 54 | { 55 | baseHeight = getScreenHeight(); 56 | } 57 | tmpHeightMeasureSpec = MeasureSpec.makeMeasureSpec(baseHeight, heightMode); 58 | } 59 | 60 | 61 | mPercentLayoutHelper.adjustChildren(tmpWidthMeasureSpec, tmpHeightMeasureSpec); 62 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 63 | if (mPercentLayoutHelper.handleMeasuredStateTooSmall()) 64 | { 65 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 66 | } 67 | } 68 | 69 | private int getScreenHeight() 70 | { 71 | WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); 72 | DisplayMetrics outMetrics = new DisplayMetrics(); 73 | wm.getDefaultDisplay().getMetrics(outMetrics); 74 | return outMetrics.heightPixels; 75 | } 76 | 77 | @Override 78 | protected void onLayout(boolean changed, int l, int t, int r, int b) 79 | { 80 | super.onLayout(changed, l, t, r, b); 81 | mPercentLayoutHelper.restoreOriginalParams(); 82 | } 83 | 84 | @Override 85 | public LayoutParams generateLayoutParams(AttributeSet attrs) 86 | { 87 | return new LayoutParams(getContext(), attrs); 88 | } 89 | 90 | 91 | public static class LayoutParams extends LinearLayout.LayoutParams 92 | implements PercentLayoutHelper.PercentLayoutParams 93 | { 94 | private PercentLayoutHelper.PercentLayoutInfo mPercentLayoutInfo; 95 | 96 | public LayoutParams(Context c, AttributeSet attrs) 97 | { 98 | super(c, attrs); 99 | mPercentLayoutInfo = PercentLayoutHelper.getPercentLayoutInfo(c, attrs); 100 | } 101 | 102 | @Override 103 | public PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo() 104 | { 105 | return mPercentLayoutInfo; 106 | } 107 | 108 | @Override 109 | protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) 110 | { 111 | PercentLayoutHelper.fetchWidthAndHeight(this, a, widthAttr, heightAttr); 112 | } 113 | 114 | public LayoutParams(int width, int height) 115 | { 116 | super(width, height); 117 | } 118 | 119 | 120 | public LayoutParams(ViewGroup.LayoutParams source) 121 | { 122 | super(source); 123 | } 124 | 125 | public LayoutParams(MarginLayoutParams source) 126 | { 127 | super(source); 128 | } 129 | 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /percent-support-extends/src/main/java/com/zhy/android/percent/support/PercentRelativeLayout.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.zhy.android.percent.support; 18 | 19 | import android.content.Context; 20 | import android.content.res.TypedArray; 21 | import android.util.AttributeSet; 22 | import android.view.ViewGroup; 23 | import android.widget.RelativeLayout; 24 | 25 | /** 26 | * Subclass of {@link RelativeLayout} that supports percentage based dimensions and 27 | * margins. 28 | * 29 | * You can specify dimension or a margin of child by using attributes with "Percent" suffix. Follow 30 | * this example: 31 | * 32 | *

 33 |  * <android.support.percent.PercentRelativeLayout
 34 |  *         xmlns:android="http://schemas.android.com/apk/res/android"
 35 |  *         xmlns:app="http://schemas.android.com/apk/res-auto"
 36 |  *         android:layout_width="match_parent"
 37 |  *         android:layout_height="match_parent"/>
 38 |  *     <ImageView
 39 |  *         app:layout_widthPercent="50%"
 40 |  *         app:layout_heightPercent="50%"
 41 |  *         app:layout_marginTopPercent="25%"
 42 |  *         app:layout_marginLeftPercent="25%"/>
 43 |  * </android.support.percent.PercentFrameLayout/>
 44 |  * 
45 | * 46 | * The attributes that you can use are: 47 | *
    48 | *
  • {@code layout_widthPercent} 49 | *
  • {@code layout_heightPercent} 50 | *
  • {@code layout_marginPercent} 51 | *
  • {@code layout_marginLeftPercent} 52 | *
  • {@code layout_marginTopPercent} 53 | *
  • {@code layout_marginRightPercent} 54 | *
  • {@code layout_marginBottomPercent} 55 | *
  • {@code layout_marginStartPercent} 56 | *
  • {@code layout_marginEndPercent} 57 | *
58 | * 59 | * It is not necessary to specify {@code layout_width/height} if you specify {@code 60 | * layout_widthPercent.} However, if you want the view to be able to take up more space than what 61 | * percentage value permits, you can add {@code layout_width/height="wrap_content"}. In that case 62 | * if the percentage size is too small for the View's content, it will be resized using 63 | * {@code wrap_content} rule. 64 | */ 65 | public class PercentRelativeLayout extends RelativeLayout { 66 | private final PercentLayoutHelper mHelper = new PercentLayoutHelper(this); 67 | 68 | public PercentRelativeLayout(Context context) { 69 | super(context); 70 | } 71 | 72 | public PercentRelativeLayout(Context context, AttributeSet attrs) { 73 | super(context, attrs); 74 | } 75 | 76 | public PercentRelativeLayout(Context context, AttributeSet attrs, int defStyle) { 77 | super(context, attrs, defStyle); 78 | } 79 | 80 | @Override 81 | public LayoutParams generateLayoutParams(AttributeSet attrs) { 82 | return new LayoutParams(getContext(), attrs); 83 | } 84 | 85 | @Override 86 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 87 | mHelper.adjustChildren(widthMeasureSpec, heightMeasureSpec); 88 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 89 | if (mHelper.handleMeasuredStateTooSmall()) { 90 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 91 | } 92 | } 93 | 94 | @Override 95 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 96 | super.onLayout(changed, left, top, right, bottom); 97 | mHelper.restoreOriginalParams(); 98 | } 99 | 100 | public static class LayoutParams extends RelativeLayout.LayoutParams 101 | implements PercentLayoutHelper.PercentLayoutParams { 102 | private PercentLayoutHelper.PercentLayoutInfo mPercentLayoutInfo; 103 | 104 | public LayoutParams(Context c, AttributeSet attrs) { 105 | super(c, attrs); 106 | mPercentLayoutInfo = PercentLayoutHelper.getPercentLayoutInfo(c, attrs); 107 | } 108 | 109 | public LayoutParams(int width, int height) { 110 | super(width, height); 111 | } 112 | 113 | public LayoutParams(ViewGroup.LayoutParams source) { 114 | super(source); 115 | } 116 | 117 | public LayoutParams(MarginLayoutParams source) { 118 | super(source); 119 | } 120 | 121 | @Override 122 | public PercentLayoutHelper.PercentLayoutInfo getPercentLayoutInfo() { 123 | return mPercentLayoutInfo; 124 | } 125 | 126 | @Override 127 | protected void setBaseAttributes(TypedArray a, int widthAttr, int heightAttr) { 128 | PercentLayoutHelper.fetchWidthAndHeight(this, a, widthAttr, heightAttr); 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /percent-support-extends/src/main/main1.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /percent-support-extends/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /percent-support-extends/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | AndroidPercentSupportExtends 3 | 4 | -------------------------------------------------------------------------------- /percent_04.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/percent_04.gif -------------------------------------------------------------------------------- /percent_sw_sh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/percent_sw_sh.png -------------------------------------------------------------------------------- /percent_sw_sh_single.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/percent_sw_sh_single.png -------------------------------------------------------------------------------- /sc_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/sc_02.png -------------------------------------------------------------------------------- /sc_02_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/sc_02_full.png -------------------------------------------------------------------------------- /sc_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/sc_03.png -------------------------------------------------------------------------------- /sc_03_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hongyangAndroid/android-percent-support-extend/87a2fed084cf6b6b8adc26134215d11a5fbb36bf/sc_03_full.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':percent-support-extends', ':percent-support-extends-sample' 2 | --------------------------------------------------------------------------------