├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README-zh.md ├── README.md ├── _config.yml ├── art ├── 1080x1920_external.png ├── 1080x1920_height.png ├── 1080x1920_width.png ├── 1440x2560_external.png ├── 1440x2560_height.png ├── 1440x2560_width.png ├── 1440x2880_external.png ├── 1440x2880_height.png ├── 1440x2880_width.png ├── 480x800_external.png ├── 480x800_height.png ├── 480x800_width.png ├── 768x1280_external.png ├── 768x1280_height.png ├── 768x1280_width.png ├── autosize_banner.jpg ├── create_step.png ├── theme_panel.png ├── unit_dp.png ├── unit_in.png ├── unit_mm.png └── unit_pt.png ├── autosize ├── .gitignore ├── bintray.gradle ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── me │ └── jessyan │ └── autosize │ ├── ActivityLifecycleCallbacksImpl.java │ ├── AutoAdaptStrategy.java │ ├── AutoSize.java │ ├── AutoSizeCompat.java │ ├── AutoSizeConfig.java │ ├── DefaultAutoAdaptStrategy.java │ ├── DisplayMetricsInfo.java │ ├── FragmentLifecycleCallbacksImpl.java │ ├── FragmentLifecycleCallbacksImplToAndroidx.java │ ├── InitProvider.java │ ├── WrapperAutoAdaptStrategy.java │ ├── external │ ├── ExternalAdaptInfo.java │ └── ExternalAdaptManager.java │ ├── internal │ ├── CancelAdapt.java │ └── CustomAdapt.java │ ├── onAdaptListener.java │ ├── unit │ ├── Subunits.java │ └── UnitsManager.java │ └── utils │ ├── AutoSizeLog.java │ ├── AutoSizeUtils.java │ ├── Preconditions.java │ └── ScreenUtils.java ├── build.gradle ├── demo-androidx ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── me │ │ └── jessyan │ │ └── autosize │ │ └── demo │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── me │ │ │ └── jessyan │ │ │ └── autosize │ │ │ └── demo │ │ │ └── androidx │ │ │ ├── BaseApplication.java │ │ │ ├── CustomAdaptActivity.java │ │ │ ├── CustomFragment1.java │ │ │ ├── CustomFragment2.java │ │ │ ├── CustomFragment3.java │ │ │ ├── FragmentHost.java │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_custom_adapt.xml │ │ ├── activity_host.xml │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── autosize_logo.png │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── me │ └── jessyan │ └── autosize │ └── demo │ └── ExampleUnitTest.java ├── demo-subunits ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── me │ │ └── jessyan │ │ └── autosize │ │ └── demo │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── me │ │ │ └── jessyan │ │ │ └── autosize │ │ │ └── demo │ │ │ └── subunits │ │ │ ├── BaseApplication.java │ │ │ ├── CustomAdaptActivity.java │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_custom_adapt.xml │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── autosize_logo.png │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── me │ └── jessyan │ └── autosize │ └── demo │ └── ExampleUnitTest.java ├── demo ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── me │ │ └── jessyan │ │ └── autosize │ │ └── demo │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── me │ │ │ └── jessyan │ │ │ └── autosize │ │ │ └── demo │ │ │ ├── BaseApplication.java │ │ │ ├── CustomAdaptActivity.java │ │ │ ├── CustomFragment1.java │ │ │ ├── CustomFragment2.java │ │ │ ├── CustomFragment3.java │ │ │ ├── FragmentHost.java │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── activity_custom_adapt.xml │ │ ├── activity_host.xml │ │ └── activity_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── autosize_logo.png │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── me │ └── jessyan │ └── autosize │ └── demo │ └── ExampleUnitTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ### Environment 5 | - [x] Autosize Version: 6 | - [x] Target Android Version: 7 | - [x] Device Model: 8 | - [x] Device Resolution: 9 | - [x] Design Size On AndroidManifest: 10 | 11 | 12 | ### Bug Description: 13 | 14 | 15 | 16 | ### Log: 17 | 18 | ```log 19 | 20 | 21 | ``` 22 | 23 | 24 | ### Screenshot 25 | 26 | 27 | 28 | ### Related Code: 29 | ```java 30 | 31 | 32 | ``` 33 | 34 | 35 | ### Others: 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea 38 | 39 | # Keystore files 40 | *.jks 41 | 42 | # MacOS 43 | .DS_Store 44 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | jdk: oraclejdk8 3 | before_install: 4 | - yes | sdkmanager "platforms;android-29" 5 | 6 | env: 7 | global: 8 | - ANDROID_API_LEVEL=29 9 | - ANDROID_BUILD_TOOLS_VERSION=29.0.2 10 | - TRAVIS_SECURE_ENV_VARS=true 11 | 12 | android: 13 | components: 14 | # The BuildTools version used by your project 15 | - tools 16 | - platform-tools 17 | - build-tools-$ANDROID_BUILD_TOOLS_VERSION 18 | - extra-android-m2repository 19 | - extra-google-android-support 20 | 21 | # The SDK version used to compile your project 22 | - android-$ANDROID_API_LEVEL 23 | licenses: 24 | - '.+' 25 | 26 | script: 27 | - ./gradlew clean 28 | - ./gradlew assembleDebug -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | [ChangeLog](https://github.com/JessYanCoding/AndroidAutoSize/releases) -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-modernist -------------------------------------------------------------------------------- /art/1080x1920_external.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/1080x1920_external.png -------------------------------------------------------------------------------- /art/1080x1920_height.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/1080x1920_height.png -------------------------------------------------------------------------------- /art/1080x1920_width.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/1080x1920_width.png -------------------------------------------------------------------------------- /art/1440x2560_external.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/1440x2560_external.png -------------------------------------------------------------------------------- /art/1440x2560_height.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/1440x2560_height.png -------------------------------------------------------------------------------- /art/1440x2560_width.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/1440x2560_width.png -------------------------------------------------------------------------------- /art/1440x2880_external.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/1440x2880_external.png -------------------------------------------------------------------------------- /art/1440x2880_height.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/1440x2880_height.png -------------------------------------------------------------------------------- /art/1440x2880_width.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/1440x2880_width.png -------------------------------------------------------------------------------- /art/480x800_external.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/480x800_external.png -------------------------------------------------------------------------------- /art/480x800_height.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/480x800_height.png -------------------------------------------------------------------------------- /art/480x800_width.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/480x800_width.png -------------------------------------------------------------------------------- /art/768x1280_external.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/768x1280_external.png -------------------------------------------------------------------------------- /art/768x1280_height.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/768x1280_height.png -------------------------------------------------------------------------------- /art/768x1280_width.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/768x1280_width.png -------------------------------------------------------------------------------- /art/autosize_banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/autosize_banner.jpg -------------------------------------------------------------------------------- /art/create_step.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/create_step.png -------------------------------------------------------------------------------- /art/theme_panel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/theme_panel.png -------------------------------------------------------------------------------- /art/unit_dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/unit_dp.png -------------------------------------------------------------------------------- /art/unit_in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/unit_in.png -------------------------------------------------------------------------------- /art/unit_mm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/unit_mm.png -------------------------------------------------------------------------------- /art/unit_pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JessYanCoding/AndroidAutoSize/e402ecdd998ea07549513ac08c12e9f097f3b48c/art/unit_pt.png -------------------------------------------------------------------------------- /autosize/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /autosize/bintray.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.novoda.bintray-release' 2 | 3 | allprojects { 4 | repositories { 5 | jcenter() 6 | } 7 | tasks.withType(Javadoc) { 8 | options{ 9 | encoding "UTF-8" 10 | charSet 'UTF-8' 11 | links "http://docs.oracle.com/javase/7/docs/api" 12 | } 13 | options.addStringOption('Xdoclint:none', '-quiet') 14 | } 15 | } 16 | 17 | 18 | def siteUrl = 'https://github.com/JessYanCoding/AndroidAutoSize' // 项目的主页 19 | 20 | publish { 21 | userOrg = 'jessyancoding' //bintray注册的用户名 22 | groupId = 'me.jessyan' //compile引用时的第1部分groupId 23 | artifactId = 'autosize' //compile引用时的第2部分项目名 24 | publishVersion = rootProject.versionName //compile引用时的第3部分版本号 25 | desc = '一个极低成本的 Android 屏幕适配方案' 26 | website = siteUrl 27 | } 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /autosize/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion rootProject.compileSdkVersion 5 | buildToolsVersion rootProject.buildToolsVersion 6 | 7 | defaultConfig { 8 | minSdkVersion rootProject.minSdkVersion 9 | targetSdkVersion rootProject.targetSdkVersion 10 | versionCode rootProject.versionCode 11 | versionName rootProject.versionName 12 | consumerProguardFiles 'proguard-rules.pro' 13 | } 14 | 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | 22 | lintOptions { 23 | abortOnError false 24 | warning 'InvalidPackage' 25 | } 26 | } 27 | 28 | dependencies { 29 | compileOnly rootProject.appcompat_v7 30 | compileOnly rootProject.androidx_appcompat 31 | } 32 | 33 | apply from: 'bintray.gradle' -------------------------------------------------------------------------------- /autosize/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | 23 | -keep class me.jessyan.autosize.** { *; } 24 | -keep interface me.jessyan.autosize.** { *; } -------------------------------------------------------------------------------- /autosize/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 10 | 11 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/ActivityLifecycleCallbacksImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize; 17 | 18 | import android.app.Activity; 19 | import android.app.Application; 20 | import android.os.Bundle; 21 | 22 | import static me.jessyan.autosize.AutoSizeConfig.DEPENDENCY_ANDROIDX; 23 | import static me.jessyan.autosize.AutoSizeConfig.DEPENDENCY_SUPPORT; 24 | 25 | /** 26 | * ================================================ 27 | * {@link ActivityLifecycleCallbacksImpl} 可用来代替在 BaseActivity 中加入适配代码的传统方式 28 | * {@link ActivityLifecycleCallbacksImpl} 这种方案类似于 AOP, 面向接口, 侵入性低, 方便统一管理, 扩展性强, 并且也支持适配三方库的 {@link Activity} 29 | *

30 | * Created by JessYan on 2018/8/8 14:32 31 | * Contact me 32 | * Follow me 33 | * ================================================ 34 | */ 35 | public class ActivityLifecycleCallbacksImpl implements Application.ActivityLifecycleCallbacks { 36 | /** 37 | * 屏幕适配逻辑策略类 38 | */ 39 | private AutoAdaptStrategy mAutoAdaptStrategy; 40 | /** 41 | * 让 Fragment 支持自定义适配参数 42 | */ 43 | private FragmentLifecycleCallbacksImpl mFragmentLifecycleCallbacks; 44 | private FragmentLifecycleCallbacksImplToAndroidx mFragmentLifecycleCallbacksToAndroidx; 45 | 46 | public ActivityLifecycleCallbacksImpl(AutoAdaptStrategy autoAdaptStrategy) { 47 | if (DEPENDENCY_ANDROIDX) { 48 | mFragmentLifecycleCallbacksToAndroidx = new FragmentLifecycleCallbacksImplToAndroidx(autoAdaptStrategy); 49 | } else if (DEPENDENCY_SUPPORT){ 50 | mFragmentLifecycleCallbacks = new FragmentLifecycleCallbacksImpl(autoAdaptStrategy); 51 | } 52 | mAutoAdaptStrategy = autoAdaptStrategy; 53 | } 54 | 55 | @Override 56 | public void onActivityCreated(Activity activity, Bundle savedInstanceState) { 57 | if (AutoSizeConfig.getInstance().isCustomFragment()) { 58 | if (mFragmentLifecycleCallbacksToAndroidx != null && activity instanceof androidx.fragment.app.FragmentActivity) { 59 | ((androidx.fragment.app.FragmentActivity) activity).getSupportFragmentManager().registerFragmentLifecycleCallbacks(mFragmentLifecycleCallbacksToAndroidx, true); 60 | } else if (mFragmentLifecycleCallbacks != null && activity instanceof android.support.v4.app.FragmentActivity) { 61 | ((android.support.v4.app.FragmentActivity) activity).getSupportFragmentManager().registerFragmentLifecycleCallbacks(mFragmentLifecycleCallbacks, true); 62 | } 63 | } 64 | 65 | //Activity 中的 setContentView(View) 一定要在 super.onCreate(Bundle); 之后执行 66 | if (mAutoAdaptStrategy != null) { 67 | mAutoAdaptStrategy.applyAdapt(activity, activity); 68 | } 69 | } 70 | 71 | @Override 72 | public void onActivityStarted(Activity activity) { 73 | if (mAutoAdaptStrategy != null) { 74 | mAutoAdaptStrategy.applyAdapt(activity, activity); 75 | } 76 | } 77 | 78 | @Override 79 | public void onActivityResumed(Activity activity) { 80 | 81 | } 82 | 83 | @Override 84 | public void onActivityPaused(Activity activity) { 85 | 86 | } 87 | 88 | @Override 89 | public void onActivityStopped(Activity activity) { 90 | 91 | } 92 | 93 | @Override 94 | public void onActivitySaveInstanceState(Activity activity, Bundle outState) { 95 | 96 | } 97 | 98 | @Override 99 | public void onActivityDestroyed(Activity activity) { 100 | 101 | } 102 | 103 | /** 104 | * 设置屏幕适配逻辑策略类 105 | * 106 | * @param autoAdaptStrategy {@link AutoAdaptStrategy} 107 | */ 108 | public void setAutoAdaptStrategy(AutoAdaptStrategy autoAdaptStrategy) { 109 | mAutoAdaptStrategy = autoAdaptStrategy; 110 | if (mFragmentLifecycleCallbacksToAndroidx != null) { 111 | mFragmentLifecycleCallbacksToAndroidx.setAutoAdaptStrategy(autoAdaptStrategy); 112 | } else if (mFragmentLifecycleCallbacks != null) { 113 | mFragmentLifecycleCallbacks.setAutoAdaptStrategy(autoAdaptStrategy); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/AutoAdaptStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize; 17 | 18 | import android.app.Activity; 19 | import android.app.Application; 20 | import android.util.DisplayMetrics; 21 | 22 | /** 23 | * ================================================ 24 | * 屏幕适配逻辑策略类, 可通过 {@link AutoSizeConfig#init(Application, boolean, AutoAdaptStrategy)} 25 | * 和 {@link AutoSizeConfig#setAutoAdaptStrategy(AutoAdaptStrategy)} 切换策略 26 | * 27 | * @see DefaultAutoAdaptStrategy 28 | * Created by JessYan on 2018/8/9 15:13 29 | * Contact me 30 | * Follow me 31 | * ================================================ 32 | */ 33 | public interface AutoAdaptStrategy { 34 | 35 | /** 36 | * 开始执行屏幕适配逻辑 37 | * 38 | * @param target 需要屏幕适配的对象 (可能是 {@link Activity} 或者 Fragment) 39 | * @param activity 需要拿到当前的 {@link Activity} 才能修改 {@link DisplayMetrics#density} 40 | */ 41 | void applyAdapt(Object target, Activity activity); 42 | } 43 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/DefaultAutoAdaptStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize; 17 | 18 | import android.app.Activity; 19 | import android.app.Application; 20 | 21 | import java.util.Locale; 22 | 23 | import me.jessyan.autosize.external.ExternalAdaptInfo; 24 | import me.jessyan.autosize.internal.CancelAdapt; 25 | import me.jessyan.autosize.internal.CustomAdapt; 26 | import me.jessyan.autosize.utils.AutoSizeLog; 27 | 28 | /** 29 | * ================================================ 30 | * 屏幕适配逻辑策略默认实现类, 可通过 {@link AutoSizeConfig#init(Application, boolean, AutoAdaptStrategy)} 31 | * 和 {@link AutoSizeConfig#setAutoAdaptStrategy(AutoAdaptStrategy)} 切换策略 32 | * 33 | * @see AutoAdaptStrategy 34 | * Created by JessYan on 2018/8/9 15:57 35 | * Contact me 36 | * Follow me 37 | * ================================================ 38 | */ 39 | public class DefaultAutoAdaptStrategy implements AutoAdaptStrategy { 40 | @Override 41 | public void applyAdapt(Object target, Activity activity) { 42 | 43 | //检查是否开启了外部三方库的适配模式, 只要不主动调用 ExternalAdaptManager 的方法, 下面的代码就不会执行 44 | if (AutoSizeConfig.getInstance().getExternalAdaptManager().isRun()) { 45 | if (AutoSizeConfig.getInstance().getExternalAdaptManager().isCancelAdapt(target.getClass())) { 46 | AutoSizeLog.w(String.format(Locale.ENGLISH, "%s canceled the adaptation!", target.getClass().getName())); 47 | AutoSize.cancelAdapt(activity); 48 | return; 49 | } else { 50 | ExternalAdaptInfo info = AutoSizeConfig.getInstance().getExternalAdaptManager() 51 | .getExternalAdaptInfoOfActivity(target.getClass()); 52 | if (info != null) { 53 | AutoSizeLog.d(String.format(Locale.ENGLISH, "%s used %s for adaptation!", target.getClass().getName(), ExternalAdaptInfo.class.getName())); 54 | AutoSize.autoConvertDensityOfExternalAdaptInfo(activity, info); 55 | return; 56 | } 57 | } 58 | } 59 | 60 | //如果 target 实现 CancelAdapt 接口表示放弃适配, 所有的适配效果都将失效 61 | if (target instanceof CancelAdapt) { 62 | AutoSizeLog.w(String.format(Locale.ENGLISH, "%s canceled the adaptation!", target.getClass().getName())); 63 | AutoSize.cancelAdapt(activity); 64 | return; 65 | } 66 | 67 | //如果 target 实现 CustomAdapt 接口表示该 target 想自定义一些用于适配的参数, 从而改变最终的适配效果 68 | if (target instanceof CustomAdapt) { 69 | AutoSizeLog.d(String.format(Locale.ENGLISH, "%s implemented by %s!", target.getClass().getName(), CustomAdapt.class.getName())); 70 | AutoSize.autoConvertDensityOfCustomAdapt(activity, (CustomAdapt) target); 71 | } else { 72 | AutoSizeLog.d(String.format(Locale.ENGLISH, "%s used the global configuration.", target.getClass().getName())); 73 | AutoSize.autoConvertDensityOfGlobal(activity); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/DisplayMetricsInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize; 17 | 18 | import android.os.Parcel; 19 | import android.os.Parcelable; 20 | import android.util.DisplayMetrics; 21 | 22 | /** 23 | * ================================================ 24 | * {@link DisplayMetrics} 封装类 25 | *

26 | * Created by JessYan on 2018/8/11 16:42 27 | * Contact me 28 | * Follow me 29 | * ================================================ 30 | */ 31 | public class DisplayMetricsInfo implements Parcelable { 32 | private float density; 33 | private int densityDpi; 34 | private float scaledDensity; 35 | private float xdpi; 36 | private int screenWidthDp; 37 | private int screenHeightDp; 38 | 39 | public DisplayMetricsInfo(float density, int densityDpi, float scaledDensity, float xdpi) { 40 | this.density = density; 41 | this.densityDpi = densityDpi; 42 | this.scaledDensity = scaledDensity; 43 | this.xdpi = xdpi; 44 | } 45 | 46 | public DisplayMetricsInfo(float density, int densityDpi, float scaledDensity, float xdpi, int screenWidthDp, int screenHeightDp) { 47 | this.density = density; 48 | this.densityDpi = densityDpi; 49 | this.scaledDensity = scaledDensity; 50 | this.xdpi = xdpi; 51 | this.screenWidthDp = screenWidthDp; 52 | this.screenHeightDp = screenHeightDp; 53 | } 54 | 55 | public float getDensity() { 56 | return density; 57 | } 58 | 59 | public void setDensity(float density) { 60 | this.density = density; 61 | } 62 | 63 | public int getDensityDpi() { 64 | return densityDpi; 65 | } 66 | 67 | public void setDensityDpi(int densityDpi) { 68 | this.densityDpi = densityDpi; 69 | } 70 | 71 | public float getScaledDensity() { 72 | return scaledDensity; 73 | } 74 | 75 | public void setScaledDensity(float scaledDensity) { 76 | this.scaledDensity = scaledDensity; 77 | } 78 | 79 | public float getXdpi() { 80 | return xdpi; 81 | } 82 | 83 | public void setXdpi(float xdpi) { 84 | this.xdpi = xdpi; 85 | } 86 | 87 | public int getScreenWidthDp() { 88 | return screenWidthDp; 89 | } 90 | 91 | public void setScreenWidthDp(int screenWidthDp) { 92 | this.screenWidthDp = screenWidthDp; 93 | } 94 | 95 | public int getScreenHeightDp() { 96 | return screenHeightDp; 97 | } 98 | 99 | public void setScreenHeightDp(int screenHeightDp) { 100 | this.screenHeightDp = screenHeightDp; 101 | } 102 | 103 | @Override 104 | public int describeContents() { 105 | return 0; 106 | } 107 | 108 | @Override 109 | public void writeToParcel(Parcel dest, int flags) { 110 | dest.writeFloat(this.density); 111 | dest.writeInt(this.densityDpi); 112 | dest.writeFloat(this.scaledDensity); 113 | dest.writeFloat(this.xdpi); 114 | dest.writeInt(this.screenWidthDp); 115 | dest.writeInt(this.screenHeightDp); 116 | } 117 | 118 | protected DisplayMetricsInfo(Parcel in) { 119 | this.density = in.readFloat(); 120 | this.densityDpi = in.readInt(); 121 | this.scaledDensity = in.readFloat(); 122 | this.xdpi = in.readFloat(); 123 | this.screenWidthDp = in.readInt(); 124 | this.screenHeightDp = in.readInt(); 125 | } 126 | 127 | public static final Creator CREATOR = new Creator() { 128 | @Override 129 | public DisplayMetricsInfo createFromParcel(Parcel source) { 130 | return new DisplayMetricsInfo(source); 131 | } 132 | 133 | @Override 134 | public DisplayMetricsInfo[] newArray(int size) { 135 | return new DisplayMetricsInfo[size]; 136 | } 137 | }; 138 | 139 | @Override 140 | public String toString() { 141 | return "DisplayMetricsInfo{" + 142 | "density=" + density + 143 | ", densityDpi=" + densityDpi + 144 | ", scaledDensity=" + scaledDensity + 145 | ", xdpi=" + xdpi + 146 | ", screenWidthDp=" + screenWidthDp + 147 | ", screenHeightDp=" + screenHeightDp + 148 | '}'; 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/FragmentLifecycleCallbacksImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize; 17 | 18 | import android.os.Bundle; 19 | import android.support.v4.app.Fragment; 20 | import android.support.v4.app.FragmentManager; 21 | 22 | /** 23 | * ================================================ 24 | * {@link FragmentLifecycleCallbacksImpl} 可用来代替在 BaseFragment 中加入适配代码的传统方式 25 | * {@link FragmentLifecycleCallbacksImpl} 这种方案类似于 AOP, 面向接口, 侵入性低, 方便统一管理, 扩展性强, 并且也支持适配三方库的 {@link Fragment} 26 | *

27 | * Created by JessYan on 2018/8/25 13:52 28 | * Contact me 29 | * Follow me 30 | * ================================================ 31 | */ 32 | public class FragmentLifecycleCallbacksImpl extends FragmentManager.FragmentLifecycleCallbacks { 33 | /** 34 | * 屏幕适配逻辑策略类 35 | */ 36 | private AutoAdaptStrategy mAutoAdaptStrategy; 37 | 38 | public FragmentLifecycleCallbacksImpl(AutoAdaptStrategy autoAdaptStrategy) { 39 | mAutoAdaptStrategy = autoAdaptStrategy; 40 | } 41 | 42 | @Override 43 | public void onFragmentCreated(FragmentManager fm, Fragment f, Bundle savedInstanceState) { 44 | if (mAutoAdaptStrategy != null) { 45 | mAutoAdaptStrategy.applyAdapt(f, f.getActivity()); 46 | } 47 | } 48 | 49 | /** 50 | * 设置屏幕适配逻辑策略类 51 | * 52 | * @param autoAdaptStrategy {@link AutoAdaptStrategy} 53 | */ 54 | public void setAutoAdaptStrategy(AutoAdaptStrategy autoAdaptStrategy) { 55 | mAutoAdaptStrategy = autoAdaptStrategy; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/FragmentLifecycleCallbacksImplToAndroidx.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize; 17 | 18 | import android.os.Bundle; 19 | import androidx.fragment.app.Fragment; 20 | import androidx.fragment.app.FragmentManager; 21 | 22 | /** 23 | * ================================================ 24 | * {@link FragmentLifecycleCallbacksImplToAndroidx} 可用来代替在 BaseFragment 中加入适配代码的传统方式 25 | * {@link FragmentLifecycleCallbacksImplToAndroidx} 这种方案类似于 AOP, 面向接口, 侵入性低, 方便统一管理, 扩展性强, 并且也支持适配三方库的 {@link Fragment} 26 | *

27 | * Created by JessYan on 2018/8/25 13:52 28 | * Contact me 29 | * Follow me 30 | * ================================================ 31 | */ 32 | public class FragmentLifecycleCallbacksImplToAndroidx extends FragmentManager.FragmentLifecycleCallbacks { 33 | /** 34 | * 屏幕适配逻辑策略类 35 | */ 36 | private AutoAdaptStrategy mAutoAdaptStrategy; 37 | 38 | public FragmentLifecycleCallbacksImplToAndroidx(AutoAdaptStrategy autoAdaptStrategy) { 39 | mAutoAdaptStrategy = autoAdaptStrategy; 40 | } 41 | 42 | @Override 43 | public void onFragmentCreated(FragmentManager fm, Fragment f, Bundle savedInstanceState) { 44 | if (mAutoAdaptStrategy != null) { 45 | mAutoAdaptStrategy.applyAdapt(f, f.getActivity()); 46 | } 47 | } 48 | 49 | /** 50 | * 设置屏幕适配逻辑策略类 51 | * 52 | * @param autoAdaptStrategy {@link AutoAdaptStrategy} 53 | */ 54 | public void setAutoAdaptStrategy(AutoAdaptStrategy autoAdaptStrategy) { 55 | mAutoAdaptStrategy = autoAdaptStrategy; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/InitProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize; 17 | 18 | import android.content.Context; 19 | import android.app.Application; 20 | import android.content.ContentProvider; 21 | import android.content.ContentValues; 22 | import android.database.Cursor; 23 | import android.net.Uri; 24 | 25 | import me.jessyan.autosize.utils.AutoSizeUtils; 26 | 27 | /** 28 | * ================================================ 29 | * 通过声明 {@link ContentProvider} 自动完成初始化 30 | * Created by JessYan on 2018/8/19 11:55 31 | * Contact me 32 | * Follow me 33 | * ================================================ 34 | */ 35 | public class InitProvider extends ContentProvider { 36 | @Override 37 | public boolean onCreate() { 38 | Context application = getContext().getApplicationContext(); 39 | if (application == null) { 40 | application = AutoSizeUtils.getApplicationByReflect(); 41 | } 42 | AutoSizeConfig.getInstance() 43 | .setLog(true) 44 | .init((Application) application) 45 | .setUseDeviceSize(false); 46 | return true; 47 | } 48 | 49 | @Override 50 | public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 51 | return null; 52 | } 53 | 54 | @Override 55 | public String getType(Uri uri) { 56 | return null; 57 | } 58 | 59 | @Override 60 | public Uri insert(Uri uri, ContentValues values) { 61 | return null; 62 | } 63 | 64 | @Override 65 | public int delete(Uri uri, String selection, String[] selectionArgs) { 66 | return 0; 67 | } 68 | 69 | @Override 70 | public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 71 | return 0; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/WrapperAutoAdaptStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize; 17 | 18 | import android.app.Activity; 19 | 20 | /** 21 | * ================================================ 22 | * {@link AutoAdaptStrategy} 的包装者, 用于给 {@link AutoAdaptStrategy} 的实现类增加一些额外的职责 23 | *

24 | * Created by JessYan on 2018/10/30 15:07 25 | * Contact me 26 | * Follow me 27 | * ================================================ 28 | */ 29 | public class WrapperAutoAdaptStrategy implements AutoAdaptStrategy { 30 | private final AutoAdaptStrategy mAutoAdaptStrategy; 31 | 32 | public WrapperAutoAdaptStrategy(AutoAdaptStrategy autoAdaptStrategy) { 33 | mAutoAdaptStrategy = autoAdaptStrategy; 34 | } 35 | 36 | @Override 37 | public void applyAdapt(Object target, Activity activity) { 38 | onAdaptListener onAdaptListener = AutoSizeConfig.getInstance().getOnAdaptListener(); 39 | if (onAdaptListener != null){ 40 | onAdaptListener.onAdaptBefore(target, activity); 41 | } 42 | if (mAutoAdaptStrategy != null) { 43 | mAutoAdaptStrategy.applyAdapt(target, activity); 44 | } 45 | if (onAdaptListener != null){ 46 | onAdaptListener.onAdaptAfter(target, activity); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/external/ExternalAdaptInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.external; 17 | 18 | import android.app.Activity; 19 | import android.os.Parcel; 20 | import android.os.Parcelable; 21 | 22 | /** 23 | * ================================================ 24 | * {@link ExternalAdaptInfo} 用来存储外部三方库的适配参数, 因为 AndroidAutoSize 默认会对项目中的所有模块都进行适配 25 | * 三方库的 {@link Activity} 也不例外, 但三方库的适配参数可能和自己项目中的适配参数不一致, 导致三方库的适配效果和理想的效果差别很大 26 | * 所以需要向 AndroidAutoSize 提供三方库的适配参数, 已完成对三方库的屏幕适配 27 | *

28 | * Created by JessYan on 2018/8/9 18:19 29 | * Contact me 30 | * Follow me 31 | * ================================================ 32 | */ 33 | public class ExternalAdaptInfo implements Parcelable { 34 | /** 35 | * 是否按照宽度进行等比例适配 (为了保证在高宽比不同的屏幕上也能正常适配, 所以只能在宽度和高度之中选一个作为基准进行适配) 36 | * {@code true} 为按照宽度适配, {@code false} 为按照高度适配 37 | */ 38 | private boolean isBaseOnWidth; 39 | /** 40 | * 设计图上的设计尺寸, 单位 dp (三方库页面的设计图尺寸可能无法获知, 所以如果想让三方库的适配效果达到最好, 只有靠不断的尝试) 41 | * {@link #sizeInDp} 须配合 {@link #isBaseOnWidth} 使用, 规则如下: 42 | * 如果 {@link #isBaseOnWidth} 设置为 {@code true}, {@link #sizeInDp} 则应该设置为设计图的总宽度 43 | * 如果 {@link #isBaseOnWidth} 设置为 {@code false}, {@link #sizeInDp} 则应该设置为设计图的总高度 44 | * 如果您不需要自定义设计图上的设计尺寸, 想继续使用在 AndroidManifest 中填写的设计图尺寸, {@link #sizeInDp} 则设置为 {@code 0} 45 | */ 46 | private float sizeInDp; 47 | 48 | public ExternalAdaptInfo(boolean isBaseOnWidth) { 49 | this.isBaseOnWidth = isBaseOnWidth; 50 | } 51 | 52 | public ExternalAdaptInfo(boolean isBaseOnWidth, float sizeInDp) { 53 | this.isBaseOnWidth = isBaseOnWidth; 54 | this.sizeInDp = sizeInDp; 55 | } 56 | 57 | public boolean isBaseOnWidth() { 58 | return isBaseOnWidth; 59 | } 60 | 61 | public void setBaseOnWidth(boolean baseOnWidth) { 62 | isBaseOnWidth = baseOnWidth; 63 | } 64 | 65 | public float getSizeInDp() { 66 | return sizeInDp; 67 | } 68 | 69 | public void setSizeInDp(float sizeInDp) { 70 | this.sizeInDp = sizeInDp; 71 | } 72 | 73 | @Override 74 | public int describeContents() { 75 | return 0; 76 | } 77 | 78 | @Override 79 | public void writeToParcel(Parcel dest, int flags) { 80 | dest.writeByte(this.isBaseOnWidth ? (byte) 1 : (byte) 0); 81 | dest.writeFloat(this.sizeInDp); 82 | } 83 | 84 | protected ExternalAdaptInfo(Parcel in) { 85 | this.isBaseOnWidth = in.readByte() != 0; 86 | this.sizeInDp = in.readFloat(); 87 | } 88 | 89 | public static final Creator CREATOR = new Creator() { 90 | @Override 91 | public ExternalAdaptInfo createFromParcel(Parcel source) { 92 | return new ExternalAdaptInfo(source); 93 | } 94 | 95 | @Override 96 | public ExternalAdaptInfo[] newArray(int size) { 97 | return new ExternalAdaptInfo[size]; 98 | } 99 | }; 100 | 101 | @Override 102 | public String toString() { 103 | return "ExternalAdaptInfo{" + 104 | "isBaseOnWidth=" + isBaseOnWidth + 105 | ", sizeInDp=" + sizeInDp + 106 | '}'; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/external/ExternalAdaptManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.external; 17 | 18 | import android.app.Activity; 19 | 20 | import java.util.ArrayList; 21 | import java.util.HashMap; 22 | import java.util.List; 23 | import java.util.Map; 24 | 25 | import me.jessyan.autosize.AutoSizeConfig; 26 | import me.jessyan.autosize.utils.Preconditions; 27 | 28 | /** 29 | * ================================================ 30 | * 管理三方库的适配信息和状态, 通过 {@link AutoSizeConfig#getExternalAdaptManager()} 获取, 切勿自己 new 31 | * AndroidAutoSize 通过实现接口的方式来让每个 {@link Activity} 都具有自定义适配参数的功能, 从而让每个 {@link Activity} 都可以自定义适配效果 32 | * 但通过远程依赖的三方库并不能修改源码, 所以也不能让三方库的 {@link Activity} 实现接口, 实现接口的方式就显得无能为力 33 | * {@link ExternalAdaptManager} 就是专门用来处理这个问题, 项目初始化时把对应的三方库 {@link Activity} 传入 {@link ExternalAdaptManager} 即可 34 | *

35 | * Created by JessYan on 2018/8/10 14:40 36 | * Contact me 37 | * Follow me 38 | * ================================================ 39 | */ 40 | public class ExternalAdaptManager { 41 | private List mCancelAdaptList; 42 | private Map mExternalAdaptInfos; 43 | private boolean isRun; 44 | 45 | /** 46 | * 将不需要适配的第三方库 {@link Activity} 添加进来 (但不局限于三方库), 即可让该 {@link Activity} 的适配效果失效 47 | *

48 | * 支持链式调用, 如: 49 | * {@link ExternalAdaptManager#addCancelAdaptOfActivity(Class)#addCancelAdaptOfActivity(Class)} 50 | * 51 | * @param targetClass {@link Activity} class, Fragment class 52 | */ 53 | public synchronized ExternalAdaptManager addCancelAdaptOfActivity(Class targetClass) { 54 | Preconditions.checkNotNull(targetClass, "targetClass == null"); 55 | if (!isRun) { 56 | isRun = true; 57 | } 58 | if (mCancelAdaptList == null) { 59 | mCancelAdaptList = new ArrayList<>(); 60 | } 61 | mCancelAdaptList.add(targetClass.getCanonicalName()); 62 | return this; 63 | } 64 | 65 | /** 66 | * 将需要提供自定义适配参数的三方库 {@link Activity} 添加进来 (但不局限于三方库), 即可让该 {@link Activity} 根据自己提供的适配参数进行适配 67 | * 默认的全局适配参数不能满足您时可以使用此方法 68 | *

69 | * 一般用于三方库的 Activity, 因为三方库的设计图尺寸可能和项目自身的设计图尺寸不一致, 所以要想完美适配三方库的页面 70 | * 就需要提供三方库的设计图尺寸, 以及适配的方向 (以宽为基准还是高为基准?) 71 | * 三方库页面的设计图尺寸可能无法获知, 所以如果想让三方库的适配效果达到最好, 只有靠不断的尝试 72 | * 由于 AndroidAutoSize 可以让布局在所有设备上都等比例缩放, 所以只要您在一个设备上测试出了一个最完美的设计图尺寸 73 | * 那这个三方库页面在其他设备上也会呈现出同样的适配效果, 等比例缩放, 所以也就完成了三方库页面的屏幕适配 74 | * 即使在不改三方库源码的情况下也可以完美适配三方库的页面, 这就是 AndroidAutoSize 的优势 75 | * 但前提是三方库页面的布局使用的是 dp 和 sp, 如果布局全部使用的 px, 那 AndroidAutoSize 也将无能为力 76 | *

77 | * 支持链式调用, 如: 78 | * {@link ExternalAdaptManager#addExternalAdaptInfoOfActivity(Class, ExternalAdaptInfo)#addExternalAdaptInfoOfActivity(Class, ExternalAdaptInfo)} 79 | * 80 | * @param targetClass {@link Activity} class, Fragment class 81 | * @param info {@link ExternalAdaptInfo} 适配参数 82 | */ 83 | public synchronized ExternalAdaptManager addExternalAdaptInfoOfActivity(Class targetClass, ExternalAdaptInfo info) { 84 | Preconditions.checkNotNull(targetClass, "targetClass == null"); 85 | if (!isRun) { 86 | isRun = true; 87 | } 88 | if (mExternalAdaptInfos == null) { 89 | mExternalAdaptInfos = new HashMap<>(16); 90 | } 91 | mExternalAdaptInfos.put(targetClass.getCanonicalName(), info); 92 | return this; 93 | } 94 | 95 | /** 96 | * 这个 {@link Activity} 是否存在在取消适配的列表中, 如果在, 则该 {@link Activity} 适配失效 97 | * 98 | * @param targetClass {@link Activity} class, Fragment class 99 | * @return {@code true} 为存在, {@code false} 为不存在 100 | */ 101 | public synchronized boolean isCancelAdapt(Class targetClass) { 102 | Preconditions.checkNotNull(targetClass, "targetClass == null"); 103 | if (mCancelAdaptList == null) { 104 | return false; 105 | } 106 | return mCancelAdaptList.contains(targetClass.getCanonicalName()); 107 | } 108 | 109 | /** 110 | * 这个 {@link Activity} 是否提供有自定义的适配参数, 如果有则使用此适配参数进行适配 111 | * 112 | * @param targetClass {@link Activity} class, Fragment class 113 | * @return 如果返回 {@code null} 则说明该 {@link Activity} 没有提供自定义的适配参数 114 | */ 115 | public synchronized ExternalAdaptInfo getExternalAdaptInfoOfActivity(Class targetClass) { 116 | Preconditions.checkNotNull(targetClass, "targetClass == null"); 117 | if (mExternalAdaptInfos == null) { 118 | return null; 119 | } 120 | return mExternalAdaptInfos.get(targetClass.getCanonicalName()); 121 | } 122 | 123 | /** 124 | * 此管理器是否已经启动 125 | * 126 | * @return {@code true} 为已经启动, {@code false} 为没有启动 127 | */ 128 | public boolean isRun() { 129 | return isRun; 130 | } 131 | 132 | /** 133 | * 设置管理器的运行状态 134 | * 135 | * @param run {@code true} 为让管理器启动运行, {@code false} 为让管理器停止运行 136 | */ 137 | public ExternalAdaptManager setRun(boolean run) { 138 | isRun = run; 139 | return this; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/internal/CancelAdapt.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.internal; 17 | 18 | import android.app.Activity; 19 | 20 | /** 21 | * ================================================ 22 | * AndroidAutoSize 默认项目中的所有模块都使用适配功能, 三方库的 {@link Activity} 也不例外 23 | * 如果某个页面不想使用适配功能, 请让该页面 {@link Activity} 实现此接口 24 | * 实现此接口表示放弃适配, 所有的适配效果都将失效 25 | *

26 | * Created by JessYan on 2018/8/9 09:54 27 | * Contact me 28 | * Follow me 29 | * ================================================ 30 | */ 31 | public interface CancelAdapt { 32 | } 33 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/internal/CustomAdapt.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.internal; 17 | 18 | import android.app.Activity; 19 | 20 | /** 21 | * ================================================ 22 | * 如果某些页面不想使用 AndroidAutoSize 初始化时设置的默认适配参数, 请让该页面 {@link Activity} 实现此接口 23 | * 实现此接口即可自定义用于适配的一些参数, 从而影响最终的适配效果 24 | *

25 | * Created by JessYan on 2018/8/9 10:25 26 | * Contact me 27 | * Follow me 28 | * ================================================ 29 | */ 30 | public interface CustomAdapt { 31 | 32 | /** 33 | * 是否按照宽度进行等比例适配 (为了保证在高宽比不同的屏幕上也能正常适配, 所以只能在宽度和高度之中选一个作为基准进行适配) 34 | * 35 | * @return {@code true} 为按照宽度适配, {@code false} 为按照高度适配 36 | */ 37 | boolean isBaseOnWidth(); 38 | 39 | /** 40 | * 返回设计图上的设计尺寸, 单位 dp 41 | * {@link #getSizeInDp} 须配合 {@link #isBaseOnWidth()} 使用, 规则如下: 42 | * 如果 {@link #isBaseOnWidth()} 返回 {@code true}, {@link #getSizeInDp} 则应该返回设计图的总宽度 43 | * 如果 {@link #isBaseOnWidth()} 返回 {@code false}, {@link #getSizeInDp} 则应该返回设计图的总高度 44 | * 如果您不需要自定义设计图上的设计尺寸, 想继续使用在 AndroidManifest 中填写的设计图尺寸, {@link #getSizeInDp} 则返回 {@code 0} 45 | * 46 | * @return 设计图上的设计尺寸, 单位 dp 47 | */ 48 | float getSizeInDp(); 49 | } 50 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/onAdaptListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize; 17 | 18 | import android.app.Activity; 19 | 20 | /** 21 | * ================================================ 22 | * 屏幕适配监听器,用于监听屏幕适配时的一些事件 23 | *

24 | * Created by JessYan on 2018/10/30 16:29 25 | * Contact me 26 | * Follow me 27 | * ================================================ 28 | */ 29 | public interface onAdaptListener { 30 | /** 31 | * 在屏幕适配前调用 32 | * 33 | * @param target 需要屏幕适配的对象 (可能是 {@link Activity} 或者 Fragment) 34 | * @param activity 当前 {@link Activity} 35 | */ 36 | void onAdaptBefore(Object target, Activity activity); 37 | 38 | /** 39 | * 在屏幕适配后调用 40 | * 41 | * @param target 需要屏幕适配的对象 (可能是 {@link Activity} 或者 Fragment) 42 | * @param activity 当前 {@link Activity} 43 | */ 44 | void onAdaptAfter(Object target, Activity activity); 45 | } 46 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/unit/Subunits.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.unit; 17 | 18 | import android.util.DisplayMetrics; 19 | 20 | /** 21 | * ================================================ 22 | * AndroidAutoSize 支持一些在 Android 系统上比较少见的单位作为副单位, 用于规避修改 {@link DisplayMetrics#density} 23 | * 所造成的对于其他使用 dp 布局的系统控件或三方库控件的不良影响 24 | *

25 | * Created by JessYan on 2018/8/28 10:27 26 | * Contact me 27 | * Follow me 28 | * ================================================ 29 | */ 30 | public enum Subunits { 31 | /** 32 | * 不使用副单位 33 | */ 34 | NONE, 35 | /** 36 | * 单位 pt 37 | * 38 | * @see android.util.TypedValue#COMPLEX_UNIT_PT 39 | */ 40 | PT, 41 | /** 42 | * 单位 in 43 | * 44 | * @see android.util.TypedValue#COMPLEX_UNIT_IN 45 | */ 46 | IN, 47 | /** 48 | * 单位 mm 49 | * 50 | * @see android.util.TypedValue#COMPLEX_UNIT_MM 51 | */ 52 | MM 53 | } 54 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/utils/AutoSizeLog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.utils; 17 | 18 | import android.util.Log; 19 | 20 | /** 21 | * ================================================ 22 | * Created by JessYan on 2018/8/8 18:48 23 | * Contact me 24 | * Follow me 25 | * ================================================ 26 | */ 27 | public class AutoSizeLog { 28 | private static final String TAG = "AndroidAutoSize"; 29 | private static boolean debug; 30 | 31 | private AutoSizeLog() { 32 | throw new IllegalStateException("you can't instantiate me!"); 33 | } 34 | 35 | public static boolean isDebug() { 36 | return debug; 37 | } 38 | 39 | public static void setDebug(boolean debug) { 40 | AutoSizeLog.debug = debug; 41 | } 42 | 43 | public static void d(String message) { 44 | if (debug) { 45 | Log.d(TAG, message); 46 | } 47 | } 48 | 49 | public static void w(String message) { 50 | if (debug) { 51 | Log.w(TAG, message); 52 | } 53 | } 54 | 55 | public static void e(String message) { 56 | if (debug) { 57 | Log.e(TAG, message); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/utils/AutoSizeUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.utils; 17 | 18 | import android.annotation.SuppressLint; 19 | import android.content.Context; 20 | import android.util.TypedValue; 21 | import android.app.Application; 22 | 23 | import java.lang.reflect.InvocationTargetException; 24 | 25 | /** 26 | * ================================================ 27 | * AndroidAutoSize 常用工具类 28 | *

29 | * Created by JessYan on 2018/8/25 15:24 30 | * Contact me 31 | * Follow me 32 | * ================================================ 33 | */ 34 | public class AutoSizeUtils { 35 | 36 | private AutoSizeUtils() { 37 | throw new IllegalStateException("you can't instantiate me!"); 38 | } 39 | 40 | public static int dp2px(Context context, float value) { 41 | return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, context.getResources().getDisplayMetrics()) + 0.5f); 42 | } 43 | 44 | public static int sp2px(Context context, float value) { 45 | return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, value, context.getResources().getDisplayMetrics()) + 0.5f); 46 | } 47 | 48 | public static int pt2px(Context context, float value) { 49 | return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PT, value, context.getResources().getDisplayMetrics()) + 0.5f); 50 | } 51 | 52 | public static int in2px(Context context, float value) { 53 | return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_IN, value, context.getResources().getDisplayMetrics()) + 0.5f); 54 | } 55 | 56 | public static int mm2px(Context context, float value) { 57 | return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, value, context.getResources().getDisplayMetrics()) + 0.5f); 58 | } 59 | 60 | public static Application getApplicationByReflect() { 61 | try { 62 | @SuppressLint("PrivateApi") 63 | Class activityThread = Class.forName("android.app.ActivityThread"); 64 | Object thread = activityThread.getMethod("currentActivityThread").invoke(null); 65 | Object app = activityThread.getMethod("getApplication").invoke(thread); 66 | if (app == null) { 67 | throw new NullPointerException("you should init first"); 68 | } 69 | return (Application) app; 70 | } catch (NoSuchMethodException e) { 71 | e.printStackTrace(); 72 | } catch (IllegalAccessException e) { 73 | e.printStackTrace(); 74 | } catch (InvocationTargetException e) { 75 | e.printStackTrace(); 76 | } catch (ClassNotFoundException e) { 77 | e.printStackTrace(); 78 | } 79 | throw new NullPointerException("you should init first"); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/utils/Preconditions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.utils; 17 | 18 | import android.os.Looper; 19 | 20 | /** 21 | * ================================================ 22 | * Created by JessYan on 26/09/2016 13:59 23 | * Contact me 24 | * Follow me 25 | * ================================================ 26 | */ 27 | public final class Preconditions { 28 | 29 | private Preconditions() { 30 | throw new IllegalStateException("you can't instantiate me!"); 31 | } 32 | 33 | public static void checkArgument(boolean expression) { 34 | if (!expression) { 35 | throw new IllegalArgumentException(); 36 | } 37 | } 38 | 39 | public static void checkArgument(boolean expression, Object errorMessage) { 40 | if (!expression) { 41 | throw new IllegalArgumentException(String.valueOf(errorMessage)); 42 | } 43 | } 44 | 45 | public static void checkArgument(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) { 46 | if (!expression) { 47 | throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs)); 48 | } 49 | } 50 | 51 | public static void checkState(boolean expression) { 52 | if (!expression) { 53 | throw new IllegalStateException(); 54 | } 55 | } 56 | 57 | public static void checkState(boolean expression, Object errorMessage) { 58 | if (!expression) { 59 | throw new IllegalStateException(String.valueOf(errorMessage)); 60 | } 61 | } 62 | 63 | public static void checkState(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) { 64 | if (!expression) { 65 | throw new IllegalStateException(format(errorMessageTemplate, errorMessageArgs)); 66 | } 67 | } 68 | 69 | public static T checkNotNull(T reference) { 70 | if (reference == null) { 71 | throw new NullPointerException(); 72 | } else { 73 | return reference; 74 | } 75 | } 76 | 77 | public static T checkNotNull(T reference, Object errorMessage) { 78 | if (reference == null) { 79 | throw new NullPointerException(String.valueOf(errorMessage)); 80 | } else { 81 | return reference; 82 | } 83 | } 84 | 85 | public static T checkNotNull(T reference, String errorMessageTemplate, Object... errorMessageArgs) { 86 | if (reference == null) { 87 | throw new NullPointerException(format(errorMessageTemplate, errorMessageArgs)); 88 | } else { 89 | return reference; 90 | } 91 | } 92 | 93 | public static int checkElementIndex(int index, int size) { 94 | return checkElementIndex(index, size, "index"); 95 | } 96 | 97 | public static int checkElementIndex(int index, int size, String desc) { 98 | if (index >= 0 && index < size) { 99 | return index; 100 | } else { 101 | throw new IndexOutOfBoundsException(badElementIndex(index, size, desc)); 102 | } 103 | } 104 | 105 | /** 106 | * Throws {@link IllegalStateException} if the calling thread is not the application's main 107 | * thread. 108 | * 109 | * @throws IllegalStateException If the calling thread is not the application's main thread. 110 | */ 111 | public static void checkMainThread() { 112 | if (Looper.myLooper() != Looper.getMainLooper()) { 113 | throw new IllegalStateException("Not in applications main thread"); 114 | } 115 | } 116 | 117 | private static String badElementIndex(int index, int size, String desc) { 118 | if (index < 0) { 119 | return format("%s (%s) must not be negative", new Object[]{desc, Integer.valueOf(index)}); 120 | } else if (size < 0) { 121 | throw new IllegalArgumentException((new StringBuilder(26)).append("negative size: ").append(size).toString()); 122 | } else { 123 | return format("%s (%s) must be less than size (%s)", new Object[]{desc, Integer.valueOf(index), Integer.valueOf(size)}); 124 | } 125 | } 126 | 127 | public static int checkPositionIndex(int index, int size) { 128 | return checkPositionIndex(index, size, "index"); 129 | } 130 | 131 | public static int checkPositionIndex(int index, int size, String desc) { 132 | if (index >= 0 && index <= size) { 133 | return index; 134 | } else { 135 | throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc)); 136 | } 137 | } 138 | 139 | private static String badPositionIndex(int index, int size, String desc) { 140 | if (index < 0) { 141 | return format("%s (%s) must not be negative", new Object[]{desc, Integer.valueOf(index)}); 142 | } else if (size < 0) { 143 | throw new IllegalArgumentException((new StringBuilder(26)).append("negative size: ").append(size).toString()); 144 | } else { 145 | return format("%s (%s) must not be greater than size (%s)", new Object[]{desc, Integer.valueOf(index), Integer.valueOf(size)}); 146 | } 147 | } 148 | 149 | public static void checkPositionIndexes(int start, int end, int size) { 150 | if (start < 0 || end < start || end > size) { 151 | throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size)); 152 | } 153 | } 154 | 155 | private static String badPositionIndexes(int start, int end, int size) { 156 | return start >= 0 && start <= size ? (end >= 0 && end <= size ? format("end index (%s) must not be less than start index (%s)", new Object[]{Integer.valueOf(end), Integer.valueOf(start)}) : badPositionIndex(end, size, "end index")) : badPositionIndex(start, size, "start index"); 157 | } 158 | 159 | static String format(String template, Object... args) { 160 | template = String.valueOf(template); 161 | StringBuilder builder = new StringBuilder(template.length() + 16 * args.length); 162 | int templateStart = 0; 163 | 164 | int i; 165 | int placeholderStart; 166 | for (i = 0; i < args.length; templateStart = placeholderStart + 2) { 167 | placeholderStart = template.indexOf("%s", templateStart); 168 | if (placeholderStart == -1) { 169 | break; 170 | } 171 | 172 | builder.append(template.substring(templateStart, placeholderStart)); 173 | builder.append(args[i++]); 174 | } 175 | 176 | builder.append(template.substring(templateStart)); 177 | if (i < args.length) { 178 | builder.append(" ["); 179 | builder.append(args[i++]); 180 | 181 | while (i < args.length) { 182 | builder.append(", "); 183 | builder.append(args[i++]); 184 | } 185 | 186 | builder.append(']'); 187 | } 188 | 189 | return builder.toString(); 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /autosize/src/main/java/me/jessyan/autosize/utils/ScreenUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.utils; 17 | 18 | import android.content.Context; 19 | import android.content.res.Resources; 20 | import android.graphics.Point; 21 | import android.os.Build; 22 | import android.provider.Settings; 23 | import android.util.DisplayMetrics; 24 | import android.view.Display; 25 | import android.view.WindowManager; 26 | 27 | /** 28 | * ================================================ 29 | * Created by JessYan on 26/09/2016 16:59 30 | * Contact me 31 | * Follow me 32 | * ================================================ 33 | */ 34 | public class ScreenUtils { 35 | 36 | private ScreenUtils() { 37 | throw new IllegalStateException("you can't instantiate me!"); 38 | } 39 | 40 | public static int getStatusBarHeight() { 41 | int result = 0; 42 | try { 43 | int resourceId = Resources.getSystem().getIdentifier("status_bar_height", "dimen", "android"); 44 | if (resourceId > 0) { 45 | result = Resources.getSystem().getDimensionPixelSize(resourceId); 46 | } 47 | } catch (Resources.NotFoundException e) { 48 | e.printStackTrace(); 49 | } 50 | return result; 51 | } 52 | 53 | /** 54 | * 获取当前的屏幕尺寸 55 | * 56 | * @param context {@link Context} 57 | * @return 屏幕尺寸 58 | */ 59 | public static int[] getScreenSize(Context context) { 60 | int[] size = new int[2]; 61 | 62 | WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 63 | Display d = w.getDefaultDisplay(); 64 | DisplayMetrics metrics = new DisplayMetrics(); 65 | d.getMetrics(metrics); 66 | 67 | size[0] = metrics.widthPixels; 68 | size[1] = metrics.heightPixels; 69 | return size; 70 | } 71 | 72 | /** 73 | * 获取原始的屏幕尺寸 74 | * 75 | * @param context {@link Context} 76 | * @return 屏幕尺寸 77 | */ 78 | public static int[] getRawScreenSize(Context context) { 79 | int[] size = new int[2]; 80 | 81 | WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 82 | Display d = w.getDefaultDisplay(); 83 | DisplayMetrics metrics = new DisplayMetrics(); 84 | d.getMetrics(metrics); 85 | // since SDK_INT = 1; 86 | int widthPixels = metrics.widthPixels; 87 | int heightPixels = metrics.heightPixels; 88 | 89 | // includes window decorations (statusbar bar/menu bar) 90 | if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17) 91 | try { 92 | widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d); 93 | heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d); 94 | } catch (Exception ignored) { 95 | } 96 | // includes window decorations (statusbar bar/menu bar) 97 | if (Build.VERSION.SDK_INT >= 17) 98 | try { 99 | Point realSize = new Point(); 100 | Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize); 101 | widthPixels = realSize.x; 102 | heightPixels = realSize.y; 103 | } catch (Exception ignored) { 104 | } 105 | size[0] = widthPixels; 106 | size[1] = heightPixels; 107 | return size; 108 | } 109 | 110 | public static int getHeightOfNavigationBar(Context context) { 111 | //如果小米手机开启了全面屏手势隐藏了导航栏则返回 0 112 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { 113 | if (Settings.Global.getInt(context.getContentResolver(), "force_fsg_nav_bar", 0) != 0) { 114 | return 0; 115 | } 116 | } 117 | 118 | int realHeight = getRawScreenSize(context)[1]; 119 | int displayHeight = getScreenSize(context)[1]; 120 | return realHeight - displayHeight; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'} 6 | jcenter() 7 | google() 8 | } 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:3.5.3' 11 | classpath 'com.novoda:bintray-release:0.9.2' 12 | // NOTE: Do not place your application dependencies here; they belong 13 | // in the individual module build.gradle files 14 | } 15 | } 16 | 17 | allprojects { 18 | repositories { 19 | maven{ url 'http://maven.aliyun.com/nexus/content/groups/public/'} 20 | jcenter() 21 | google() 22 | } 23 | } 24 | 25 | task clean(type: Delete) { 26 | delete rootProject.buildDir 27 | } 28 | 29 | ext { 30 | minSdkVersion = 14 31 | targetSdkVersion = 29 32 | compileSdkVersion = 29 33 | buildToolsVersion = "29.0.2" 34 | versionCode = 41 35 | versionName = "1.2.1" 36 | appcompat_v7 = "com.android.support:appcompat-v7:28.0.0" 37 | androidx_appcompat = "androidx.appcompat:appcompat:1.1.0" 38 | } -------------------------------------------------------------------------------- /demo-androidx/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /demo-androidx/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion rootProject.compileSdkVersion 5 | buildToolsVersion rootProject.buildToolsVersion 6 | 7 | defaultConfig { 8 | applicationId "me.jessyan.autosize.demo.androidx" 9 | minSdkVersion rootProject.minSdkVersion 10 | targetSdkVersion rootProject.targetSdkVersion 11 | versionCode rootProject.versionCode 12 | versionName rootProject.versionName 13 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 14 | } 15 | buildTypes { 16 | release { 17 | minifyEnabled false 18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 19 | } 20 | } 21 | } 22 | 23 | dependencies { 24 | // implementation 'me.jessyan:autosize:1.2.1' 25 | implementation project(':autosize') 26 | implementation rootProject.androidx_appcompat 27 | testImplementation 'junit:junit:4.12' 28 | } 29 | -------------------------------------------------------------------------------- /demo-androidx/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /demo-androidx/src/androidTest/java/me/jessyan/autosize/demo/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package me.jessyan.autosize.demo; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("me.jessyan.autosize.demo", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /demo-androidx/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /demo-androidx/src/main/java/me/jessyan/autosize/demo/androidx/BaseApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.demo.androidx; 17 | 18 | import android.app.Activity; 19 | import android.app.Application; 20 | import android.util.DisplayMetrics; 21 | 22 | import java.util.Locale; 23 | 24 | import me.jessyan.autosize.AutoSize; 25 | import me.jessyan.autosize.AutoSizeConfig; 26 | import me.jessyan.autosize.onAdaptListener; 27 | import me.jessyan.autosize.utils.AutoSizeLog; 28 | 29 | /** 30 | * ================================================ 31 | * v0.9.1 发布后新增了副单位,可以在 pt、in、mm 三个冷门单位中选择一个作为副单位,然后在 layout 文件中使用副单位进行布局 32 | * 副单位可以规避修改 {@link DisplayMetrics#density} 所造成的对于其他使用 dp 布局的系统控件或三方库控件的不良影响 33 | * 使用副单位后可直接在 AndroidManifest 中填写设计图上的像素尺寸,不需要再将像素转化为 dp 34 | * 点击查看在布局中的实时预览方式 35 | *

36 | * 本框架核心原理来自于 今日头条官方适配方案 37 | *

38 | * 本框架源码的注释都很详细, 欢迎阅读学习 39 | *

40 | * AndroidAutoSize 会在 APP 启动时自动完成初始化, 如果您想设置自定义参数可以在 {@link Application#onCreate()} 中设置 41 | *

42 | * Created by JessYan on 2018/8/9 17:05 43 | * Contact me 44 | * Follow me 45 | * ================================================ 46 | */ 47 | public class BaseApplication extends Application { 48 | @Override 49 | public void onCreate() { 50 | super.onCreate(); 51 | //当 App 中出现多进程, 并且您需要适配所有的进程, 就需要在 App 初始化时调用 initCompatMultiProcess() 52 | AutoSize.initCompatMultiProcess(this); 53 | 54 | //如果在某些特殊情况下出现 InitProvider 未能正常实例化, 导致 AndroidAutoSize 未能完成初始化 55 | //可以主动调用 AutoSize.checkAndInit(this) 方法, 完成 AndroidAutoSize 的初始化后即可正常使用 56 | // AutoSize.checkAndInit(this); 57 | 58 | // 如何控制 AndroidAutoSize 的初始化,让 AndroidAutoSize 在某些设备上不自动启动?https://github.com/JessYanCoding/AndroidAutoSize/issues/249 59 | 60 | /** 61 | * 以下是 AndroidAutoSize 可以自定义的参数, {@link AutoSizeConfig} 的每个方法的注释都写的很详细 62 | * 使用前请一定记得跳进源码,查看方法的注释, 下面的注释只是简单描述!!! 63 | */ 64 | AutoSizeConfig.getInstance() 65 | 66 | //是否让框架支持自定义 Fragment 的适配参数, 由于这个需求是比较少见的, 所以须要使用者手动开启 67 | //如果没有这个需求建议不开启 68 | .setCustomFragment(true) 69 | 70 | //是否屏蔽系统字体大小对 AndroidAutoSize 的影响, 如果为 true, App 内的字体的大小将不会跟随系统设置中字体大小的改变 71 | //如果为 false, 则会跟随系统设置中字体大小的改变, 默认为 false 72 | // .setExcludeFontScale(true) 73 | 74 | //区别于系统字体大小的放大比例, AndroidAutoSize 允许 APP 内部可以独立于系统字体大小之外,独自拥有全局调节 APP 字体大小的能力 75 | //当然, 在 APP 内您必须使用 sp 来作为字体的单位, 否则此功能无效, 不设置或将此值设为 0 则取消此功能 76 | // .setPrivateFontScale(0.8f) 77 | 78 | //屏幕适配监听器 79 | .setOnAdaptListener(new onAdaptListener() { 80 | @Override 81 | public void onAdaptBefore(Object target, Activity activity) { 82 | //使用以下代码, 可以解决横竖屏切换时的屏幕适配问题 83 | //使用以下代码, 可支持 Android 的分屏或缩放模式, 但前提是在分屏或缩放模式下当用户改变您 App 的窗口大小时 84 | //系统会重绘当前的页面, 经测试在某些机型, 某些情况下系统不会重绘当前页面, ScreenUtils.getScreenSize(activity) 的参数一定要不要传 Application!!! 85 | // AutoSizeConfig.getInstance().setScreenWidth(ScreenUtils.getScreenSize(activity)[0]); 86 | // AutoSizeConfig.getInstance().setScreenHeight(ScreenUtils.getScreenSize(activity)[1]); 87 | AutoSizeLog.d(String.format(Locale.ENGLISH, "%s onAdaptBefore!", target.getClass().getName())); 88 | } 89 | 90 | @Override 91 | public void onAdaptAfter(Object target, Activity activity) { 92 | AutoSizeLog.d(String.format(Locale.ENGLISH, "%s onAdaptAfter!", target.getClass().getName())); 93 | } 94 | }) 95 | 96 | //是否打印 AutoSize 的内部日志, 默认为 true, 如果您不想 AutoSize 打印日志, 则请设置为 false 97 | // .setLog(false) 98 | 99 | //是否使用设备的实际尺寸做适配, 默认为 false, 如果设置为 false, 在以屏幕高度为基准进行适配时 100 | //AutoSize 会将屏幕总高度减去状态栏高度来做适配 101 | //设置为 true 则使用设备的实际屏幕高度, 不会减去状态栏高度 102 | //在全面屏或刘海屏幕设备中, 获取到的屏幕高度可能不包含状态栏高度, 所以在全面屏设备中不需要减去状态栏高度,所以可以 setUseDeviceSize(true) 103 | // .setUseDeviceSize(true) 104 | 105 | //是否全局按照宽度进行等比例适配, 默认为 true, 如果设置为 false, AutoSize 会全局按照高度进行适配 106 | // .setBaseOnWidth(false) 107 | 108 | //设置屏幕适配逻辑策略类, 一般不用设置, 使用框架默认的就好 109 | // .setAutoAdaptStrategy(new AutoAdaptStrategy()) 110 | ; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /demo-androidx/src/main/java/me/jessyan/autosize/demo/androidx/CustomAdaptActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.demo.androidx; 17 | 18 | import android.app.Activity; 19 | import android.content.Intent; 20 | import android.os.Bundle; 21 | import android.view.View; 22 | 23 | import androidx.appcompat.app.AppCompatActivity; 24 | import androidx.fragment.app.Fragment; 25 | import me.jessyan.autosize.internal.CustomAdapt; 26 | 27 | /** 28 | * ================================================ 29 | * 本框架核心原理来自于 今日头条官方适配方案 30 | *

31 | * {@link CustomAdaptActivity} 展示项目内部的 {@link Activity} 自定义适配参数的用法, 需要实现 {@link CustomAdapt} 32 | * 现在 AndroidAutoSize 是全局以屏幕宽度为基准进行适配的, 并且全局的设计图尺寸为 360 * 640 33 | * 这里就展示怎么让 {@link CustomAdaptActivity} 单个页面, 有别于全局设置, 以屏幕高度为基准进行适配, 并且更改设计图尺寸为 iPhone 的设计图尺寸 34 | * 如果这个页面的设计图尺寸有别于其他页面, AndroidAutoSize 允许您改变单个页面的设计图尺寸, {@link #getSizeInDp()} 35 | *

36 | * Created by JessYan on 2018/8/11 11:31 37 | * Contact me 38 | * Follow me 39 | * ================================================ 40 | */ 41 | public class CustomAdaptActivity extends AppCompatActivity implements CustomAdapt { 42 | 43 | @Override 44 | protected void onCreate(Bundle savedInstanceState) { 45 | super.onCreate(savedInstanceState); 46 | setContentView(R.layout.activity_custom_adapt); 47 | } 48 | 49 | /** 50 | * 跳转到 {@link FragmentHost}, 展示项目内部的 {@link Fragment} 自定义适配参数的用法 51 | * 52 | * @param view {@link View} 53 | */ 54 | public void goCustomAdaptFragment(View view) { 55 | startActivity(new Intent(getApplicationContext(), FragmentHost.class)); 56 | } 57 | 58 | /** 59 | * 是否按照宽度进行等比例适配 (为了保证在高宽比不同的屏幕上也能正常适配, 所以只能在宽度和高度之中选择一个作为基准进行适配) 60 | * 61 | * @return {@code true} 为按照宽度进行适配, {@code false} 为按照高度进行适配 62 | */ 63 | @Override 64 | public boolean isBaseOnWidth() { 65 | return false; 66 | } 67 | 68 | /** 69 | * 这里使用 iPhone 的设计图, iPhone 的设计图尺寸为 750px * 1334px, 高换算成 dp 为 667 (1334px / 2 = 667dp) 70 | *

71 | * 返回设计图上的设计尺寸, 单位 dp 72 | * {@link #getSizeInDp} 须配合 {@link #isBaseOnWidth()} 使用, 规则如下: 73 | * 如果 {@link #isBaseOnWidth()} 返回 {@code true}, {@link #getSizeInDp} 则应该返回设计图的总宽度 74 | * 如果 {@link #isBaseOnWidth()} 返回 {@code false}, {@link #getSizeInDp} 则应该返回设计图的总高度 75 | * 如果您不需要自定义设计图上的设计尺寸, 想继续使用在 AndroidManifest 中填写的设计图尺寸, {@link #getSizeInDp} 则返回 {@code 0} 76 | * 77 | * @return 设计图上的设计尺寸, 单位 dp 78 | */ 79 | @Override 80 | public float getSizeInDp() { 81 | return 667; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /demo-androidx/src/main/java/me/jessyan/autosize/demo/androidx/CustomFragment1.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.demo.androidx; 17 | 18 | import android.os.Bundle; 19 | import android.view.Gravity; 20 | import android.view.LayoutInflater; 21 | import android.view.View; 22 | import android.view.ViewGroup; 23 | import android.widget.TextView; 24 | 25 | import androidx.annotation.NonNull; 26 | import androidx.annotation.Nullable; 27 | import androidx.fragment.app.Fragment; 28 | import me.jessyan.autosize.AutoSize; 29 | import me.jessyan.autosize.internal.CustomAdapt; 30 | import me.jessyan.autosize.utils.AutoSizeUtils; 31 | 32 | /** 33 | * ================================================ 34 | * Created by JessYan on 2018/8/25 14:06 35 | * Contact me 36 | * Follow me 37 | * ================================================ 38 | */ 39 | public class CustomFragment1 extends Fragment implements CustomAdapt { 40 | 41 | @Nullable 42 | @Override 43 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 44 | //由于某些原因, 屏幕旋转后 Fragment 的重建, 会导致框架对 Fragment 的自定义适配参数失去效果 45 | //所以如果您的 Fragment 允许屏幕旋转, 则请在 onCreateView 手动调用一次 AutoSize.autoConvertDensity() 46 | //如果您的 Fragment 不允许屏幕旋转, 则可以将下面调用 AutoSize.autoConvertDensity() 的代码删除掉 47 | AutoSize.autoConvertDensity(getActivity(), 1080, true); 48 | return createTextView(inflater, "Fragment-1\nView width = 360dp\nTotal width = 1080dp", 0xffff0000); 49 | } 50 | 51 | @Override 52 | public boolean isBaseOnWidth() { 53 | return true; 54 | } 55 | 56 | @Override 57 | public float getSizeInDp() { 58 | return 1080; 59 | } 60 | 61 | public static View createTextView(LayoutInflater inflater, String content, int backgroundColor) { 62 | TextView view = new TextView(inflater.getContext()); 63 | ViewGroup.LayoutParams layoutParams = 64 | new ViewGroup.LayoutParams((AutoSizeUtils.dp2px(inflater.getContext(), 360)), 65 | ViewGroup.LayoutParams.MATCH_PARENT); 66 | view.setLayoutParams(layoutParams); 67 | view.setText(content); 68 | view.setTextColor(0xffffffff); 69 | view.setGravity(Gravity.CENTER); 70 | view.setTextSize(30); 71 | view.setBackgroundColor(backgroundColor); 72 | return view; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /demo-androidx/src/main/java/me/jessyan/autosize/demo/androidx/CustomFragment2.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.demo.androidx; 17 | 18 | import android.os.Bundle; 19 | import android.view.LayoutInflater; 20 | import android.view.View; 21 | import android.view.ViewGroup; 22 | 23 | import androidx.annotation.NonNull; 24 | import androidx.annotation.Nullable; 25 | import androidx.fragment.app.Fragment; 26 | import me.jessyan.autosize.AutoSize; 27 | import me.jessyan.autosize.internal.CustomAdapt; 28 | 29 | /** 30 | * ================================================ 31 | * Created by JessYan on 2018/8/25 14:06 32 | * Contact me 33 | * Follow me 34 | * ================================================ 35 | */ 36 | public class CustomFragment2 extends Fragment implements CustomAdapt{ 37 | 38 | @Nullable 39 | @Override 40 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 41 | //由于某些原因, 屏幕旋转后 Fragment 的重建, 会导致框架对 Fragment 的自定义适配参数失去效果 42 | //所以如果您的 Fragment 允许屏幕旋转, 则请在 onCreateView 手动调用一次 AutoSize.autoConvertDensity() 43 | //如果您的 Fragment 不允许屏幕旋转, 则可以将下面调用 AutoSize.autoConvertDensity() 的代码删除掉 44 | AutoSize.autoConvertDensity(getActivity(), 720, true); 45 | return CustomFragment1.createTextView(inflater, "Fragment-2\nView width = 360dp\nTotal width = 720dp", 0xff00ff00); 46 | } 47 | 48 | @Override 49 | public boolean isBaseOnWidth() { 50 | return true; 51 | } 52 | 53 | @Override 54 | public float getSizeInDp() { 55 | return 720; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /demo-androidx/src/main/java/me/jessyan/autosize/demo/androidx/CustomFragment3.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.demo.androidx; 17 | 18 | import android.os.Bundle; 19 | import android.view.LayoutInflater; 20 | import android.view.View; 21 | import android.view.ViewGroup; 22 | 23 | import androidx.annotation.NonNull; 24 | import androidx.annotation.Nullable; 25 | import androidx.fragment.app.Fragment; 26 | import me.jessyan.autosize.AutoSize; 27 | import me.jessyan.autosize.internal.CustomAdapt; 28 | 29 | /** 30 | * ================================================ 31 | * Created by JessYan on 2018/8/25 14:06 32 | * Contact me 33 | * Follow me 34 | * ================================================ 35 | */ 36 | public class CustomFragment3 extends Fragment implements CustomAdapt{ 37 | 38 | @Nullable 39 | @Override 40 | public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 41 | //由于某些原因, 屏幕旋转后 Fragment 的重建, 会导致框架对 Fragment 的自定义适配参数失去效果 42 | //所以如果您的 Fragment 允许屏幕旋转, 则请在 onCreateView 手动调用一次 AutoSize.autoConvertDensity() 43 | //如果您的 Fragment 不允许屏幕旋转, 则可以将下面调用 AutoSize.autoConvertDensity() 的代码删除掉 44 | AutoSize.autoConvertDensity(getActivity(), 360, true); 45 | return CustomFragment1.createTextView(inflater, "Fragment-3\nView width = 360dp\nTotal width = 360dp", 0xff0000ff); 46 | } 47 | 48 | @Override 49 | public boolean isBaseOnWidth() { 50 | return true; 51 | } 52 | 53 | @Override 54 | public float getSizeInDp() { 55 | return 360; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /demo-androidx/src/main/java/me/jessyan/autosize/demo/androidx/FragmentHost.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.demo.androidx; 17 | 18 | import android.os.Bundle; 19 | 20 | import androidx.annotation.Nullable; 21 | import androidx.appcompat.app.AppCompatActivity; 22 | import me.jessyan.autosize.internal.CustomAdapt; 23 | 24 | /** 25 | * ================================================ 26 | * Created by JessYan on 2018/8/25 14:39 27 | * Contact me 28 | * Follow me 29 | * ================================================ 30 | */ 31 | public class FragmentHost extends AppCompatActivity implements CustomAdapt { 32 | @Override 33 | protected void onCreate(@Nullable Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | setContentView(R.layout.activity_host); 36 | if (getSupportFragmentManager().findFragmentById(R.id.container1) == null) { 37 | getSupportFragmentManager().beginTransaction().add(R.id.container1, new CustomFragment1()).commit(); 38 | } 39 | if (getSupportFragmentManager().findFragmentById(R.id.container2) == null) { 40 | getSupportFragmentManager().beginTransaction().add(R.id.container2, new CustomFragment2()).commit(); 41 | } 42 | if (getSupportFragmentManager().findFragmentById(R.id.container3) == null) { 43 | getSupportFragmentManager().beginTransaction().add(R.id.container3, new CustomFragment3()).commit(); 44 | } 45 | } 46 | 47 | @Override 48 | public boolean isBaseOnWidth() { 49 | return true; 50 | } 51 | 52 | @Override 53 | public float getSizeInDp() { 54 | return 720; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /demo-androidx/src/main/java/me/jessyan/autosize/demo/androidx/MainActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 JessYan 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package me.jessyan.autosize.demo.androidx; 17 | 18 | import android.app.Activity; 19 | import android.app.Dialog; 20 | import android.app.Fragment; 21 | import android.content.Intent; 22 | import android.os.Bundle; 23 | import android.view.View; 24 | import android.widget.Toast; 25 | 26 | import androidx.appcompat.app.AppCompatActivity; 27 | import me.jessyan.autosize.AutoSizeConfig; 28 | import me.jessyan.autosize.internal.CustomAdapt; 29 | 30 | /** 31 | * ================================================ 32 | * 本框架核心原理来自于 今日头条官方适配方案 33 | * 此方案不光可以适配 {@link Activity}, 这个 {@link Activity} 下的所有 {@link Fragment}、{@link Dialog}、{@link View} 都会自动适配 34 | *

35 | * {@link MainActivity} 是以屏幕宽度为基准进行适配的, 并且使用的是在 AndroidManifest 中填写的全局设计图尺寸 360 * 640 36 | * 不懂什么叫基准的话, 请看 {@link AutoSizeConfig#isBaseOnWidth}) 的注释, AndroidAutoSize 默认全局以屏幕宽度为基准进行适配 37 | * 如果想更改为全局以屏幕高度为基准进行适配, 请在 {@link BaseApplication} 中按注释中更改, 为什么强调全局? 38 | * 因为 AndroidAutoSize 允许每个 {@link Activity} 可以自定义适配参数, 自定义适配参数通过实现 {@link CustomAdapt} 39 | * 如果不自定义适配参数就会使用全局的适配参数, 全局适配参数在 {@link BaseApplication} 中按注释设置 40 | *

41 | * Created by JessYan on 2018/8/9 17:05 42 | * Contact me 43 | * Follow me 44 | * ================================================ 45 | */ 46 | //实现 CancelAdapt 即可取消当前 Activity 的屏幕适配, 并且这个 Activity 下的所有 Fragment 和 View 都会被取消适配 47 | //public class MainActivity extends AppCompatActivity implements CancelAdapt { 48 | public class MainActivity extends AppCompatActivity { 49 | 50 | @Override 51 | protected void onCreate(Bundle savedInstanceState) { 52 | super.onCreate(savedInstanceState); 53 | setContentView(R.layout.activity_main); 54 | } 55 | 56 | /** 57 | * 需要注意的是暂停 AndroidAutoSize 后, AndroidAutoSize 只是停止了对后续还没有启动的 {@link Activity} 进行适配的工作 58 | * 但对已经启动且已经适配的 {@link Activity} 不会有任何影响 59 | * 60 | * @param view {@link View} 61 | */ 62 | public void stop(View view) { 63 | Toast.makeText(getApplicationContext(), "AndroidAutoSize stops working!", Toast.LENGTH_SHORT).show(); 64 | AutoSizeConfig.getInstance().stop(this); 65 | } 66 | 67 | /** 68 | * 需要注意的是重新启动 AndroidAutoSize 后, AndroidAutoSize 只是重新开始了对后续还没有启动的 {@link Activity} 进行适配的工作 69 | * 但对已经启动且在 stop 期间未适配的 {@link Activity} 不会有任何影响 70 | * 71 | * @param view {@link View} 72 | */ 73 | public void restart(View view) { 74 | Toast.makeText(getApplicationContext(), "AndroidAutoSize continues to work", Toast.LENGTH_SHORT).show(); 75 | AutoSizeConfig.getInstance().restart(); 76 | } 77 | 78 | /** 79 | * 跳转到 {@link CustomAdaptActivity}, 展示项目内部的 {@link Activity} 自定义适配参数的用法 80 | * 81 | * @param view {@link View} 82 | */ 83 | public void goCustomAdaptActivity(View view) { 84 | startActivity(new Intent(getApplicationContext(), CustomAdaptActivity.class)); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /demo-androidx/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /demo-androidx/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 11 | 16 | 21 | 26 | 31 | 36 | 41 | 46 | 51 | 56 | 61 | 66 | 71 | 76 | 81 | 86 | 91 | 96 | 101 | 106 | 111 | 116 | 121 | 126 | 131 | 136 | 141 | 146 | 151 | 156 | 161 | 166 | 171 | 172 | -------------------------------------------------------------------------------- /demo-androidx/src/main/res/layout/activity_custom_adapt.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 23 | 24 | 26 | 27 | 32 | 33 |