├── .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 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.idea/copyright/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/misc.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 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 | 1.7
51 |
52 |
53 |
54 |
55 |
56 |
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 |
5 |
6 |
7 |
8 |
9 |
10 |
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 |
7 |
8 |
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 | [](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 | 
14 | ## complex result
15 | 
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 | [](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 | 
519 | ## complex result
520 | 
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 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | generateDebugAndroidTestSources
19 | generateDebugSources
20 |
21 |
22 |
23 |
24 |
25 |
26 |
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 | [](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 | 
321 | ## complex result
322 | 
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 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | generateDebugAndroidTestSources
19 | generateDebugSources
20 |
21 |
22 |
23 |
24 |
25 |
26 |
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 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | generateDebugAndroidTestSources
19 | generateDebugSources
20 |
21 |
22 |
23 |
24 |
25 |
26 |
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 |
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 | * You need a {@link ViewGroup.LayoutParams} subclass in your ViewGroup that implements
48 | * {@link com.zhy.android.percent.support.PercentLayoutHelper.PercentLayoutParams}.
49 | * 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 | * Override
55 | * {@link ViewGroup.LayoutParams#setBaseAttributes(TypedArray, int, int)}
56 | * with a single line implementation {@code PercentLayoutHelper.fetchWidthAndHeight(this, a,
57 | * widthAttr, heightAttr);}
58 | * In your ViewGroup override {@link ViewGroup#generateLayoutParams(AttributeSet)} to return
59 | * your LayoutParams.
60 | * 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 | * 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 |
--------------------------------------------------------------------------------