Repository: hongyangAndroid/AndroidAutoLayout Branch: master Commit: d0045f33d2a9 Files: 133 Total size: 186.9 KB Directory structure: gitextract_nptwaebs/ ├── .gitignore ├── LICENSE ├── README.md ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── zhy/ │ │ └── com/ │ │ └── autolayout/ │ │ └── ApplicationTest.java │ └── main/ │ ├── AndroidManifest.xml │ ├── java/ │ │ └── zhy/ │ │ └── com/ │ │ └── autolayout/ │ │ └── MainActivity.java │ └── res/ │ ├── layout/ │ │ └── activity_main.xml │ ├── menu/ │ │ └── menu_main.xml │ ├── values/ │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── values-w820dp/ │ └── dimens.xml ├── autolayout/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── zhy/ │ │ └── com/ │ │ └── autolayout/ │ │ └── ApplicationTest.java │ └── main/ │ ├── AndroidManifest.xml │ ├── java/ │ │ └── com/ │ │ └── zhy/ │ │ └── autolayout/ │ │ ├── AutoFrameLayout.java │ │ ├── AutoLayoutActivity.java │ │ ├── AutoLayoutInfo.java │ │ ├── AutoLinearLayout.java │ │ ├── AutoRelativeLayout.java │ │ ├── attr/ │ │ │ ├── Attrs.java │ │ │ ├── AutoAttr.java │ │ │ ├── HeightAttr.java │ │ │ ├── MarginAttr.java │ │ │ ├── MarginBottomAttr.java │ │ │ ├── MarginLeftAttr.java │ │ │ ├── MarginRightAttr.java │ │ │ ├── MarginTopAttr.java │ │ │ ├── MaxHeightAttr.java │ │ │ ├── MaxWidthAttr.java │ │ │ ├── MinHeightAttr.java │ │ │ ├── MinWidthAttr.java │ │ │ ├── PaddingAttr.java │ │ │ ├── PaddingBottomAttr.java │ │ │ ├── PaddingLeftAttr.java │ │ │ ├── PaddingRightAttr.java │ │ │ ├── PaddingTopAttr.java │ │ │ ├── TextSizeAttr.java │ │ │ └── WidthAttr.java │ │ ├── config/ │ │ │ ├── AutoLayoutConifg.java │ │ │ └── UseLandscape.java │ │ ├── utils/ │ │ │ ├── AutoLayoutHelper.java │ │ │ ├── AutoUtils.java │ │ │ ├── DimenUtils.java │ │ │ ├── L.java │ │ │ └── ScreenUtils.java │ │ └── widget/ │ │ └── MetroLayout.java │ └── res/ │ └── values/ │ ├── attrs.xml │ ├── ids.xml │ └── strings.xml ├── autolayout-widget/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── zhy/ │ │ └── autolayout/ │ │ └── widget/ │ │ └── ApplicationTest.java │ └── main/ │ ├── AndroidManifest.xml │ ├── java/ │ │ └── com/ │ │ └── zhy/ │ │ └── autolayout/ │ │ └── widget/ │ │ ├── AutoActionMenuItemView.java │ │ ├── AutoCardView.java │ │ ├── AutoLayoutWidgetActivity.java │ │ ├── AutoRadioGroup.java │ │ ├── AutoTabLayout.java │ │ ├── AutoTableLayout.java │ │ ├── AutoTableRow.java │ │ └── AutoToolbar.java │ └── res/ │ └── values/ │ ├── attrs.xml │ └── strings.xml ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── sample/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── zhy/ │ │ └── sample/ │ │ └── ApplicationTest.java │ └── main/ │ ├── AndroidManifest.xml │ ├── java/ │ │ └── com/ │ │ └── zhy/ │ │ └── sample/ │ │ ├── CategoryActivity.java │ │ ├── MainActivity.java │ │ ├── UseDeviceSizeApplication.java │ │ ├── fragment/ │ │ │ ├── ListFragment.java │ │ │ ├── PayFragment.java │ │ │ ├── RecyclerViewFragment.java │ │ │ ├── RecyclerViewGridFragment.java │ │ │ ├── RegisterFragment.java │ │ │ ├── SimpleFragment.java │ │ │ └── TestFragment.java │ │ └── view/ │ │ ├── AutoCardView.java │ │ └── DividerItemDecoration.java │ └── res/ │ ├── drawable/ │ │ ├── selector_btn_stroke_orange.xml │ │ ├── selector_pay_radio.xml │ │ ├── shape_btn_edge_orange.xml │ │ ├── shape_btn_edge_orange_pre.xml │ │ └── shape_edit_stroke.xml │ ├── layout/ │ │ ├── activity_category.xml │ │ ├── activity_main.xml │ │ ├── activity_test.xml │ │ ├── app_base_title.xml │ │ ├── fragment_list.xml │ │ ├── fragment_pay.xml │ │ ├── fragment_recyclerview.xml │ │ ├── fragment_recyclerview_grid.xml │ │ ├── fragment_register.xml │ │ ├── list_item.xml │ │ ├── recyclerview_item.xml │ │ └── recyclerview_item_grid.xml │ ├── menu/ │ │ ├── menu_main.xml │ │ └── menu_test.xml │ ├── values/ │ │ ├── attrs.xml │ │ ├── color.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── values-w820dp/ │ └── dimens.xml ├── settings.gradle └── widgetsample/ ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src/ ├── androidTest/ │ └── java/ │ └── com/ │ └── zhy/ │ └── autolayout/ │ └── test/ │ └── widgets/ │ └── ApplicationTest.java └── main/ ├── AndroidManifest.xml ├── java/ │ └── com/ │ └── zhy/ │ └── autolayout/ │ └── test/ │ └── widgets/ │ ├── MainActivity.java │ └── fragments/ │ └── SimpleFragment.java └── res/ ├── layout/ │ ├── activity_main.xml │ └── fragment_simple.xml ├── menu/ │ └── menu_main.xml ├── values/ │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml └── values-w820dp/ └── dimens.xml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ /captures # Built application files *.apk *.ap_ # Generated files bin/ gen/ # Gradle files .gradle/ /build /*/build/ # Local configuration file (sdk path, etc) local.properties # Proguard folder generated by Eclipse proguard/ # Log Files *.log # Eclipse project files .classpath .project .settings/ # Intellij project files *.iml *.ipr *.iws .idea/ # System files .DS_Store ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright {yyyy} {name of copyright owner} Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README.md ================================================ # AndroidAutoLayout [DEPRECATED]Android屏幕适配方案,直接填写设计图上的像素尺寸即可完成适配。 >目前没有精力,已停止维护,使用前务必看明白代码,明确该方案可以解决自身问题,有扩展代码能力,否则不建议使用。 非常感谢 : 吃土豆的人 的协作。 >推荐使用[AndroidAutoSize](https://github.com/JessYanCoding/AndroidAutoSize) AndroidAutoSize目前作者一直在维护,私下也有一些交流,也是 AndroidAutoLayout 3年的使用者,自研了[AndroidAutoSize](https://github.com/JessYanCoding/AndroidAutoSize), 在目前本库已经没有精力维护的情况下,推荐使用;如果使用了本库,迁移成本也非常低,[迁移指南](https://github.com/JessYanCoding/AndroidAutoSize/issues/90)。 ## 效果图 最大幅度解决适配问题,并且最大化方便开发者。 so,看下用法: 你没有看错,拿到设计稿,在布局文件里面直接填写对应的px即可,px:这里的px并非是Google不建议使用的px,在内部会进行转化处理。 ok,拿一些实际项目的页面,看下不同分辨率下的效果: 左为:768 * 1280 ; 右为:1080 * 1920 上述两个机器的分辨率差距挺大了,但是完美实现了适配,最为重要的是: * 再也不用拿着设计稿去想这控件的宽高到底取多少dp * 再也不用去为多个屏幕去写多个dimens * 再也不用去计算百分比了(如果使用百分比控件完成适配) * 再也不用去跟UI MM去解释什么是dp了 你所要做的就是抄抄设计稿上面的px,直接写入布局文件。 还有很多好处,比如上面的Item里面元素比较多,如果标识的比较全面,一个FrameLayout,里面的View填写各种marginLeft,marginTop就能完美实现,几乎不需要嵌套了。 ## 引入 * Android Studio 将[autolayout](autolayout)引入 ```xml dependencies { compile project(':autolayout') } ``` 也可以直接 ``` dependencies { compile 'com.zhy:autolayout:1.4.5' } ``` * Eclipse 建议使用As,方便版本更新。实在不行,只有复制粘贴源码了。 ## 用法 ### 第一步: 在你的项目的AndroidManifest中注明你的`设计稿`的尺寸。 ```xml ``` ### 第二步: 让你的Activity继承自`AutoLayoutActivity`. 非常简单的两个步骤,你就可以开始愉快的编写布局了,详细可以参考sample。 ## 其他用法 如果你不希望继承`AutoLayoutActivity`,可以在编写布局文件时,将 * LinearLayout -> AutoLinearLayout * RelativeLayout -> AutoRelativeLayout * FrameLayout -> AutoFrameLayout 这样也可以完成适配。 ## 目前支持属性 * layout_width * layout_height * layout_margin(left,top,right,bottom) * pading(left,top,right,bottom) * textSize * maxWidth, minWidth, maxHeight, minHeight ## 配置 默认使用的高度是设备的可用高度,也就是不包括状态栏和底部的操作栏的,如果你希望拿设备的物理高度进行百分比化: 可以在Application的onCreate方法中进行设置: ```java public class UseDeviceSizeApplication extends Application { @Override public void onCreate() { super.onCreate(); AutoLayoutConifg.getInstance().useDeviceSize(); } } ``` ## 预览 大家都知道,写布局文件的时候,不能实时的去预览效果,那么体验真的是非常的不好,也在很大程度上降低开发效率,所以下面教大家如何用好,用对PreView(针对该库)。 首先,你要记得你设计稿的尺寸,比如 `768 * 1280` 然后在你的PreView面板,选择于设计图分辨率一致的设备: 然后你就可以看到`最为精确的`预览了: 两个注意事项: 1. 你们UI给的设计图的尺寸并非是主流的设计图,该尺寸没找到,你可以自己去新建一个设备。 2. 不要在PreView中去查看所有分辨率下的显示,是看不出来适配效果的,因为有些计算是动态的。 ## 扩展 对于其他继承系统的FrameLayout、LinearLayout、RelativeLayout的控件,比如`CardView`,如果希望再其内部直接支持"px"百分比化,可以自己扩展,扩展方式为下面的代码,也可参考[issue#21](https://github.com/hongyangAndroid/AndroidAutoLayout/issues/21): ``` package com.zhy.sample.view; import android.content.Context; import android.support.v7.widget.CardView; import android.util.AttributeSet; import com.zhy.autolayout.AutoFrameLayout; import com.zhy.autolayout.utils.AutoLayoutHelper; /** * Created by zhy on 15/12/8. */ public class AutoCardView extends CardView { private final AutoLayoutHelper mHelper = new AutoLayoutHelper(this); public AutoCardView(Context context) { super(context); } public AutoCardView(Context context, AttributeSet attrs) { super(context, attrs); } public AutoCardView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public AutoFrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) { return new AutoFrameLayout.LayoutParams(getContext(), attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!isInEditMode()) { mHelper.adjustChildren(); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } ``` ## 注意事项 ### ListView、RecyclerView类的Item的适配 **sample中包含ListView、RecyclerView例子,具体查看sample** * 对于ListView 对于ListView这类控件的item,默认根局部写“px”进行适配是无效的,因为外层非AutoXXXLayout,而是ListView。但是,不用怕,一行代码就可以支持了: ```java @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false); convertView.setTag(holder); //对于listview,注意添加这一行,即可在item上使用高度 AutoUtils.autoSize(convertView); } else { holder = (ViewHolder) convertView.getTag(); } return convertView; } ``` 注意` AutoUtils.autoSize(convertView);`这行代码的位置即可。demo中也有相关实例。 * 对于RecyclerView ```java public ViewHolder(View itemView) { super(itemView); AutoUtils.autoSize(itemView); } //... @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View convertView = LayoutInflater.from(mContext).inflate(R.layout.recyclerview_item, parent, false); return new ViewHolder(convertView); } ``` 一定要记得`LayoutInflater.from(mContext).inflate`使用三个参数的方法! ### 指定设置的值参考宽度或者高度 由于该库的特点,布局文件中宽高上的1px是不相等的,于是如果需要宽高保持一致的情况,布局中使用属性: `app:layout_auto_basewidth="height"`,代表height上编写的像素值参考宽度。 `app:layout_auto_baseheight="width"`,代表width上编写的像素值参考高度。 如果需要指定多个值参考宽度即: `app:layout_auto_basewidth="height|padding"` 用|隔开,类似gravity的用法,取值为: * width,height * margin,marginLeft,marginTop,marginRight,marginBottom * padding,paddingLeft,paddingTop,paddingRight,paddingBottom * textSize. ### TextView的高度问题 设计稿一般只会标识一个字体的大小,比如你设置textSize="20px",实际上TextView所占据的高度肯定大于20px,字的上下都会有一定的间隙,所以一定要灵活去写字体的高度,比如对于text上下的margin可以选择尽可能小一点。或者选择别的约束条件去定位(比如上例,选择了marginBottom) ## 常见问题 ###(1)导入后出现`org/gradle/api/publication/maven/internal/DefaultMavenFactory` 最简单的方式,通过`compile 'com.zhy:autolayout:x.x.x'`进行依赖使用,如果一定要以module引用,参考该issue[#74](https://github.com/hongyangAndroid/AndroidAutoLayout/issues/74) ###(2)RadioGroup,Toolbar等控件中的子View无法完成适配 这个其实上文已经提到过了,需要自己扩展。不过这个很多使用者贡献了他们的扩展类可以直接使用, 参考[autolayout-widget](https://github.com/hongyangAndroid/AndroidAutoLayout/tree/master/widgetsample), 如果没有发现你需要的容器类,那么你就真的需要自行扩展了,当然如果你完成了扩展,可以给我发个PR,或者让我知道,我可以加入到 `autolayout-widget`中方便他人,ps:需要用到哪个copy就好了,不要直接引用`autolayout-widget`,因为其引用了大量的库,可能很多 库你是用不到的。 ###(3)java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity. 这个问题是因为默认AutoLayoutActivity会继承自AppCompatActivity,所以默认需要设置 Theme.AppCompat的theme; 如果你使用的依旧是FragmentActivity等,且不考虑使用AppCompatActivity, 你可以选择自己编写一个`MyAutoLayoutActivity extends 目前你使用的Activity基类`,例如 `MyAutoLayoutActivity extends FragmentActivity`,然后将该库中AutoLayoutActivity中的逻辑 拷贝进去即可,以后你就继承你的`MyAutoLayoutActivity`就好了。 ps:还是建议尽快更新SDK版本使用`AppCompatActivity`. ## 其他信息 作者信息: * [hongyangAndroid](https://github.com/hongyangAndroid) * 吃土豆的人 灵感来自: * [android-percent-support-lib-sample](https://github.com/JulienGenoud/android-percent-support-lib-sample) * [android-percent-support-extend](https://github.com/hongyangAndroid/android-percent-support-extend) * [Android 屏幕适配方案](http://blog.csdn.net/lmj623565791/article/details/45460089) ================================================ FILE: app/.gitignore ================================================ /build ================================================ FILE: app/build.gradle ================================================ apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.1" defaultConfig { applicationId "zhy.com.autolayout" minSdkVersion 10 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.1.0' } ================================================ FILE: app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in /Users/zhy/android/sdk/android-sdk-macosx/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} ================================================ FILE: app/src/androidTest/java/zhy/com/autolayout/ApplicationTest.java ================================================ package zhy.com.autolayout; import android.app.Application; import android.test.ApplicationTestCase; /** * Testing Fundamentals */ public class ApplicationTest extends ApplicationTestCase { public ApplicationTest() { super(Application.class); } } ================================================ FILE: app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: app/src/main/java/zhy/com/autolayout/MainActivity.java ================================================ package zhy.com.autolayout; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } } ================================================ FILE: app/src/main/res/layout/activity_main.xml ================================================ ================================================ FILE: app/src/main/res/menu/menu_main.xml ================================================ ================================================ FILE: app/src/main/res/values/dimens.xml ================================================ 16dp 16dp ================================================ FILE: app/src/main/res/values/strings.xml ================================================ AutoLayout Hello world! Settings ================================================ FILE: app/src/main/res/values/styles.xml ================================================ ================================================ FILE: app/src/main/res/values-w820dp/dimens.xml ================================================ 64dp ================================================ FILE: autolayout/.gitignore ================================================ /build ================================================ FILE: autolayout/build.gradle ================================================ apply plugin: 'com.android.library' apply plugin: 'com.github.dcendents.android-maven' apply plugin: 'com.jfrog.bintray' version = "1.4.5" android { compileSdkVersion 23 buildToolsVersion "23.0.1" defaultConfig { minSdkVersion 7 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } def siteUrl = 'https://github.com/hongyangAndroid/AndroidAutoLayout' // #CONFIG# // project homepage def gitUrl = 'https://github.com/hongyangAndroid/AndroidAutoLayout.git' // #CONFIG# // project git group = "com.zhy" install { repositories.mavenInstaller { // This generates POM.xml with proper parameters pom { project { packaging 'aar' name 'AutoLayout' // #CONFIG# // project title url siteUrl // Set your license licenses { license { name 'The Apache Software License, Version 2.0' url 'http://www.apache.org/licenses/LICENSE-2.0.txt' } } developers { developer { id 'hongyangAndroid' // #CONFIG# // your user id (you can write your nickname) name 'ZhangHongyang' // #CONFIG# // your user name email '623565791@qq.com' // #CONFIG# // your email } } scm { connection gitUrl developerConnection gitUrl url siteUrl } } } } } task sourcesJar(type: Jar) { from android.sourceSets.main.java.srcDirs classifier = 'sources' } task javadoc(type: Javadoc) { source = android.sourceSets.main.java.srcDirs classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) } task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' from javadoc.destinationDir } artifacts { archives javadocJar archives sourcesJar } Properties properties = new Properties() properties.load(project.rootProject.file('local.properties').newDataInputStream()) bintray { user = properties.getProperty("bintray.user") key = properties.getProperty("bintray.apikey") configurations = ['archives'] pkg { repo = "maven" name = "autolayout" // #CONFIG# project name in jcenter websiteUrl = siteUrl vcsUrl = gitUrl licenses = ["Apache-2.0"] publish = true } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.0.1' } ================================================ FILE: autolayout/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in /Users/zhy/android/sdk/android-sdk-macosx/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} ================================================ FILE: autolayout/src/androidTest/java/zhy/com/autolayout/ApplicationTest.java ================================================ package zhy.com.autolayout; import android.app.Application; import android.test.ApplicationTestCase; /** * Testing Fundamentals */ public class ApplicationTest extends ApplicationTestCase { public ApplicationTest() { super(Application.class); } } ================================================ FILE: autolayout/src/main/AndroidManifest.xml ================================================ ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/AutoFrameLayout.java ================================================ /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zhy.autolayout; import android.annotation.TargetApi; import android.content.Context; import android.os.Build; import android.util.AttributeSet; import android.view.ViewGroup; import android.widget.FrameLayout; import com.zhy.autolayout.utils.AutoLayoutHelper; public class AutoFrameLayout extends FrameLayout { private final AutoLayoutHelper mHelper = new AutoLayoutHelper(this); public AutoFrameLayout(Context context) { super(context); } public AutoFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); } public AutoFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public AutoFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new LayoutParams(getContext(), attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!isInEditMode()) { mHelper.adjustChildren(); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } public static class LayoutParams extends FrameLayout.LayoutParams implements AutoLayoutHelper.AutoLayoutParams { private AutoLayoutInfo mAutoLayoutInfo; public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs); } public LayoutParams(int width, int height) { super(width, height); } public LayoutParams(int width, int height, int gravity) { super(width, height, gravity); } public LayoutParams(ViewGroup.LayoutParams source) { super(source); } public LayoutParams(MarginLayoutParams source) { super(source); } public LayoutParams(FrameLayout.LayoutParams source) { super((MarginLayoutParams) source); gravity = source.gravity; } public LayoutParams(LayoutParams source) { this((FrameLayout.LayoutParams) source); mAutoLayoutInfo = source.mAutoLayoutInfo; } @Override public AutoLayoutInfo getAutoLayoutInfo() { return mAutoLayoutInfo; } } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/AutoLayoutActivity.java ================================================ package com.zhy.autolayout; import android.content.Context; import android.support.v7.app.AppCompatActivity; import android.util.AttributeSet; import android.view.View; ; /** * Created by zhy on 15/11/19. */ public class AutoLayoutActivity extends AppCompatActivity { private static final String LAYOUT_LINEARLAYOUT = "LinearLayout"; private static final String LAYOUT_FRAMELAYOUT = "FrameLayout"; private static final String LAYOUT_RELATIVELAYOUT = "RelativeLayout"; @Override public View onCreateView(String name, Context context, AttributeSet attrs) { View view = null; if (name.equals(LAYOUT_FRAMELAYOUT)) { view = new AutoFrameLayout(context, attrs); } if (name.equals(LAYOUT_LINEARLAYOUT)) { view = new AutoLinearLayout(context, attrs); } if (name.equals(LAYOUT_RELATIVELAYOUT)) { view = new AutoRelativeLayout(context, attrs); } if (view != null) return view; return super.onCreateView(name, context, attrs); } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/AutoLayoutInfo.java ================================================ package com.zhy.autolayout; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.zhy.autolayout.attr.Attrs; import com.zhy.autolayout.attr.AutoAttr; import com.zhy.autolayout.attr.HeightAttr; import com.zhy.autolayout.attr.MarginBottomAttr; import com.zhy.autolayout.attr.MarginLeftAttr; import com.zhy.autolayout.attr.MarginRightAttr; import com.zhy.autolayout.attr.MarginTopAttr; import com.zhy.autolayout.attr.MaxHeightAttr; import com.zhy.autolayout.attr.MaxWidthAttr; import com.zhy.autolayout.attr.MinHeightAttr; import com.zhy.autolayout.attr.MinWidthAttr; import com.zhy.autolayout.attr.PaddingBottomAttr; import com.zhy.autolayout.attr.PaddingLeftAttr; import com.zhy.autolayout.attr.PaddingRightAttr; import com.zhy.autolayout.attr.PaddingTopAttr; import com.zhy.autolayout.attr.TextSizeAttr; import com.zhy.autolayout.attr.WidthAttr; import java.util.ArrayList; import java.util.List; public class AutoLayoutInfo { private List autoAttrs = new ArrayList<>(); public void addAttr(AutoAttr autoAttr) { autoAttrs.add(autoAttr); } public void fillAttrs(View view) { for (AutoAttr autoAttr : autoAttrs) { autoAttr.apply(view); } } public static AutoLayoutInfo getAttrFromView(View view, int attrs, int base) { ViewGroup.LayoutParams params = view.getLayoutParams(); if (params == null) return null; AutoLayoutInfo autoLayoutInfo = new AutoLayoutInfo(); // width & height if ((attrs & Attrs.WIDTH) != 0 && params.width > 0) { autoLayoutInfo.addAttr(WidthAttr.generate(params.width, base)); } if ((attrs & Attrs.HEIGHT) != 0 && params.height > 0) { autoLayoutInfo.addAttr(HeightAttr.generate(params.height, base)); } //margin if (params instanceof ViewGroup.MarginLayoutParams) { if ((attrs & Attrs.MARGIN) != 0) { autoLayoutInfo.addAttr(MarginLeftAttr.generate(((ViewGroup.MarginLayoutParams) params).leftMargin, base)); autoLayoutInfo.addAttr(MarginTopAttr.generate(((ViewGroup.MarginLayoutParams) params).topMargin, base)); autoLayoutInfo.addAttr(MarginRightAttr.generate(((ViewGroup.MarginLayoutParams) params).rightMargin, base)); autoLayoutInfo.addAttr(MarginBottomAttr.generate(((ViewGroup.MarginLayoutParams) params).bottomMargin, base)); } if ((attrs & Attrs.MARGIN_LEFT) != 0) { autoLayoutInfo.addAttr(MarginLeftAttr.generate(((ViewGroup.MarginLayoutParams) params).leftMargin, base)); } if ((attrs & Attrs.MARGIN_TOP) != 0) { autoLayoutInfo.addAttr(MarginTopAttr.generate(((ViewGroup.MarginLayoutParams) params).topMargin, base)); } if ((attrs & Attrs.MARGIN_RIGHT) != 0) { autoLayoutInfo.addAttr(MarginRightAttr.generate(((ViewGroup.MarginLayoutParams) params).rightMargin, base)); } if ((attrs & Attrs.MARGIN_BOTTOM) != 0) { autoLayoutInfo.addAttr(MarginBottomAttr.generate(((ViewGroup.MarginLayoutParams) params).bottomMargin, base)); } } //padding if ((attrs & Attrs.PADDING) != 0) { autoLayoutInfo.addAttr(PaddingLeftAttr.generate(view.getPaddingLeft(), base)); autoLayoutInfo.addAttr(PaddingTopAttr.generate(view.getPaddingTop(), base)); autoLayoutInfo.addAttr(PaddingRightAttr.generate(view.getPaddingRight(), base)); autoLayoutInfo.addAttr(PaddingBottomAttr.generate(view.getPaddingBottom(), base)); } if ((attrs & Attrs.PADDING_LEFT) != 0) { autoLayoutInfo.addAttr(MarginLeftAttr.generate(view.getPaddingLeft(), base)); } if ((attrs & Attrs.PADDING_TOP) != 0) { autoLayoutInfo.addAttr(MarginTopAttr.generate(view.getPaddingTop(), base)); } if ((attrs & Attrs.PADDING_RIGHT) != 0) { autoLayoutInfo.addAttr(MarginRightAttr.generate(view.getPaddingRight(), base)); } if ((attrs & Attrs.PADDING_BOTTOM) != 0) { autoLayoutInfo.addAttr(MarginBottomAttr.generate(view.getPaddingBottom(), base)); } //minWidth ,maxWidth , minHeight , maxHeight if ((attrs & Attrs.MIN_WIDTH) != 0) { autoLayoutInfo.addAttr(MinWidthAttr.generate(MinWidthAttr.getMinWidth(view), base)); } if ((attrs & Attrs.MAX_WIDTH) != 0) { autoLayoutInfo.addAttr(MaxWidthAttr.generate(MaxWidthAttr.getMaxWidth(view), base)); } if ((attrs & Attrs.MIN_HEIGHT) != 0) { autoLayoutInfo.addAttr(MinHeightAttr.generate(MinHeightAttr.getMinHeight(view), base)); } if ((attrs & Attrs.MAX_HEIGHT) != 0) { autoLayoutInfo.addAttr(MaxHeightAttr.generate(MaxHeightAttr.getMaxHeight(view), base)); } //textsize if (view instanceof TextView) { if ((attrs & Attrs.TEXTSIZE) != 0) { autoLayoutInfo.addAttr(TextSizeAttr.generate((int) ((TextView) view).getTextSize(), base)); } } return autoLayoutInfo; } @Override public String toString() { return "AutoLayoutInfo{" + "autoAttrs=" + autoAttrs + '}'; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/AutoLinearLayout.java ================================================ package com.zhy.autolayout; import android.annotation.TargetApi; import android.content.Context; import android.os.Build; import android.util.AttributeSet; import android.view.ViewGroup; import android.widget.LinearLayout; import com.zhy.autolayout.utils.AutoLayoutHelper; /** * Created by zhy on 15/6/30. */ public class AutoLinearLayout extends LinearLayout { private AutoLayoutHelper mHelper = new AutoLayoutHelper(this); public AutoLinearLayout(Context context) { super(context); } public AutoLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); } @TargetApi(Build.VERSION_CODES.HONEYCOMB) public AutoLinearLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public AutoLinearLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!isInEditMode()) mHelper.adjustChildren(); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new AutoLinearLayout.LayoutParams(getContext(), attrs); } public static class LayoutParams extends LinearLayout.LayoutParams implements AutoLayoutHelper.AutoLayoutParams { private AutoLayoutInfo mAutoLayoutInfo; public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs); } @Override public AutoLayoutInfo getAutoLayoutInfo() { return mAutoLayoutInfo; } public LayoutParams(int width, int height) { super(width, height); } public LayoutParams(ViewGroup.LayoutParams source) { super(source); } public LayoutParams(MarginLayoutParams source) { super(source); } } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/AutoRelativeLayout.java ================================================ /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zhy.autolayout; import android.annotation.TargetApi; import android.content.Context; import android.os.Build; import android.util.AttributeSet; import android.view.ViewGroup; import android.widget.RelativeLayout; import com.zhy.autolayout.utils.AutoLayoutHelper; public class AutoRelativeLayout extends RelativeLayout { private final AutoLayoutHelper mHelper = new AutoLayoutHelper(this); public AutoRelativeLayout(Context context) { super(context); } public AutoRelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); } public AutoRelativeLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public AutoRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new LayoutParams(getContext(), attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!isInEditMode()) mHelper.adjustChildren(); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } public static class LayoutParams extends RelativeLayout.LayoutParams implements AutoLayoutHelper.AutoLayoutParams { private AutoLayoutInfo mAutoLayoutInfo; public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs); } public LayoutParams(int width, int height) { super(width, height); } public LayoutParams(ViewGroup.LayoutParams source) { super(source); } public LayoutParams(MarginLayoutParams source) { super(source); } @Override public AutoLayoutInfo getAutoLayoutInfo() { return mAutoLayoutInfo; } } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/Attrs.java ================================================ package com.zhy.autolayout.attr; /** * Created by zhy on 15/12/5. *

* 与attrs.xml中数值对应 */ public interface Attrs { public static final int WIDTH = 1; public static final int HEIGHT = WIDTH << 1; public static final int TEXTSIZE = HEIGHT << 1; public static final int PADDING = TEXTSIZE << 1; public static final int MARGIN = PADDING << 1; public static final int MARGIN_LEFT = MARGIN << 1; public static final int MARGIN_TOP = MARGIN_LEFT << 1; public static final int MARGIN_RIGHT = MARGIN_TOP << 1; public static final int MARGIN_BOTTOM = MARGIN_RIGHT << 1; public static final int PADDING_LEFT = MARGIN_BOTTOM << 1; public static final int PADDING_TOP = PADDING_LEFT << 1; public static final int PADDING_RIGHT = PADDING_TOP << 1; public static final int PADDING_BOTTOM = PADDING_RIGHT << 1; public static final int MIN_WIDTH = PADDING_BOTTOM << 1; public static final int MAX_WIDTH = MIN_WIDTH << 1; public static final int MIN_HEIGHT = MAX_WIDTH << 1; public static final int MAX_HEIGHT = MIN_HEIGHT << 1; } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/AutoAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; import com.zhy.autolayout.utils.AutoUtils; import com.zhy.autolayout.utils.L; /** * Created by zhy on 15/12/4. */ public abstract class AutoAttr { public static final int BASE_WIDTH = 1; public static final int BASE_HEIGHT = 2; public static final int BASE_DEFAULT = 3; protected int pxVal; protected int baseWidth; protected int baseHeight; /* protected boolean isBaseWidth; protected boolean isBaseDefault; public AutoAttr(int pxVal) { this.pxVal = pxVal; isBaseDefault = true; } public AutoAttr(int pxVal, boolean isBaseWidth) { this.pxVal = pxVal; this.isBaseWidth = isBaseWidth; } */ public AutoAttr(int pxVal, int baseWidth, int baseHeight) { this.pxVal = pxVal; this.baseWidth = baseWidth; this.baseHeight = baseHeight; } public void apply(View view) { boolean log = view.getTag() != null && view.getTag().toString().equals("auto"); if (log) { L.e(" pxVal = " + pxVal + " ," + this.getClass().getSimpleName()); } int val; if (useDefault()) { val = defaultBaseWidth() ? getPercentWidthSize() : getPercentHeightSize(); if (log) { L.e(" useDefault val= " + val); } } else if (baseWidth()) { val = getPercentWidthSize(); if (log) { L.e(" baseWidth val= " + val); } } else { val = getPercentHeightSize(); if (log) { L.e(" baseHeight val= " + val); } } if (val > 0) val = Math.max(val, 1);//for very thin divider execute(view, val); } protected int getPercentWidthSize() { return AutoUtils.getPercentWidthSizeBigger(pxVal); } protected int getPercentHeightSize() { return AutoUtils.getPercentHeightSizeBigger(pxVal); } protected boolean baseWidth() { return contains(baseWidth, attrVal()); } protected boolean useDefault() { return !contains(baseHeight, attrVal()) && !contains(baseWidth, attrVal()); } protected boolean contains(int baseVal, int flag) { return (baseVal & flag) != 0; } protected abstract int attrVal(); protected abstract boolean defaultBaseWidth(); protected abstract void execute(View view, int val); @Override public String toString() { return "AutoAttr{" + "pxVal=" + pxVal + ", baseWidth=" + baseWidth() + ", defaultBaseWidth=" + defaultBaseWidth() + '}'; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/HeightAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; import android.view.ViewGroup; /** * Created by zhy on 15/12/5. */ public class HeightAttr extends AutoAttr { public HeightAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.HEIGHT; } @Override protected boolean defaultBaseWidth() { return false; } @Override protected void execute(View view, int val) { ViewGroup.LayoutParams lp = view.getLayoutParams(); lp.height = val; } public static HeightAttr generate(int val, int baseFlag) { HeightAttr heightAttr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: heightAttr = new HeightAttr(val, Attrs.HEIGHT, 0); break; case AutoAttr.BASE_HEIGHT: heightAttr = new HeightAttr(val, 0, Attrs.HEIGHT); break; case AutoAttr.BASE_DEFAULT: heightAttr = new HeightAttr(val, 0, 0); break; } return heightAttr; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/MarginAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; import android.view.ViewGroup; /** * Created by zhy on 15/12/5. */ public class MarginAttr extends AutoAttr { public MarginAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.MARGIN; } @Override protected boolean defaultBaseWidth() { return false; } @Override public void apply(View view) { if (!(view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams)) { return; } if (useDefault()) { ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams(); lp.leftMargin = lp.rightMargin = getPercentWidthSize(); lp.topMargin = lp.bottomMargin = getPercentHeightSize(); return; } super.apply(view); } @Override protected void execute(View view, int val) { ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams(); lp.leftMargin = lp.rightMargin = lp.topMargin = lp.bottomMargin = val; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/MarginBottomAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; import android.view.ViewGroup; /** * Created by zhy on 15/12/5. */ public class MarginBottomAttr extends AutoAttr { public MarginBottomAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.MARGIN_BOTTOM; } @Override protected boolean defaultBaseWidth() { return false; } @Override protected void execute(View view, int val) { if(!(view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams)) { return ; } ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams(); lp.bottomMargin = val; } public static MarginBottomAttr generate(int val, int baseFlag) { MarginBottomAttr attr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: attr = new MarginBottomAttr(val, Attrs.MARGIN_BOTTOM, 0); break; case AutoAttr.BASE_HEIGHT: attr = new MarginBottomAttr(val, 0, Attrs.MARGIN_BOTTOM); break; case AutoAttr.BASE_DEFAULT: attr = new MarginBottomAttr(val, 0, 0); break; } return attr; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/MarginLeftAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; import android.view.ViewGroup; /** * Created by zhy on 15/12/5. */ public class MarginLeftAttr extends AutoAttr { public MarginLeftAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.MARGIN_LEFT; } @Override protected boolean defaultBaseWidth() { return true; } @Override protected void execute(View view, int val) { if (!(view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams)) { return; } ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams(); lp.leftMargin = val; } public static MarginLeftAttr generate(int val, int baseFlag) { MarginLeftAttr attr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: attr = new MarginLeftAttr(val, Attrs.MARGIN_LEFT, 0); break; case AutoAttr.BASE_HEIGHT: attr = new MarginLeftAttr(val, 0, Attrs.MARGIN_LEFT); break; case AutoAttr.BASE_DEFAULT: attr = new MarginLeftAttr(val, 0, 0); break; } return attr; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/MarginRightAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; import android.view.ViewGroup; /** * Created by zhy on 15/12/5. */ public class MarginRightAttr extends AutoAttr { public MarginRightAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.MARGIN_RIGHT; } @Override protected boolean defaultBaseWidth() { return true; } @Override protected void execute(View view, int val) { if (!(view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams)) { return; } ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams(); lp.rightMargin = val; } public static MarginRightAttr generate(int val, int baseFlag) { MarginRightAttr attr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: attr = new MarginRightAttr(val, Attrs.MARGIN_RIGHT, 0); break; case AutoAttr.BASE_HEIGHT: attr = new MarginRightAttr(val, 0, Attrs.MARGIN_RIGHT); break; case AutoAttr.BASE_DEFAULT: attr = new MarginRightAttr(val, 0, 0); break; } return attr; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/MarginTopAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; import android.view.ViewGroup; /** * Created by zhy on 15/12/5. */ public class MarginTopAttr extends AutoAttr { public MarginTopAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.MARGIN_TOP; } @Override protected boolean defaultBaseWidth() { return false; } @Override protected void execute(View view, int val) { if (!(view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams)) { return; } ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view.getLayoutParams(); lp.topMargin = val; } public static MarginTopAttr generate(int val, int baseFlag) { MarginTopAttr attr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: attr = new MarginTopAttr(val, Attrs.MARGIN_TOP, 0); break; case AutoAttr.BASE_HEIGHT: attr = new MarginTopAttr(val, 0, Attrs.MARGIN_TOP); break; case AutoAttr.BASE_DEFAULT: attr = new MarginTopAttr(val, 0, 0); break; } return attr; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/MaxHeightAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; import java.lang.reflect.Method; /** * Created by zhy on 15/12/24. */ public class MaxHeightAttr extends AutoAttr { public MaxHeightAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.MAX_HEIGHT; } @Override protected boolean defaultBaseWidth() { return false; } @Override protected void execute(View view, int val) { try { Method setMaxWidthMethod = view.getClass().getMethod("setMaxHeight", int.class); setMaxWidthMethod.invoke(view, val); } catch (Exception ignore) { } } public static MaxHeightAttr generate(int val, int baseFlag) { MaxHeightAttr attr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: attr = new MaxHeightAttr(val, Attrs.MAX_HEIGHT, 0); break; case AutoAttr.BASE_HEIGHT: attr = new MaxHeightAttr(val, 0, Attrs.MAX_HEIGHT); break; case AutoAttr.BASE_DEFAULT: attr = new MaxHeightAttr(val, 0, 0); break; } return attr; } public static int getMaxHeight(View view) { try { Method setMaxWidthMethod = view.getClass().getMethod("getMaxHeight"); return (int) setMaxWidthMethod.invoke(view); } catch (Exception ignore) { } return 0; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/MaxWidthAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; import java.lang.reflect.Method; /** * Created by zhy on 15/12/24. */ public class MaxWidthAttr extends AutoAttr { public MaxWidthAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.MAX_WIDTH; } @Override protected boolean defaultBaseWidth() { return true; } @Override protected void execute(View view, int val) { try { Method setMaxWidthMethod = view.getClass().getMethod("setMaxWidth", int.class); setMaxWidthMethod.invoke(view, val); } catch (Exception ignore) { } } public static MaxWidthAttr generate(int val, int baseFlag) { MaxWidthAttr attr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: attr = new MaxWidthAttr(val, Attrs.MAX_WIDTH, 0); break; case AutoAttr.BASE_HEIGHT: attr = new MaxWidthAttr(val, 0, Attrs.MAX_WIDTH); break; case AutoAttr.BASE_DEFAULT: attr = new MaxWidthAttr(val, 0, 0); break; } return attr; } public static int getMaxWidth(View view) { try { Method setMaxWidthMethod = view.getClass().getMethod("getMaxWidth"); return (int) setMaxWidthMethod.invoke(view); } catch (Exception ignore) { } return 0; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/MinHeightAttr.java ================================================ package com.zhy.autolayout.attr; import android.os.Build; import android.view.View; import java.lang.reflect.Field; /** * Created by zhy on 15/12/24. */ public class MinHeightAttr extends AutoAttr { public MinHeightAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.MIN_HEIGHT; } @Override protected boolean defaultBaseWidth() { return false; } @Override protected void execute(View view, int val) { try { view.setMinimumHeight(val); // Method setMaxWidthMethod = view.getClass().getMethod("setMinHeight", int.class); // setMaxWidthMethod.invoke(view, val); } catch (Exception ignore) { } } public static MinHeightAttr generate(int val, int baseFlag) { MinHeightAttr attr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: attr = new MinHeightAttr(val, Attrs.MIN_HEIGHT, 0); break; case AutoAttr.BASE_HEIGHT: attr = new MinHeightAttr(val, 0, Attrs.MIN_HEIGHT); break; case AutoAttr.BASE_DEFAULT: attr = new MinHeightAttr(val, 0, 0); break; } return attr; } public static int getMinHeight(View view) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { return view.getMinimumHeight(); } else { try { Field minHeight = view.getClass().getField("mMinHeight"); minHeight.setAccessible(true); return (int) minHeight.get(view); } catch (Exception e) { } } return 0; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/MinWidthAttr.java ================================================ package com.zhy.autolayout.attr; import android.os.Build; import android.view.View; import java.lang.reflect.Field; /** * Created by zhy on 15/12/24. */ public class MinWidthAttr extends AutoAttr { public MinWidthAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.MIN_WIDTH; } @Override protected boolean defaultBaseWidth() { return true; } @Override protected void execute(View view, int val) { try { // Method setMaxWidthMethod = view.getClass().getMethod("setMinWidth", int.class); // setMaxWidthMethod.invoke(view, val); } catch (Exception ignore) { } view.setMinimumWidth(val); } public static int getMinWidth(View view) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) return view.getMinimumWidth(); try { Field minWidth = view.getClass().getField("mMinWidth"); minWidth.setAccessible(true); return (int) minWidth.get(view); } catch (Exception ignore) { } return 0; } public static MinWidthAttr generate(int val, int baseFlag) { MinWidthAttr attr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: attr = new MinWidthAttr(val, Attrs.MIN_WIDTH, 0); break; case AutoAttr.BASE_HEIGHT: attr = new MinWidthAttr(val, 0, Attrs.MIN_WIDTH); break; case AutoAttr.BASE_DEFAULT: attr = new MinWidthAttr(val, 0, 0); break; } return attr; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/PaddingAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; /** * Created by zhy on 15/12/5. */ public class PaddingAttr extends AutoAttr { public PaddingAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.PADDING; } @Override public void apply(View view) { int l, t, r, b; if (useDefault()) { l = r = getPercentWidthSize(); t = b = getPercentHeightSize(); view.setPadding(l, t, r, b); return; } super.apply(view); } @Override protected boolean defaultBaseWidth() { return false; } @Override protected void execute(View view, int val) { view.setPadding(val, val, val, val); } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/PaddingBottomAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; /** * Created by zhy on 15/12/5. */ public class PaddingBottomAttr extends AutoAttr { public PaddingBottomAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.PADDING_BOTTOM; } @Override protected boolean defaultBaseWidth() { return false; } @Override protected void execute(View view, int val) { int l = view.getPaddingLeft(); int t = view.getPaddingTop(); int r = view.getPaddingRight(); int b = val; view.setPadding(l, t, r, b); } public static PaddingBottomAttr generate(int val, int baseFlag) { PaddingBottomAttr attr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: attr = new PaddingBottomAttr(val, Attrs.PADDING_BOTTOM, 0); break; case AutoAttr.BASE_HEIGHT: attr = new PaddingBottomAttr(val, 0, Attrs.PADDING_BOTTOM); break; case AutoAttr.BASE_DEFAULT: attr = new PaddingBottomAttr(val, 0, 0); break; } return attr; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/PaddingLeftAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; /** * Created by zhy on 15/12/5. */ public class PaddingLeftAttr extends AutoAttr { public PaddingLeftAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.PADDING_LEFT; } @Override protected boolean defaultBaseWidth() { return true; } @Override protected void execute(View view, int val) { int l = val; int t = view.getPaddingTop(); int r = view.getPaddingRight(); int b = view.getPaddingBottom(); view.setPadding(l, t, r, b); } public static PaddingLeftAttr generate(int val, int baseFlag) { PaddingLeftAttr attr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: attr = new PaddingLeftAttr(val, Attrs.PADDING_LEFT, 0); break; case AutoAttr.BASE_HEIGHT: attr = new PaddingLeftAttr(val, 0, Attrs.PADDING_LEFT); break; case AutoAttr.BASE_DEFAULT: attr = new PaddingLeftAttr(val, 0, 0); break; } return attr; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/PaddingRightAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; /** * Created by zhy on 15/12/5. */ public class PaddingRightAttr extends AutoAttr { public PaddingRightAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.PADDING_RIGHT; } @Override protected boolean defaultBaseWidth() { return true; } @Override protected void execute(View view, int val) { int l = view.getPaddingLeft(); int t = view.getPaddingTop(); int r = val; int b = view.getPaddingBottom(); view.setPadding(l, t, r, b); } public static PaddingRightAttr generate(int val, int baseFlag) { PaddingRightAttr attr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: attr = new PaddingRightAttr(val, Attrs.PADDING_RIGHT, 0); break; case AutoAttr.BASE_HEIGHT: attr = new PaddingRightAttr(val, 0, Attrs.PADDING_RIGHT); break; case AutoAttr.BASE_DEFAULT: attr = new PaddingRightAttr(val, 0, 0); break; } return attr; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/PaddingTopAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; /** * Created by zhy on 15/12/5. */ public class PaddingTopAttr extends AutoAttr { public PaddingTopAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.PADDING_TOP; } @Override protected boolean defaultBaseWidth() { return false; } @Override protected void execute(View view, int val) { int l = view.getPaddingLeft(); int t = val; int r = view.getPaddingRight(); int b = view.getPaddingBottom(); view.setPadding(l, t, r, b); } public static PaddingTopAttr generate(int val, int baseFlag) { PaddingTopAttr attr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: attr = new PaddingTopAttr(val, Attrs.PADDING_TOP, 0); break; case AutoAttr.BASE_HEIGHT: attr = new PaddingTopAttr(val, 0, Attrs.PADDING_TOP); break; case AutoAttr.BASE_DEFAULT: attr = new PaddingTopAttr(val, 0, 0); break; } return attr; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/TextSizeAttr.java ================================================ package com.zhy.autolayout.attr; import android.util.TypedValue; import android.view.View; import android.widget.TextView; /** * Created by zhy on 15/12/4. */ public class TextSizeAttr extends AutoAttr { public TextSizeAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.TEXTSIZE; } @Override protected boolean defaultBaseWidth() { return false; } @Override protected void execute(View view, int val) { if (!(view instanceof TextView)) return; ((TextView) view).setIncludeFontPadding(false); ((TextView) view).setTextSize(TypedValue.COMPLEX_UNIT_PX, val); } public static TextSizeAttr generate(int val, int baseFlag) { TextSizeAttr attr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: attr = new TextSizeAttr(val, Attrs.TEXTSIZE, 0); break; case AutoAttr.BASE_HEIGHT: attr = new TextSizeAttr(val, 0, Attrs.TEXTSIZE); break; case AutoAttr.BASE_DEFAULT: attr = new TextSizeAttr(val, 0, 0); break; } return attr; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/attr/WidthAttr.java ================================================ package com.zhy.autolayout.attr; import android.view.View; import android.view.ViewGroup; /** * Created by zhy on 15/12/5. */ public class WidthAttr extends AutoAttr { public WidthAttr(int pxVal, int baseWidth, int baseHeight) { super(pxVal, baseWidth, baseHeight); } @Override protected int attrVal() { return Attrs.WIDTH; } @Override protected boolean defaultBaseWidth() { return true; } @Override protected void execute(View view, int val) { ViewGroup.LayoutParams lp = view.getLayoutParams(); lp.width = val; } public static WidthAttr generate(int val, int baseFlag) { WidthAttr widthAttr = null; switch (baseFlag) { case AutoAttr.BASE_WIDTH: widthAttr = new WidthAttr(val, Attrs.WIDTH, 0); break; case AutoAttr.BASE_HEIGHT: widthAttr = new WidthAttr(val, 0, Attrs.WIDTH); break; case AutoAttr.BASE_DEFAULT: widthAttr = new WidthAttr(val, 0, 0); break; } return widthAttr; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/config/AutoLayoutConifg.java ================================================ package com.zhy.autolayout.config; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import com.zhy.autolayout.utils.L; import com.zhy.autolayout.utils.ScreenUtils; /** * Created by zhy on 15/11/18. */ public class AutoLayoutConifg { private static AutoLayoutConifg sIntance = new AutoLayoutConifg(); private static final String KEY_DESIGN_WIDTH = "design_width"; private static final String KEY_DESIGN_HEIGHT = "design_height"; private int mScreenWidth; private int mScreenHeight; private int mDesignWidth; private int mDesignHeight; private boolean useDeviceSize; private AutoLayoutConifg() { } public void checkParams() { if (mDesignHeight <= 0 || mDesignWidth <= 0) { throw new RuntimeException( "you must set " + KEY_DESIGN_WIDTH + " and " + KEY_DESIGN_HEIGHT + " in your manifest file."); } } public AutoLayoutConifg useDeviceSize() { useDeviceSize = true; return this; } public static AutoLayoutConifg getInstance() { return sIntance; } public int getScreenWidth() { return mScreenWidth; } public int getScreenHeight() { return mScreenHeight; } public int getDesignWidth() { return mDesignWidth; } public int getDesignHeight() { return mDesignHeight; } public void init(Context context) { getMetaData(context); int[] screenSize = ScreenUtils.getScreenSize(context, useDeviceSize); mScreenWidth = screenSize[0]; mScreenHeight = screenSize[1]; L.e(" screenWidth =" + mScreenWidth + " ,screenHeight = " + mScreenHeight); } private void getMetaData(Context context) { PackageManager packageManager = context.getPackageManager(); ApplicationInfo applicationInfo; try { applicationInfo = packageManager.getApplicationInfo(context .getPackageName(), PackageManager.GET_META_DATA); if (applicationInfo != null && applicationInfo.metaData != null) { mDesignWidth = (int) applicationInfo.metaData.get(KEY_DESIGN_WIDTH); mDesignHeight = (int) applicationInfo.metaData.get(KEY_DESIGN_HEIGHT); } } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException( "you must set " + KEY_DESIGN_WIDTH + " and " + KEY_DESIGN_HEIGHT + " in your manifest file.", e); } L.e(" designWidth =" + mDesignWidth + " , designHeight = " + mDesignHeight); } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/config/UseLandscape.java ================================================ package com.zhy.autolayout.config; /** * Created by zhy on 15/12/5. * 如果Activity设计稿是横屏,继承该接口即可 */ public interface UseLandscape { } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/utils/AutoLayoutHelper.java ================================================ /* * Copyright (C) 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.zhy.autolayout.utils; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import com.zhy.autolayout.AutoLayoutInfo; import com.zhy.autolayout.R; import com.zhy.autolayout.attr.HeightAttr; import com.zhy.autolayout.attr.MarginAttr; import com.zhy.autolayout.attr.MarginBottomAttr; import com.zhy.autolayout.attr.MarginLeftAttr; import com.zhy.autolayout.attr.MarginRightAttr; import com.zhy.autolayout.attr.MarginTopAttr; import com.zhy.autolayout.attr.MaxHeightAttr; import com.zhy.autolayout.attr.MaxWidthAttr; import com.zhy.autolayout.attr.MinHeightAttr; import com.zhy.autolayout.attr.MinWidthAttr; import com.zhy.autolayout.attr.PaddingAttr; import com.zhy.autolayout.attr.PaddingBottomAttr; import com.zhy.autolayout.attr.PaddingLeftAttr; import com.zhy.autolayout.attr.PaddingRightAttr; import com.zhy.autolayout.attr.PaddingTopAttr; import com.zhy.autolayout.attr.TextSizeAttr; import com.zhy.autolayout.attr.WidthAttr; import com.zhy.autolayout.config.AutoLayoutConifg; public class AutoLayoutHelper { private final ViewGroup mHost; private static final int[] LL = new int[] { // android.R.attr.textSize, android.R.attr.padding,// android.R.attr.paddingLeft,// android.R.attr.paddingTop,// android.R.attr.paddingRight,// android.R.attr.paddingBottom,// android.R.attr.layout_width,// android.R.attr.layout_height,// android.R.attr.layout_margin,// android.R.attr.layout_marginLeft,// android.R.attr.layout_marginTop,// android.R.attr.layout_marginRight,// android.R.attr.layout_marginBottom,// android.R.attr.maxWidth,// android.R.attr.maxHeight,// android.R.attr.minWidth,// android.R.attr.minHeight,//16843072 }; private static final int INDEX_TEXT_SIZE = 0; private static final int INDEX_PADDING = 1; private static final int INDEX_PADDING_LEFT = 2; private static final int INDEX_PADDING_TOP = 3; private static final int INDEX_PADDING_RIGHT = 4; private static final int INDEX_PADDING_BOTTOM = 5; private static final int INDEX_WIDTH = 6; private static final int INDEX_HEIGHT = 7; private static final int INDEX_MARGIN = 8; private static final int INDEX_MARGIN_LEFT = 9; private static final int INDEX_MARGIN_TOP = 10; private static final int INDEX_MARGIN_RIGHT = 11; private static final int INDEX_MARGIN_BOTTOM = 12; private static final int INDEX_MAX_WIDTH = 13; private static final int INDEX_MAX_HEIGHT = 14; private static final int INDEX_MIN_WIDTH = 15; private static final int INDEX_MIN_HEIGHT = 16; /** * move to other place? */ private static AutoLayoutConifg mAutoLayoutConifg; public AutoLayoutHelper(ViewGroup host) { mHost = host; if (mAutoLayoutConifg == null) { initAutoLayoutConfig(host); } } private void initAutoLayoutConfig(ViewGroup host) { mAutoLayoutConifg = AutoLayoutConifg.getInstance(); mAutoLayoutConifg.init(host.getContext()); } public void adjustChildren() { AutoLayoutConifg.getInstance().checkParams(); for (int i = 0, n = mHost.getChildCount(); i < n; i++) { View view = mHost.getChildAt(i); ViewGroup.LayoutParams params = view.getLayoutParams(); if (params instanceof AutoLayoutParams) { AutoLayoutInfo info = ((AutoLayoutParams) params).getAutoLayoutInfo(); if (info != null) { info.fillAttrs(view); } } } } public static AutoLayoutInfo getAutoLayoutInfo(Context context, AttributeSet attrs) { AutoLayoutInfo info = new AutoLayoutInfo(); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoLayout_Layout); int baseWidth = a.getInt(R.styleable.AutoLayout_Layout_layout_auto_basewidth, 0); int baseHeight = a.getInt(R.styleable.AutoLayout_Layout_layout_auto_baseheight, 0); a.recycle(); TypedArray array = context.obtainStyledAttributes(attrs, LL); int n = array.getIndexCount(); for (int i = 0; i < n; i++) { int index = array.getIndex(i); // String val = array.getString(index); // if (!isPxVal(val)) continue; if (!DimenUtils.isPxVal(array.peekValue(index))) continue; int pxVal = 0; try { pxVal = array.getDimensionPixelOffset(index, 0); } catch (Exception ignore)//not dimension { continue; } switch (index) { case INDEX_TEXT_SIZE: info.addAttr(new TextSizeAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_PADDING: info.addAttr(new PaddingAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_PADDING_LEFT: info.addAttr(new PaddingLeftAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_PADDING_TOP: info.addAttr(new PaddingTopAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_PADDING_RIGHT: info.addAttr(new PaddingRightAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_PADDING_BOTTOM: info.addAttr(new PaddingBottomAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_WIDTH: info.addAttr(new WidthAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_HEIGHT: info.addAttr(new HeightAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_MARGIN: info.addAttr(new MarginAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_MARGIN_LEFT: info.addAttr(new MarginLeftAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_MARGIN_TOP: info.addAttr(new MarginTopAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_MARGIN_RIGHT: info.addAttr(new MarginRightAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_MARGIN_BOTTOM: info.addAttr(new MarginBottomAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_MAX_WIDTH: info.addAttr(new MaxWidthAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_MAX_HEIGHT: info.addAttr(new MaxHeightAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_MIN_WIDTH: info.addAttr(new MinWidthAttr(pxVal, baseWidth, baseHeight)); break; case INDEX_MIN_HEIGHT: info.addAttr(new MinHeightAttr(pxVal, baseWidth, baseHeight)); break; } } array.recycle(); L.e(" getAutoLayoutInfo " + info.toString()); return info; } public interface AutoLayoutParams { AutoLayoutInfo getAutoLayoutInfo(); } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/utils/AutoUtils.java ================================================ package com.zhy.autolayout.utils; import android.view.View; import com.zhy.autolayout.AutoLayoutInfo; import com.zhy.autolayout.R; import com.zhy.autolayout.attr.Attrs; import com.zhy.autolayout.attr.AutoAttr; import com.zhy.autolayout.config.AutoLayoutConifg; /** * Created by zhy on 15/12/4. */ public class AutoUtils { /** * 会直接将view的LayoutParams上设置的width,height直接进行百分比处理 * * @param view */ public static void auto(View view) { autoSize(view); autoPadding(view); autoMargin(view); autoTextSize(view, AutoAttr.BASE_DEFAULT); } /** * @param view * @param attrs #Attrs.WIDTH|Attrs.HEIGHT * @param base AutoAttr.BASE_WIDTH|AutoAttr.BASE_HEIGHT|AutoAttr.BASE_DEFAULT */ public static void auto(View view, int attrs, int base) { AutoLayoutInfo autoLayoutInfo = AutoLayoutInfo.getAttrFromView(view, attrs, base); if (autoLayoutInfo != null) autoLayoutInfo.fillAttrs(view); } public static void autoTextSize(View view) { auto(view, Attrs.TEXTSIZE, AutoAttr.BASE_DEFAULT); } public static void autoTextSize(View view, int base) { auto(view, Attrs.TEXTSIZE, base); } public static void autoMargin(View view) { auto(view, Attrs.MARGIN, AutoAttr.BASE_DEFAULT); } public static void autoMargin(View view, int base) { auto(view, Attrs.MARGIN, base); } public static void autoPadding(View view) { auto(view, Attrs.PADDING, AutoAttr.BASE_DEFAULT); } public static void autoPadding(View view, int base) { auto(view, Attrs.PADDING, base); } public static void autoSize(View view) { auto(view, Attrs.WIDTH | Attrs.HEIGHT, AutoAttr.BASE_DEFAULT); } public static void autoSize(View view, int base) { auto(view, Attrs.WIDTH | Attrs.HEIGHT, base); } public static boolean autoed(View view) { Object tag = view.getTag(R.id.id_tag_autolayout_size); if (tag != null) return true; view.setTag(R.id.id_tag_autolayout_size, "Just Identify"); return false; } public static float getPercentWidth1px() { int screenWidth = AutoLayoutConifg.getInstance().getScreenWidth(); int designWidth = AutoLayoutConifg.getInstance().getDesignWidth(); return 1.0f * screenWidth / designWidth; } public static float getPercentHeight1px() { int screenHeight = AutoLayoutConifg.getInstance().getScreenHeight(); int designHeight = AutoLayoutConifg.getInstance().getDesignHeight(); return 1.0f * screenHeight / designHeight; } public static int getPercentWidthSize(int val) { int screenWidth = AutoLayoutConifg.getInstance().getScreenWidth(); int designWidth = AutoLayoutConifg.getInstance().getDesignWidth(); return (int) (val * 1.0f / designWidth * screenWidth); } public static int getPercentWidthSizeBigger(int val) { int screenWidth = AutoLayoutConifg.getInstance().getScreenWidth(); int designWidth = AutoLayoutConifg.getInstance().getDesignWidth(); int res = val * screenWidth; if (res % designWidth == 0) { return res / designWidth; } else { return res / designWidth + 1; } } public static int getPercentHeightSizeBigger(int val) { int screenHeight = AutoLayoutConifg.getInstance().getScreenHeight(); int designHeight = AutoLayoutConifg.getInstance().getDesignHeight(); int res = val * screenHeight; if (res % designHeight == 0) { return res / designHeight; } else { return res / designHeight + 1; } } public static int getPercentHeightSize(int val) { int screenHeight = AutoLayoutConifg.getInstance().getScreenHeight(); int designHeight = AutoLayoutConifg.getInstance().getDesignHeight(); return (int) (val * 1.0f / designHeight * screenHeight); } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/utils/DimenUtils.java ================================================ package com.zhy.autolayout.utils; import android.util.TypedValue; /** * Created by zhy on 16/3/3. */ public class DimenUtils { private static int getComplexUnit(int data) { return TypedValue.COMPLEX_UNIT_MASK & (data >> TypedValue.COMPLEX_UNIT_SHIFT); } public static boolean isPxVal(TypedValue val) { if (val != null && val.type == TypedValue.TYPE_DIMENSION && getComplexUnit(val.data) == TypedValue.COMPLEX_UNIT_PX) { return true; } return false; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/utils/L.java ================================================ package com.zhy.autolayout.utils; import android.util.Log; /** * Created by zhy on 15/11/18. */ public class L { public static boolean debug = false; private static final String TAG = "AUTO_LAYOUT"; public static void e(String msg) { if (debug) { Log.e(TAG, msg); } } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/utils/ScreenUtils.java ================================================ package com.zhy.autolayout.utils; import android.content.Context; import android.content.res.Resources; import android.graphics.Point; import android.os.Build; import android.util.DisplayMetrics; import android.view.Display; import android.view.WindowManager; /** * Created by zhy on 15/12/4.
* form http://stackoverflow.com/questions/1016896/get-screen-dimensions-in-pixels/15699681#15699681 */ public class ScreenUtils { public static int getStatusBarHeight(Context context) { int result = 0; try { int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resourceId > 0) { result = context.getResources().getDimensionPixelSize(resourceId); } } catch (Resources.NotFoundException e) { e.printStackTrace(); } return result; } public static int[] getScreenSize(Context context, boolean useDeviceSize) { int[] size = new int[2]; WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display d = w.getDefaultDisplay(); DisplayMetrics metrics = new DisplayMetrics(); d.getMetrics(metrics); // since SDK_INT = 1; int widthPixels = metrics.widthPixels; int heightPixels = metrics.heightPixels; if (!useDeviceSize) { size[0] = widthPixels; size[1] = heightPixels - getStatusBarHeight(context); return size; } // includes window decorations (statusbar bar/menu bar) if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17) try { widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d); heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d); } catch (Exception ignored) { } // includes window decorations (statusbar bar/menu bar) if (Build.VERSION.SDK_INT >= 17) try { Point realSize = new Point(); Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize); widthPixels = realSize.x; heightPixels = realSize.y; } catch (Exception ignored) { } size[0] = widthPixels; size[1] = heightPixels; return size; } } ================================================ FILE: autolayout/src/main/java/com/zhy/autolayout/widget/MetroLayout.java ================================================ package com.zhy.autolayout.widget; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import com.zhy.autolayout.AutoLayoutInfo; import com.zhy.autolayout.R; import com.zhy.autolayout.utils.AutoLayoutHelper; import com.zhy.autolayout.utils.AutoUtils; import java.util.ArrayList; import java.util.List; import java.util.Random; /** * Created by zhy on 15/12/10. * * //do not use */ public class MetroLayout extends ViewGroup { private final AutoLayoutHelper mHelper = new AutoLayoutHelper(this); private static class MetroBlock { int left; int top; int width; } private List mAvailablePos = new ArrayList<>(); private int mDivider; public MetroLayout(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MetroLayout); mDivider = a.getDimensionPixelOffset(R.styleable.MetroLayout_metro_divider, 0); mDivider = AutoUtils.getPercentWidthSizeBigger(mDivider); a.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (true) randomColor(); if (!isInEditMode()) mHelper.adjustChildren(); measureChildren(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } private void randomColor() { Random r = new Random(255); for (int i = 0, n = getChildCount(); i < n; i++) { View v = getChildAt(i); v.setBackgroundColor(Color.argb(100, r.nextInt(), r.nextInt(), r.nextInt())); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { initAvailablePosition(); int left = 0; int top = 0; int divider = mDivider; for (int i = 0, n = getChildCount(); i < n; i++) { View v = getChildAt(i); if (v.getVisibility() == View.GONE) continue; MetroBlock newPos = findAvailablePos(v); left = newPos.left; top = newPos.top; int childWidth = v.getMeasuredWidth(); int childHeight = v.getMeasuredHeight(); int right = left + childWidth; int bottom = top + childHeight; v.layout(left, top, right, bottom); if (childWidth + divider < newPos.width) { newPos.left += childWidth + divider; newPos.width -= childWidth + divider; } else { mAvailablePos.remove(newPos); } MetroBlock p = new MetroBlock(); p.left = left; p.top = bottom + divider; p.width = childWidth; mAvailablePos.add(p); mergeAvailablePosition(); } } private void mergeAvailablePosition() { if (mAvailablePos.size() <= 1) return; List needRemoveBlocks = new ArrayList<>(); MetroBlock one = mAvailablePos.get(0); MetroBlock two = mAvailablePos.get(1); for (int i = 1, n = mAvailablePos.size(); i < n - 1; i++) { if (one.top == two.top) { one.width = one.width + two.width; needRemoveBlocks.add(one); two.left = one.left; two = mAvailablePos.get(i + 1); } else { one = mAvailablePos.get(i); two = mAvailablePos.get(i + 1); } } mAvailablePos.removeAll(needRemoveBlocks); } private void initAvailablePosition() { mAvailablePos.clear(); MetroBlock first = new MetroBlock(); first.left = getPaddingLeft(); first.top = getPaddingTop(); first.width = getMeasuredWidth(); mAvailablePos.add(first); } private MetroBlock findAvailablePos(View view) { MetroBlock p = new MetroBlock(); if (mAvailablePos.size() == 0) { p.left = getPaddingLeft(); p.top = getPaddingTop(); p.width = getMeasuredWidth(); return p; } int min = mAvailablePos.get(0).top; MetroBlock minHeightPos = mAvailablePos.get(0); for (MetroBlock _p : mAvailablePos) { if (_p.top < min) { min = _p.top; minHeightPos = _p; } } return minHeightPos; } @Override public MetroLayout.LayoutParams generateLayoutParams(AttributeSet attrs) { return new LayoutParams(getContext(), attrs); } public static class LayoutParams extends ViewGroup.MarginLayoutParams implements AutoLayoutHelper.AutoLayoutParams { private AutoLayoutInfo mAutoLayoutInfo; public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs); } public LayoutParams(int width, int height) { super(width, height); } public LayoutParams(ViewGroup.LayoutParams source) { super(source); } public LayoutParams(MarginLayoutParams source) { super(source); } public LayoutParams(LayoutParams source) { this((ViewGroup.LayoutParams) source); mAutoLayoutInfo = source.mAutoLayoutInfo; } @Override public AutoLayoutInfo getAutoLayoutInfo() { return mAutoLayoutInfo; } } } ================================================ FILE: autolayout/src/main/res/values/attrs.xml ================================================ ================================================ FILE: autolayout/src/main/res/values/ids.xml ================================================ ================================================ FILE: autolayout/src/main/res/values/strings.xml ================================================ autolayout ================================================ FILE: autolayout-widget/.gitignore ================================================ /build ================================================ FILE: autolayout-widget/build.gradle ================================================ apply plugin: 'com.android.library' android { compileSdkVersion 23 buildToolsVersion "23.0.1" defaultConfig { minSdkVersion 10 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.1.0' compile project(':autolayout') compile 'com.android.support:support-v4:23.1.0' compile 'com.android.support:design:23.1.1' compile 'com.android.support:gridlayout-v7:23.1.0' compile 'com.android.support:cardview-v7:23.1.0' } ================================================ FILE: autolayout-widget/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in /Users/zhy/android/sdk/android-sdk-macosx/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} ================================================ FILE: autolayout-widget/src/androidTest/java/com/zhy/autolayout/widget/ApplicationTest.java ================================================ package com.zhy.autolayout.widget; import android.app.Application; import android.test.ApplicationTestCase; /** * Testing Fundamentals */ public class ApplicationTest extends ApplicationTestCase { public ApplicationTest() { super(Application.class); } } ================================================ FILE: autolayout-widget/src/main/AndroidManifest.xml ================================================ ================================================ FILE: autolayout-widget/src/main/java/com/zhy/autolayout/widget/AutoActionMenuItemView.java ================================================ package com.zhy.autolayout.widget; import android.content.Context; import android.content.res.TypedArray; import android.support.v7.view.menu.ActionMenuItemView; import android.util.AttributeSet; import android.util.TypedValue; import com.zhy.autolayout.utils.AutoUtils; import com.zhy.autolayout.utils.DimenUtils; /** * Created by hupei on 2016/3/7 14:44. */ public class AutoActionMenuItemView extends ActionMenuItemView { private static final int NO_VALID = -1; private int mMenuTextSize; public AutoActionMenuItemView(Context context) { this(context, null); } public AutoActionMenuItemView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public AutoActionMenuItemView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.Theme, defStyle, R.style.ThemeOverlay_AppCompat); int menuTextAppearance = a.getResourceId(R.styleable.Theme_actionBarTheme, R.style.ThemeOverlay_AppCompat_ActionBar); mMenuTextSize = loadTextSizeFromTextAppearance(menuTextAppearance); a.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!this.isInEditMode()) { setUpTitleTextSize(); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } private int loadTextSizeFromTextAppearance(int textAppearanceResId) { TypedArray a = getContext().obtainStyledAttributes(textAppearanceResId, R.styleable.TextAppearance); try { if (!DimenUtils.isPxVal(a.peekValue(R.styleable.TextAppearance_android_textSize))) return NO_VALID; return a.getDimensionPixelSize(R.styleable.TextAppearance_android_textSize, NO_VALID); } finally { a.recycle(); } } private void setUpTitleTextSize() { if (mMenuTextSize == -1) return; int autoTextSize = AutoUtils.getPercentHeightSize(mMenuTextSize); setTextSize(TypedValue.COMPLEX_UNIT_PX, autoTextSize); } } ================================================ FILE: autolayout-widget/src/main/java/com/zhy/autolayout/widget/AutoCardView.java ================================================ package com.zhy.autolayout.widget; import android.content.Context; import android.support.v7.widget.CardView; import android.util.AttributeSet; import com.zhy.autolayout.AutoFrameLayout; import com.zhy.autolayout.utils.AutoLayoutHelper; /** * Created by zhy on 15/12/8. */ public class AutoCardView extends CardView { private final AutoLayoutHelper mHelper = new AutoLayoutHelper(this); public AutoCardView(Context context) { super(context); } public AutoCardView(Context context, AttributeSet attrs) { super(context, attrs); } public AutoCardView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public AutoFrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) { return new AutoFrameLayout.LayoutParams(getContext(), attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!isInEditMode()) { mHelper.adjustChildren(); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } ================================================ FILE: autolayout-widget/src/main/java/com/zhy/autolayout/widget/AutoLayoutWidgetActivity.java ================================================ package com.zhy.autolayout.widget; import android.content.Context; import android.util.AttributeSet; import android.view.View; import com.zhy.autolayout.AutoLayoutActivity; /** * Created by hupei on 2016/3/7 16:44. */ public class AutoLayoutWidgetActivity extends AutoLayoutActivity { private static final String ACTION_MENU_ITEM_VIEW = "android.support.v7.view.menu.ActionMenuItemView"; private static final String TAB_LAYOUT = "android.support.design.widget.TabLayout"; @Override public View onCreateView(String name, Context context, AttributeSet attrs) { View view = null; if (name.equals(ACTION_MENU_ITEM_VIEW)) { view = new AutoActionMenuItemView(context, attrs); } if (name.equals(TAB_LAYOUT)) { view = new AutoTabLayout(context, attrs); } if (view != null) return view; return super.onCreateView(name, context, attrs); } } ================================================ FILE: autolayout-widget/src/main/java/com/zhy/autolayout/widget/AutoRadioGroup.java ================================================ package com.zhy.autolayout.widget; import android.content.Context; import android.util.AttributeSet; import android.view.ViewGroup; import android.widget.RadioGroup; import com.zhy.autolayout.AutoLayoutInfo; import com.zhy.autolayout.utils.AutoLayoutHelper; /** * Created by hupei on 2016/2/29 9:59. */ public class AutoRadioGroup extends RadioGroup { private AutoLayoutHelper mHelper = new AutoLayoutHelper(this); public AutoRadioGroup(Context context) { super(context); } public AutoRadioGroup(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!isInEditMode()) mHelper.adjustChildren(); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new LayoutParams(getContext(), attrs); } public static class LayoutParams extends RadioGroup.LayoutParams implements AutoLayoutHelper.AutoLayoutParams { private AutoLayoutInfo mAutoLayoutInfo; public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs); } @Override public AutoLayoutInfo getAutoLayoutInfo() { return mAutoLayoutInfo; } public LayoutParams(int width, int height) { super(width, height); } public LayoutParams(ViewGroup.LayoutParams source) { super(source); } public LayoutParams(MarginLayoutParams source) { super(source); } } } ================================================ FILE: autolayout-widget/src/main/java/com/zhy/autolayout/widget/AutoTabLayout.java ================================================ package com.zhy.autolayout.widget; import android.content.Context; import android.content.res.TypedArray; import android.support.design.widget.TabLayout; import android.util.AttributeSet; import android.util.TypedValue; import android.view.ViewGroup; import android.widget.TextView; import com.zhy.autolayout.utils.AutoUtils; import com.zhy.autolayout.utils.DimenUtils; /** * Created by zhy on 16/3/3. */ public class AutoTabLayout extends TabLayout { private static final int NO_VALID = -1; private int mTextSize; private boolean mTextSizeBaseWidth = false; public AutoTabLayout(Context context) { this(context, null); } public AutoTabLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public AutoTabLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initTextSizeBaseWidth(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TabLayout, defStyleAttr, R.style.Widget_Design_TabLayout); int tabTextAppearance = a.getResourceId(R.styleable.TabLayout_tabTextAppearance, R.style.TextAppearance_Design_Tab); mTextSize = loadTextSizeFromTextAppearance(tabTextAppearance); a.recycle(); } private void initTextSizeBaseWidth(Context context, AttributeSet attrs) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoTabLayout); mTextSizeBaseWidth = a.getBoolean(R.styleable.AutoTabLayout_auto_textSize_base_width, false); a.recycle(); } private int loadTextSizeFromTextAppearance(int textAppearanceResId) { TypedArray a = getContext().obtainStyledAttributes(textAppearanceResId, R.styleable.TextAppearance); try { if (!DimenUtils.isPxVal(a.peekValue(R.styleable.TextAppearance_android_textSize))) return NO_VALID; return a.getDimensionPixelSize(R.styleable.TextAppearance_android_textSize, NO_VALID); } finally { a.recycle(); } } @Override public void addTab(Tab tab, int position, boolean setSelected) { super.addTab(tab, position, setSelected); setUpTabTextSize(tab); } @Override public void addTab(Tab tab, boolean setSelected) { super.addTab(tab, setSelected); setUpTabTextSize(tab); } private void setUpTabTextSize(Tab tab) { if (mTextSize == NO_VALID || tab.getCustomView() != null) return; ViewGroup tabGroup = (ViewGroup) getChildAt(0); ViewGroup tabContainer = (ViewGroup) tabGroup.getChildAt(tab.getPosition()); TextView textView = (TextView) tabContainer.getChildAt(1); if (AutoUtils.autoed(textView)) { return; } int autoTextSize = 0 ; if (mTextSizeBaseWidth) { autoTextSize = AutoUtils.getPercentWidthSize(mTextSize); } else { autoTextSize = AutoUtils.getPercentHeightSize(mTextSize); } textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, autoTextSize); } } ================================================ FILE: autolayout-widget/src/main/java/com/zhy/autolayout/widget/AutoTableLayout.java ================================================ package com.zhy.autolayout.widget; import android.content.Context; import android.util.AttributeSet; import android.view.ViewGroup; import android.widget.TableLayout; import com.zhy.autolayout.AutoLayoutInfo; import com.zhy.autolayout.utils.AutoLayoutHelper; /** * Created by hupei on 2016/2/29 9:59. */ public class AutoTableLayout extends TableLayout { private AutoLayoutHelper mHelper = new AutoLayoutHelper(this); public AutoTableLayout(Context context) { super(context); } public AutoTableLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!isInEditMode()) mHelper.adjustChildren(); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new LayoutParams(getContext(), attrs); } public static class LayoutParams extends TableLayout.LayoutParams implements AutoLayoutHelper.AutoLayoutParams { private AutoLayoutInfo mAutoLayoutInfo; public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs); } @Override public AutoLayoutInfo getAutoLayoutInfo() { return mAutoLayoutInfo; } public LayoutParams(int width, int height) { super(width, height); } public LayoutParams(ViewGroup.LayoutParams source) { super(source); } public LayoutParams(MarginLayoutParams source) { super(source); } } } ================================================ FILE: autolayout-widget/src/main/java/com/zhy/autolayout/widget/AutoTableRow.java ================================================ package com.zhy.autolayout.widget; import android.content.Context; import android.util.AttributeSet; import android.view.ViewGroup; import android.widget.TableRow; import com.zhy.autolayout.AutoLayoutInfo; import com.zhy.autolayout.utils.AutoLayoutHelper; /** * Created by hupei on 2016/2/29 9:59. */ public class AutoTableRow extends TableRow { private AutoLayoutHelper mHelper = new AutoLayoutHelper(this); public AutoTableRow(Context context) { super(context); } public AutoTableRow(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!isInEditMode()) mHelper.adjustChildren(); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new LayoutParams(getContext(), attrs); } public static class LayoutParams extends TableRow.LayoutParams implements AutoLayoutHelper.AutoLayoutParams { private AutoLayoutInfo mAutoLayoutInfo; public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs); } @Override public AutoLayoutInfo getAutoLayoutInfo() { return mAutoLayoutInfo; } public LayoutParams(int width, int height) { super(width, height); } public LayoutParams(ViewGroup.LayoutParams source) { super(source); } public LayoutParams(MarginLayoutParams source) { super(source); } } } ================================================ FILE: autolayout-widget/src/main/java/com/zhy/autolayout/widget/AutoToolbar.java ================================================ package com.zhy.autolayout.widget; import android.content.Context; import android.content.res.TypedArray; import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.util.AttributeSet; import android.util.TypedValue; import android.widget.TextView; import com.zhy.autolayout.AutoLayoutInfo; import com.zhy.autolayout.utils.AutoLayoutHelper; import com.zhy.autolayout.utils.AutoUtils; import com.zhy.autolayout.utils.DimenUtils; import java.lang.reflect.Field; /** * Created by hupei on 2015/12/28 20:33. */ public class AutoToolbar extends Toolbar { private static final int NO_VALID = -1; private int mTextSize; private int mSubTextSize; private final AutoLayoutHelper mHelper = new AutoLayoutHelper(this); public AutoToolbar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Toolbar, defStyleAttr, R.style.Widget_AppCompat_Toolbar); int titleTextAppearance = a.getResourceId(R.styleable.Toolbar_titleTextAppearance, R.style.TextAppearance_Widget_AppCompat_Toolbar_Title); int subtitleTextAppearance = a.getResourceId(R.styleable.Toolbar_subtitleTextAppearance, R.style.TextAppearance_Widget_AppCompat_Toolbar_Subtitle); mTextSize = loadTextSizeFromTextAppearance(titleTextAppearance); mSubTextSize = loadTextSizeFromTextAppearance(subtitleTextAppearance); TypedArray menuA = context.getTheme().obtainStyledAttributes(attrs, R.styleable.Theme, defStyleAttr, R.style.ThemeOverlay_AppCompat); int menuTextAppearance = menuA.getResourceId(R.styleable.Theme_actionBarTheme, R.style.ThemeOverlay_AppCompat_ActionBar); int menuTextSize = loadTextSizeFromTextAppearance(menuTextAppearance); //防止 menu 定义 textSize,而 Toolbar 无定义 textSize 时,title 的 textSize 随 menu 变化 if (mTextSize == NO_VALID) mTextSize = menuTextSize; if (mSubTextSize == NO_VALID) mSubTextSize = menuTextSize; a.recycle(); menuA.recycle(); } public AutoToolbar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public AutoToolbar(Context context) { this(context, null); } private int loadTextSizeFromTextAppearance(int textAppearanceResId) { TypedArray a = getContext().obtainStyledAttributes(textAppearanceResId, R.styleable.TextAppearance); try { if (!DimenUtils.isPxVal(a.peekValue(R.styleable.TextAppearance_android_textSize))) return NO_VALID; return a.getDimensionPixelSize(R.styleable.TextAppearance_android_textSize, NO_VALID); } finally { a.recycle(); } } private void setUpTitleTextSize() { CharSequence title = getTitle(); if (!TextUtils.isEmpty(title) && mTextSize != NO_VALID) setUpTitleTextSize("mTitleTextView", mTextSize); CharSequence subtitle = getSubtitle(); if (!TextUtils.isEmpty(subtitle) && mSubTextSize != NO_VALID) setUpTitleTextSize("mSubtitleTextView", mSubTextSize); } private void setUpTitleTextSize(String name, int val) { try { //反射 Toolbar 的 TextView Field f = getClass().getSuperclass().getDeclaredField(name); f.setAccessible(true); TextView textView = (TextView) f.get(this); if (textView != null) { int autoTextSize = AutoUtils.getPercentHeightSize(val); textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, autoTextSize); } } catch (Exception e) { e.printStackTrace(); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!this.isInEditMode()) { setUpTitleTextSize(); this.mHelper.adjustChildren(); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new LayoutParams(this.getContext(), attrs); } public static class LayoutParams extends Toolbar.LayoutParams implements AutoLayoutHelper.AutoLayoutParams { private AutoLayoutInfo mDimenLayoutInfo; public LayoutParams(Context c, AttributeSet attrs) { super(c, attrs); this.mDimenLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs); } @Override public AutoLayoutInfo getAutoLayoutInfo() { return this.mDimenLayoutInfo; } public LayoutParams(int width, int height) { super(width, height); } public LayoutParams(android.view.ViewGroup.LayoutParams source) { super(source); } public LayoutParams(MarginLayoutParams source) { super(source); } } } ================================================ FILE: autolayout-widget/src/main/res/values/attrs.xml ================================================ ================================================ FILE: autolayout-widget/src/main/res/values/strings.xml ================================================ autolayout-widget ================================================ FILE: build.gradle ================================================ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.2.3' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0' classpath 'com.github.dcendents:android-maven-plugin:1.2' } } allprojects { repositories { jcenter() } } ================================================ FILE: gradle/wrapper/gradle-wrapper.properties ================================================ #Thu Nov 19 16:52:41 GMT+08:00 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip ================================================ FILE: gradle.properties ================================================ # Project-wide Gradle settings. # IDE (e.g. Android Studio) users: # Gradle settings configured through the IDE *will override* # any settings specified in this file. # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. # Default value: -Xmx10248m -XX:MaxPermSize=256m # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true ================================================ FILE: gradlew ================================================ #!/usr/bin/env bash ############################################################################## ## ## Gradle start up script for UN*X ## ############################################################################## # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS="" APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" warn ( ) { echo "$*" } die ( ) { echo echo "$*" echo exit 1 } # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false case "`uname`" in CYGWIN* ) cygwin=true ;; Darwin* ) darwin=true ;; MINGW* ) msys=true ;; esac # For Cygwin, ensure paths are in UNIX format before anything is touched. if $cygwin ; then [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` fi # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG=`dirname "$PRG"`"/$link" fi done SAVED="`pwd`" cd "`dirname \"$PRG\"`/" >&- APP_HOME="`pwd -P`" cd "$SAVED" >&- CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD="java" which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi # Increase the maximum file descriptors if we can. if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi ulimit -n $MAX_FD if [ $? -ne 0 ] ; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" fi fi # For Darwin, add options to specify how the application appears in the dock if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin, switch paths to Windows format before running java if $cygwin ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` # We build the pattern for arguments to be converted via cygpath ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" SEP="|" done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments if [ "$GRADLE_CYGPATTERN" != "" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` else eval `echo args$i`="\"$arg\"" fi i=$((i+1)) done case $i in (0) set -- ;; (1) set -- "$args0" ;; (2) set -- "$args0" "$args1" ;; (3) set -- "$args0" "$args1" "$args2" ;; (4) set -- "$args0" "$args1" "$args2" "$args3" ;; (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules function splitJvmOpts() { JVM_OPTS=("$@") } eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" ================================================ FILE: gradlew.bat ================================================ @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS= set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if "%ERRORLEVEL%" == "0" goto init echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto init echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :init @rem Get command-line arguments, handling Windowz variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. set CMD_LINE_ARGS= set _SKIP=2 :win9xME_args_slurp if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* goto execute :4NT_args @rem Get arguments from the 4NT Shell from JP Software set CMD_LINE_ARGS=%$ :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% :end @rem End local scope for the variables with windows NT shell if "%ERRORLEVEL%"=="0" goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 exit /b 1 :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: sample/.gitignore ================================================ /build ================================================ FILE: sample/build.gradle ================================================ apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.1" defaultConfig { applicationId "com.zhy.sample" minSdkVersion 10 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:23.1.0' compile project(':autolayout') compile 'com.zhy:base-adapter:2.0.2' compile 'com.android.support:design:23.1.0' compile 'com.android.support:cardview-v7:23.1.0' compile 'com.android.support:recyclerview-v7:23.2.0' } ================================================ FILE: sample/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in /Users/zhy/android/sdk/android-sdk-macosx/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} ================================================ FILE: sample/src/androidTest/java/com/zhy/sample/ApplicationTest.java ================================================ package com.zhy.sample; import android.app.Application; import android.test.ApplicationTestCase; /** * Testing Fundamentals */ public class ApplicationTest extends ApplicationTestCase { public ApplicationTest() { super(Application.class); } } ================================================ FILE: sample/src/main/AndroidManifest.xml ================================================ ================================================ FILE: sample/src/main/java/com/zhy/sample/CategoryActivity.java ================================================ package com.zhy.sample; import android.content.Context; import android.os.Bundle; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import com.zhy.autolayout.AutoLayoutActivity; import com.zhy.sample.fragment.SimpleFragment; public class CategoryActivity extends AutoLayoutActivity { private TabLayout mTabLayout; private ViewPager mViewPager; private String[] mTabTitles = new String[] {"单个UI", "正方形"}; @Override public Context getBaseContext() { return super.getBaseContext(); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_category); mTabLayout = (TabLayout) findViewById(R.id.id_tablayout); mViewPager = (ViewPager) findViewById(R.id.id_viewpager); mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int i) { return new SimpleFragment(); } @Override public CharSequence getPageTitle(int position) { return mTabTitles[position]; } @Override public int getCount() { return mTabTitles.length; } }); mTabLayout.setupWithViewPager(mViewPager); } } ================================================ FILE: sample/src/main/java/com/zhy/sample/MainActivity.java ================================================ package com.zhy.sample; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.view.Menu; import android.view.WindowManager; import com.zhy.autolayout.AutoLayoutActivity; import com.zhy.sample.fragment.ListFragment; import com.zhy.sample.fragment.PayFragment; import com.zhy.sample.fragment.RecyclerViewFragment; import com.zhy.sample.fragment.RecyclerViewGridFragment; import com.zhy.sample.fragment.RegisterFragment; import com.zhy.sample.fragment.TestFragment; import java.util.ArrayList; public class MainActivity extends AutoLayoutActivity { private ViewPager mViewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //requestWindowFeature(Window.FEATURE_NO_TITLE); setImmersionStatus(); setContentView(R.layout.activity_main); initView(); initDatas(); } private void setImmersionStatus() { if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { // 透明状态栏 getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); // 透明导航栏 // getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); } } private void initDatas() { ArrayList mList = new ArrayList(); mList.add(new ListFragment()); mList.add(new RegisterFragment()); mList.add(new PayFragment()); mList.add(new RecyclerViewFragment()); mList.add(new RecyclerViewGridFragment()); mList.add(new TestFragment()); mViewPager.setAdapter(new MyAdapter(getSupportFragmentManager(), mList)); } private void initView() { mViewPager = (ViewPager) findViewById(R.id.id_viewpager); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } public class MyAdapter extends FragmentPagerAdapter { ArrayList tabs = null; public MyAdapter(FragmentManager fm, ArrayList tabs) { super(fm); this.tabs = tabs; } @Override public Fragment getItem(int pos) { return tabs.get(pos); } @Override public int getCount() { return tabs.size(); } } } ================================================ FILE: sample/src/main/java/com/zhy/sample/UseDeviceSizeApplication.java ================================================ package com.zhy.sample; import android.app.Application; import com.zhy.autolayout.config.AutoLayoutConifg; /** * Created by zhy on 15/12/23. */ public class UseDeviceSizeApplication extends Application { @Override public void onCreate() { super.onCreate(); AutoLayoutConifg.getInstance().useDeviceSize().init(this); } } ================================================ FILE: sample/src/main/java/com/zhy/sample/fragment/ListFragment.java ================================================ package com.zhy.sample.fragment; import android.content.Context; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ListView; import com.zhy.autolayout.utils.AutoUtils; import com.zhy.sample.R; import java.util.ArrayList; import java.util.List; public class ListFragment extends Fragment { private View mView; private ListView mlistview; private List mList; private Context mContext; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { mView = inflater.inflate(R.layout.fragment_list, container, false); initView(); return mView; } private void initView() { mContext = getActivity(); mlistview = (ListView) mView.findViewById(R.id.id_listview); mList = new ArrayList(); for (int i = 0; i < 50; i++) { mList.add(i + ""); } mlistview.setAdapter(new MyAdapter()); // mlistview.setAdapter(new CommonAdapter(getActivity(),R.layout.list_item,mList) // { // @Override // protected void onConvertViewCreated(View convertView) // { // AutoUtils.autoSize(convertView); // } // // @Override // public void convert(com.zhy.base.adapter.ViewHolder viewHolder, String s) // { // // } // }); } class MyAdapter extends BaseAdapter { @Override public int getCount() { return mList.size(); } @Override public Object getItem(int arg0) { return mList.get(arg0); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false); convertView.setTag(holder); //对于listview,注意添加这一行,即可在item上使用高度 AutoUtils.autoSize(convertView); } else { holder = (ViewHolder) convertView.getTag(); } return convertView; } } class ViewHolder { } } ================================================ FILE: sample/src/main/java/com/zhy/sample/fragment/PayFragment.java ================================================ package com.zhy.sample.fragment; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.zhy.sample.R; public class PayFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_pay, container, false); } } ================================================ FILE: sample/src/main/java/com/zhy/sample/fragment/RecyclerViewFragment.java ================================================ package com.zhy.sample.fragment; import android.content.Context; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.zhy.autolayout.utils.AutoUtils; import com.zhy.base.adapter.recyclerview.CommonAdapter; import com.zhy.sample.R; import com.zhy.sample.view.DividerItemDecoration; import java.util.ArrayList; import java.util.List; public class RecyclerViewFragment extends Fragment { private View mView; private RecyclerView mRecyclerView; private List mList; private Context mContext; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { mView = inflater.inflate(R.layout.fragment_recyclerview, container, false); initView(); return mView; } private void initView() { mContext = getActivity(); mRecyclerView = (RecyclerView) mView.findViewById(R.id.id_recyclerview); mList = new ArrayList(); for (int i = 0; i < 50; i++) { mList.add(i + ""); } mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); mRecyclerView.setAdapter(new MyAdapter(getActivity(),mList)); mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST)); } class MyAdapter extends CommonAdapter { public MyAdapter(Context context, List datas) { super(context, R.layout.recyclerview_item, datas); } @Override public com.zhy.base.adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { com.zhy.base.adapter.ViewHolder viewHolder = super.onCreateViewHolder(parent, viewType); AutoUtils.autoSize(viewHolder.getConvertView()); return viewHolder; } @Override public void convert(com.zhy.base.adapter.ViewHolder viewHolder, String s) { } } } ================================================ FILE: sample/src/main/java/com/zhy/sample/fragment/RecyclerViewGridFragment.java ================================================ package com.zhy.sample.fragment; import android.content.Context; import android.graphics.Color; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.zhy.autolayout.attr.AutoAttr; import com.zhy.autolayout.utils.AutoUtils; import com.zhy.sample.R; import java.util.ArrayList; import java.util.List; import java.util.Random; public class RecyclerViewGridFragment extends Fragment { private View mView; private RecyclerView mRecyclerView; private List mList; private Context mContext; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { mView = inflater.inflate(R.layout.fragment_recyclerview_grid, container, false); initView(); return mView; } private void initView() { mContext = getActivity(); mRecyclerView = (RecyclerView) mView.findViewById(R.id.id_recyclerview); mList = new ArrayList(); for (int i = 0; i < 50; i++) { mList.add(i + ""); } mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2, GridLayoutManager.HORIZONTAL, false)); mRecyclerView.setAdapter(new MyAdapter()); } class MyAdapter extends RecyclerView.Adapter { @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View convertView = LayoutInflater.from(mContext).inflate(R.layout.recyclerview_item_grid, parent, false); return new ViewHolder(convertView); } @Override public void onBindViewHolder(ViewHolder holder, int position) { } @Override public long getItemId(int position) { return position; } @Override public int getItemCount() { return mList.size(); } } static class ViewHolder extends RecyclerView.ViewHolder { public ViewHolder(View itemView) { super(itemView); Random random = new Random(); itemView.setBackgroundColor(Color.argb(200, random.nextInt(255), random.nextInt(255), random.nextInt(255))); //recyclerview,注意添加这一行 AutoUtils.autoSize(itemView, AutoAttr.BASE_HEIGHT); // Log.e("", itemView.getLayoutParams().width + " , " + itemView.getLayoutParams().height); } } } ================================================ FILE: sample/src/main/java/com/zhy/sample/fragment/RegisterFragment.java ================================================ package com.zhy.sample.fragment; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.zhy.sample.R; public class RegisterFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_register, container,false); } } ================================================ FILE: sample/src/main/java/com/zhy/sample/fragment/SimpleFragment.java ================================================ package com.zhy.sample.fragment; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.zhy.sample.R; public class SimpleFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.activity_main, container, false); } } ================================================ FILE: sample/src/main/java/com/zhy/sample/fragment/TestFragment.java ================================================ package com.zhy.sample.fragment; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.zhy.sample.R; public class TestFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.activity_test, container, false); } } ================================================ FILE: sample/src/main/java/com/zhy/sample/view/AutoCardView.java ================================================ package com.zhy.sample.view; import android.content.Context; import android.support.v7.widget.CardView; import android.util.AttributeSet; import com.zhy.autolayout.AutoFrameLayout; import com.zhy.autolayout.utils.AutoLayoutHelper; /** * Created by zhy on 15/12/8. */ public class AutoCardView extends CardView { private final AutoLayoutHelper mHelper = new AutoLayoutHelper(this); public AutoCardView(Context context) { super(context); } public AutoCardView(Context context, AttributeSet attrs) { super(context, attrs); } public AutoCardView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public AutoFrameLayout.LayoutParams generateLayoutParams(AttributeSet attrs) { return new AutoFrameLayout.LayoutParams(getContext(), attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if (!isInEditMode()) { mHelper.adjustChildren(); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } ================================================ FILE: sample/src/main/java/com/zhy/sample/view/DividerItemDecoration.java ================================================ package com.zhy.sample.view;/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * limitations under the License. */ import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; import android.view.View; /** * This class is from the v7 samples of the Android SDK. It's not by me! *

* See the license above for details. */ public class DividerItemDecoration extends RecyclerView.ItemDecoration { private static final int[] ATTRS = new int[]{ android.R.attr.listDivider }; public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; private Drawable mDivider; private int mOrientation; public DividerItemDecoration(Context context, int orientation) { final TypedArray a = context.obtainStyledAttributes(ATTRS); mDivider = a.getDrawable(0); a.recycle(); setOrientation(orientation); } public void setOrientation(int orientation) { if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { throw new IllegalArgumentException("invalid orientation"); } mOrientation = orientation; } @Override public void onDraw(Canvas c, RecyclerView parent) { Log.v("recyclerview - itemdecoration", "onDraw()"); if (mOrientation == VERTICAL_LIST) { drawVertical(c, parent); } else { drawHorizontal(c, parent); } } public void drawVertical(Canvas c, RecyclerView parent) { final int left = parent.getPaddingLeft(); final int right = parent.getWidth() - parent.getPaddingRight(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); RecyclerView v = new RecyclerView(parent.getContext()); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int top = child.getBottom() + params.bottomMargin; final int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } public void drawHorizontal(Canvas c, RecyclerView parent) { final int top = parent.getPaddingTop(); final int bottom = parent.getHeight() - parent.getPaddingBottom(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int left = child.getRight() + params.rightMargin; final int right = left + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } @Override public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { if (mOrientation == VERTICAL_LIST) { outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } else { outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); } } } ================================================ FILE: sample/src/main/res/drawable/selector_btn_stroke_orange.xml ================================================ ================================================ FILE: sample/src/main/res/drawable/selector_pay_radio.xml ================================================ ================================================ FILE: sample/src/main/res/drawable/shape_btn_edge_orange.xml ================================================ ================================================ FILE: sample/src/main/res/drawable/shape_btn_edge_orange_pre.xml ================================================ ================================================ FILE: sample/src/main/res/drawable/shape_edit_stroke.xml ================================================ ================================================ FILE: sample/src/main/res/layout/activity_category.xml ================================================ ================================================ FILE: sample/src/main/res/layout/activity_main.xml ================================================ ================================================ FILE: sample/src/main/res/layout/activity_test.xml ================================================ ================================================ FILE: sample/src/main/res/layout/app_base_title.xml ================================================ ================================================ FILE: sample/src/main/res/layout/fragment_list.xml ================================================ ================================================ FILE: sample/src/main/res/layout/fragment_pay.xml ================================================ ================================================ FILE: sample/src/main/res/layout/fragment_recyclerview.xml ================================================ ================================================ FILE: sample/src/main/res/layout/fragment_recyclerview_grid.xml ================================================ ================================================ FILE: sample/src/main/res/layout/fragment_register.xml ================================================ ================================================ FILE: sample/src/main/res/layout/list_item.xml ================================================ ================================================ FILE: sample/src/main/res/layout/recyclerview_item.xml ================================================ ================================================ FILE: sample/src/main/res/layout/recyclerview_item_grid.xml ================================================ ================================================ FILE: sample/src/main/res/menu/menu_main.xml ================================================

================================================ FILE: sample/src/main/res/menu/menu_test.xml ================================================ ================================================ FILE: sample/src/main/res/values/attrs.xml ================================================ ================================================ FILE: sample/src/main/res/values/color.xml ================================================ #ff6600 #c8580d #d7d7d7 #c9c9c9 #c3c3c3 #666666 #f31216 #f3f3f3 ================================================ FILE: sample/src/main/res/values/dimens.xml ================================================ 16dp 16dp 20px 020px 20dp ================================================ FILE: sample/src/main/res/values/strings.xml ================================================ sample Hello world! Settings TestActivity ================================================ FILE: sample/src/main/res/values/styles.xml ================================================ ================================================ FILE: sample/src/main/res/values-w820dp/dimens.xml ================================================ 64dp ================================================ FILE: settings.gradle ================================================ include ':sample', ':autolayout', ':widgetsample', ':autolayout-widget' ================================================ FILE: widgetsample/.gitignore ================================================ /build ================================================ FILE: widgetsample/build.gradle ================================================ apply plugin: 'com.android.application' android { compileSdkVersion 23 buildToolsVersion "23.0.1" defaultConfig { applicationId "com.zhy.autolayout.test.widgets" minSdkVersion 10 targetSdkVersion 23 versionCode 1 versionName "1.0" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile project(':autolayout') compile project(':autolayout-widget') compile 'com.android.support:design:23.1.1' compile 'com.android.support:support-v4:23.1.1' compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:gridlayout-v7:23.1.1' compile 'com.android.support:cardview-v7:23.1.1' } ================================================ FILE: widgetsample/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in /Users/zhy/android/sdk/android-sdk-macosx/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} ================================================ FILE: widgetsample/src/androidTest/java/com/zhy/autolayout/test/widgets/ApplicationTest.java ================================================ package com.zhy.autolayout.test.widgets; import android.app.Application; import android.test.ApplicationTestCase; /** * Testing Fundamentals */ public class ApplicationTest extends ApplicationTestCase { public ApplicationTest() { super(Application.class); } } ================================================ FILE: widgetsample/src/main/AndroidManifest.xml ================================================ ================================================ FILE: widgetsample/src/main/java/com/zhy/autolayout/test/widgets/MainActivity.java ================================================ package com.zhy.autolayout.test.widgets; import android.os.Bundle; import android.support.design.widget.TabLayout; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import com.zhy.autolayout.test.widgets.fragments.SimpleFragment; import com.zhy.autolayout.widget.AutoLayoutWidgetActivity; public class MainActivity extends AutoLayoutWidgetActivity { private TabLayout mTabLayout; private ViewPager mViewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); toolbar.setTitle("标题"); setSupportActionBar(toolbar); mTabLayout = (TabLayout) findViewById(R.id.id_tablayout); mViewPager = (ViewPager) findViewById(R.id.id_viewpager); mViewPager.setAdapter(new FragmentPagerAdapter(getSupportFragmentManager()) { @Override public Fragment getItem(int position) { return new SimpleFragment(); } @Override public int getCount() { return 2; } @Override public CharSequence getPageTitle(int position) { return "Page " + position; } }); mTabLayout.setupWithViewPager(mViewPager); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } } ================================================ FILE: widgetsample/src/main/java/com/zhy/autolayout/test/widgets/fragments/SimpleFragment.java ================================================ package com.zhy.autolayout.test.widgets.fragments; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.zhy.autolayout.test.widgets.R; /** * Created by zhy on 16/3/3. */ public class SimpleFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_simple, container, false); } } ================================================ FILE: widgetsample/src/main/res/layout/activity_main.xml ================================================ ================================================ FILE: widgetsample/src/main/res/layout/fragment_simple.xml ================================================ ================================================ FILE: widgetsample/src/main/res/menu/menu_main.xml ================================================ ================================================ FILE: widgetsample/src/main/res/values/dimens.xml ================================================ 16dp 16dp ================================================ FILE: widgetsample/src/main/res/values/strings.xml ================================================ widgetSample Hello world! 设置 ================================================ FILE: widgetsample/src/main/res/values/styles.xml ================================================ ================================================ FILE: widgetsample/src/main/res/values-w820dp/dimens.xml ================================================ 64dp