Giter Site home page Giter Site logo

jessyancoding / androidautosize Goto Github PK

View Code? Open in Web Editor NEW
13.3K 13.3K 1.9K 3.06 MB

🔥 A low-cost Android screen adaptation solution (今日头条屏幕适配方案终极版,一个极低成本的 Android 屏幕适配方案).

License: Apache License 2.0

Java 100.00%
adapterview android arms density mvparms screenadapter

androidautosize's Introduction

Hi

Life is a fucking movie. 😈 😈 😈 😈 😈 😈

人生如戏。

androidautosize's People

Contributors

jessyancoding avatar kalasoo avatar liqvip avatar xxjy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

androidautosize's Issues

添加了不起作用

Environment

  • Autosize Version: v0.7.0
  • Target Android Version: Android 8.0
  • Device Model:小米note3,三星s7 edge
  • Device Resolution:1080px * 1920px
  • Design Size On AndroidManifest: 360dp * 640dp

Bug Description:

添加了不起作用,不同手机打印的日志一样,布局的view宽度是相同的,实际在屏幕上显示的不一样

Log:

qq 20180822204556
qq 20180822205546

Screenshot

qq 20180822204949
qq 20180822204934

显示效果

三星s7 edge
qq 20180822205641
小米note3
_20180822205507

系统弹窗适配问题

您好,我自己使用头条的适配方案的时候发现系统的弹窗适配不对,都超出屏幕了。碰巧看到您的实现,发现也有这问题。请问什么原因?怎么解决?

我引入后运行报错java.lang.NoClassDefFoundError,自己解决了,贡献一下思路。

Environment

  • Autosize Version: v0.9.1
  • Target Android Version: Android 6.0.1
  • Device Model: 网易mumu模拟器
  • Device Resolution: 1080px * 1920px
  • Design Size On AndroidManifest: 1280dp * 720dp

Bug Description:

java.lang.NoClassDefFoundError: me.jessyan.autosize.FragmentLifecycleCallbacksImpl
at me.jessyan.autosize.ActivityLifecycleCallbacksImpl.(ActivityLifecycleCallbacksImpl.java:45)

日志中提示FragmentLifecycleCallbacksImpl这个类找不到,报错,但是我去External Libraries里面能找到引入的Autosize包里面有该类。所以这个问题显得很诡异。
不知道问题出在哪里,只能回到原点,自己新建工程,重新引入,运行,没问题!这就奇怪了。于是我对比gradle里面的依赖及配置信息,由于使用的是Android studio 3.1.4,compileSdkVersion,targetSdkVersion,com.android.support:appcompat-v7:26.1.0等属性版本不一致,版本23可能太低了, 改成使用新建工程后的默认版本26,具体版本可参照新建工程后的版本,问题解决了。

Log:


Screenshot

Related Code:

  

Others:

对于横屏、平板电脑、TV 的适配

可能有人觉得 AndroidAutoSize 对横屏、平板电脑、TV 的适配效果不够好,这里统一解答下

AndroidAutoSize 对于横屏的适配:假如你某个页面的的设计图尺寸是 1920 * 1080,设计图是为竖屏设计的,运行设备的屏幕分辨率也是 1920 * 1080,当在竖屏的时候,一切显示完好,当设备切换为横屏时,屏幕的高或宽就已经互换,这时高为 1080 px,宽为 1920 px,横屏时如果
AndroidAutoSize 是以宽度为基准进行适配,AndroidAutoSize 就会将原本在竖屏时宽为 1080 px 的布局横向拉伸为 1920 px,布局宽度刚好平铺满屏幕,高度也会等比例放大,但布局高度却不会平铺满屏幕,所以会造成竖屏时高为 1920 px 的布局在横屏时纵向的内容显示不全,感觉整个布局被放大很多的视觉效果,如果想让布局在横屏时纵向内容显示完全,高度从 1920 px 缩小至 1080 px,就要让 AndroidAutoSize 以高度为基准进行适配,但是这样又会造成布局的宽度不能平铺满屏幕,导致布局的横向空间上有间隙,那为什么 AndroidAutoSize 只能让高度或宽度中,其中的一个平铺满屏幕,不能让高度和宽度同时平铺满屏幕呢,请看这个 回答,这就是 AndroidAutoSize 在横屏时的适配情况,如果你想布局在横屏时获得更好的适配效果,就只有让设计师针对横屏再出一套设计图 (针对横屏做单独适配这是基础吧,毕竟高和宽都完全不一样)

AndroidAutoSize 对平板电脑、TV 等大屏幕设备的适配:你根据设计师为手机出的设计图,实现为布局后,在手机上的显示是完好的,但显示在平板电脑、TV 等大屏幕设备上感觉变得很大 (如果是横屏,也会出现上面的效果),但我想告诉你这是正常的, AndroidAutoSize 能保证的只是小屏幕显示的内容和大屏幕显示的内容相对于整个屏幕的比例是相等的,因为平板电脑或 TV 的屏幕空间比手机大很多,所以将手机的设计图等比例放大到平板电脑或 TV 上,布局中的控件变大几倍甚至十几倍都是正常的,这就是百分比库的特性,如果你将为平板设计的设计图等比例缩小到手机上,你也会感觉布局在手机上的显示效果偏小,再一次强调这就是百分比库的特性,AndroidAutoSize 能做的只是在不同尺寸的屏幕上以设计图上的比例拉伸或缩放布局,至于这个布局在拉伸或缩放后的效果在这个屏幕上是否美观,不在 AndroidAutoSize 所考虑的范围内

其实不使用任何的百分比屏幕适配库(AutoSizeConfig.getInstance().stop(activity) 停止框架就可以了),直接使用原生的 dp 进行适配,就可以达到在越大的屏幕上显示更多的内容,百分比库是实现不了在越大的屏幕上显示更多的内容的,不管是小到手机还是大到TV,他只会让布局在所有屏幕上都显示相同大小的内容,因为这就是它的特性。

用户都希望在大屏幕设备上让 APP 能显示更多的内容,以更好的利用大屏幕的优势,这都是人之常情,但你想让一套手机设计图就能完美适配平板和TV,就是非常不现实的行为了。

如果你想让平板电脑、TV 等大屏幕设备能比手机屏幕显示更多的内容,并且达到更完美的适配效果,就只有让设计师针对平板电脑、TV 等大屏幕设备再出一套设计图 (这也是基础,毕竟尺寸差别这么大,如果出一套手机的设计图就能让平板电脑、TV 等大屏幕设备达到最好的适配效果,那那些音视频的 App 都不用花费这么多精力专门适配平板了),如果你觉得现在的适配效果还能接受或者想偷懒,那也可以继续使用手机的设计图来适配平板电脑、TV 等大屏幕设备。

小米mix2s设置全面屏手势,不能很好适配。屏幕下方留有空间

  • Autosize Version: 0.7.0
  • Target Android Version: MIUI 9.6 (ANDOIRD 8.0)
  • Device Model:小米 MIX2S
  • Device Resolution: 2160px * 1080px
  • Design Size On AndroidManifest: demo

运行楼主提供demo,打开适配CustomAdaptActivity界面,并不能适配全面屏手势,下面一处留有空白间隙,如果不是全面屏手势,就没有问题。留有空白处刚好是虚拟按键高度。

20180823134359

密度会动态改变,第一次加载正常

我出现了一个问题,密度会动态改变,我不知道是否与本库有关联。图片第一次加载时密度是正确的,滑动图片导致密度缩小了3倍左右。有可能是自身原因,目前解决方案是在全局写了一个变量保存第一次获取到的密度

Screenshot

image
bings

Related Code:

   //    dp 和 px 之间的转换
        fun dp2px(dip: Float): Int {
            val density = context.resources.displayMetrics.density
            return (dip * density + 0.5f).toInt()
        }

切换多语言适配失效

Environment

  • Autosize Version:: v0.7.0
  • Target Android Version:Android 8.0 -
  • Device Model: 一加3
  • Device Resolution: 1920*1080
  • Design Size On AndroidManifest: 360dp * 640dp

Bug Description:

切换多语言,会导致适配失效,字体变小了,布局也变了

Log:切换前后是一样的

isBaseOnWidth = true, designWidthInDp = 360.000000, targetDensity = 3.000000, targetScaledDensity = 3.000000, targetDensityDpi = 480

Screenshot

切换前
qq 20180823111209
qq 20180823112130

切换后
qq 20180823111214
qq 20180823112136

Related Code:

      public static void changeLanguageSetting(Locale locale, Activity activity) {
        changeAppLanguage(activity, locale, true);
        //开始新的activity同时移除之前所有的activity
        PreferenceStore.ofBoolean(CHANGE_LANGUAGE, false).set(true);
        Intent intent = new Intent(activity, MainPageActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        activity.startActivity(intent);
    }

  /**
     * 更改应用语言
     *
     * @param context
     * @param locale      语言地区
     * @param persistence 是否持久化
     */
    public static Context changeAppLanguage(Context context, Locale locale,
                                            boolean persistence) {
        if (locale == null) {
            return context;
        }
        curLocale = locale;
        Log.i(TAG, "changeAppLanguage: local : " + locale.getLanguage());

        if (persistence) {
            saveLanguageSetting(context, locale);
        }
        CommonCountryManager.ins().changeCommonCountryLanguage(context, locale);

        Resources resources = context.getResources();
        DisplayMetrics metrics = resources.getDisplayMetrics();
        Configuration configuration = resources.getConfiguration();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            configuration.setLocale(locale);
        } else {
            configuration.locale = locale;
        }
        context = context.createConfigurationContext(configuration);
        resources.updateConfiguration(configuration, metrics);
        return context;

    }

Others:

解锁屏幕旋转后 fg中的item显示异常

型号:nexus 6P
log:
designWidthInDp = 0, designHeightInDp = 768, screenWidth = 2560, screenHeight = 1440
initDensity = 3.5, initScaledDensity = 3.5
HomeActivity Info: isBaseOnWidth = false, designHeightInDp = 768.000000, targetDensity = 1.765625, targetScaledDensity = 1.765625, targetDensityDpi = 282
解锁-屏幕旋转后
initScaledDensity = 3.5 on ConfigurationChanged
initScaledDensity = 3.5 on ConfigurationChanged
fg中recycleview的item就有异常了 和刚进来的不一致。

后来 我在锁屏的时候调用了 stop 在开屏的时候加上 restart发现的log是这样的
HomeActivity Info: isBaseOnWidth = false, designHeightInDp = 768.000000, targetDensity = 3.333333, targetScaledDensity = 3.333333, targetDensityDpi = 533
屏幕旋转后 尺寸不同了 怎么修复呢

基于宽没有适配成功,日志没有适配成功的提示。

Environment

  • Autosize Version: v0.7.0
  • Target Android Version: Android 8.0
  • Device Model: 华为Mate9
  • Device Resolution: 1080px * 1920px
  • Design Size On AndroidManifest: 360dp * 640dp

Bug Description:

现在是基于宽适配,但是没有达到预期效果,日志好像没有显示适配成功的字眼。

Log:

qq20180823-170940 2x

qq20180823-170902 2x

通过默认配置项目适配失败

Environment

  • Autosize Version: 0.8.0
  • Target Android Version: API28
  • Device Model: Nexus 5x
  • Device Resolution: 750*1334
  • Design Size On AndroidManifest: 750*1334

Bug Description:

适配失败,看日志像是1比1输出,但这个跑出来的效果差很远

Log:

08-27 08:10:28.119 4224-4224/com.zhixiang.balancewallet D/AndroidAutoSize: designWidthInDp = 750, designHeightInDp = 1334, screenWidth = 750, screenHeight = 1334
08-27 08:10:28.120 4224-4224/com.zhixiang.balancewallet D/AndroidAutoSize: initDensity = 2.0, initScaledDensity = 2.0
08-27 08:10:28.214 4224-4224/com.zhixiang.balancewallet D/AndroidAutoSize: com.zhixiang.balancewallet.ui.MainActivity used the global configuration.
08-27 08:10:28.216 4224-4224/com.zhixiang.balancewallet D/AndroidAutoSize: The com.zhixiang.balancewallet.ui.MainActivity has been adapted! 
    MainActivity Info: isBaseOnWidth = true, designWidthInDp = 750.000000, targetDensity = 1.000000, targetScaledDensity = 1.000000, targetDensityDpi = 160

Screenshot

layout文件预览效果
1535357836 1
模拟器跑起来的效果
1535357854 1

Related Code:

Others:

配置只是配置了AndroidManifest文件而已,View写的是DP单位

状态栏和标题栏中间有个间隔

Environment

  • Autosize Version:
  • Target Android Version:
  • Device Model:
  • Device Resolution:
  • Design Size On AndroidManifest:

Bug Description:

Log:



Screenshot

Related Code:

Others:

好像适配之后有些出入

Environment

  • Autosize Version: v0.7.0
  • Target Android Version: targetSdkVersion : 27
  • Device Model: HuaWei & Samsung
  • Device Resolution: 720-1440 & 1440-2560
  • Design Size On AndroidManifest: 375dp* 667dp

Bug Description:

Log:

HuaWei
08-22 16:31:45.598 D/AndroidAutoSize: designWidthInDp = 375, designHeightInDp = 667, screenWidth = 720, screenHeight = 1440
08-22 16:31:45.599 D/AndroidAutoSize: initDensity = 2.0, initScaledDensity = 2.0

Samsung
08-22 16:30:50.367 D/AndroidAutoSize: designWidthInDp = 375, designHeightInDp = 667, screenWidth = 1440, screenHeight = 2560
08-22 16:30:50.368 D/AndroidAutoSize: initDensity = 4.0, initScaledDensity = 4.0

Related Code:

  <meta-data
            android:name="design_width_in_dp"
            android:value="375" />
        <meta-data
            android:name="design_height_in_dp"
            android:value="667" />

Others:

只填写了清单文件的meta value ,最终出来的效果好像还是有点差别, 截图右边是华为分辨率小的,布局底部空出了一大块

默认横屏显示,在关闭屏幕,再解锁进入或者回到桌面再次进入时,popupwindow和dialogfragment会出现适配失效。

Environment

  • Autosize Version: v0.9.1
  • Target Android Version: Android 8.0
  • Device Model: 华为荣耀8
  • Device Resolution: 1080px * 1920px
  • Design Size On AndroidManifest: 584dp * 830dp

Bug Description:

项目默认是横屏显示的,本来适配是正常的,但是在锁屏解锁后或者切到桌面再回到app会出现popupwindow和dialog适配失效。

Log:

 D/AndroidAutoSize: designWidthInDp = 584, designHeightInDp = 830, screenWidth = 1920, screenHeight = 1080
 D/AndroidAutoSize: initDensity = 3.0, initScaledDensity = 3.0
 D/AndroidAutoSize: initScaledDensity = 3.0 on ConfigurationChanged
 D/AndroidAutoSize: cn.pluss.yunlan.paddiancan.activity.LoginActivity implemented by me.jessyan.autosize.internal.CustomAdapt!
 D/AndroidAutoSize: The cn.pluss.yunlan.paddiancan.activity.LoginActivity has been adapted! 
    LoginActivity Info: isBaseOnWidth = false, designHeightInDp = 830.000000, targetDensity = 1.214458, targetScaledDensity = 1.214458, targetDensityDpi = 194, targetXdpi = 1.214458
 D/AndroidAutoSize: cn.pluss.yunlan.paddiancan.activity.MainActivity implemented by me.jessyan.autosize.internal.CustomAdapt!
 D/AndroidAutoSize: The cn.pluss.yunlan.paddiancan.activity.MainActivity has been adapted! 
    MainActivity Info: isBaseOnWidth = false, designHeightInDp = 830.000000, targetDensity = 1.214458, targetScaledDensity = 1.214458, targetDensityDpi = 194, targetXdpi = 1.214458
 D/AndroidAutoSize: initScaledDensity = 3.0 on ConfigurationChanged
 D/AndroidAutoSize: initScaledDensity = 3.0 on ConfigurationChanged

Screenshot

正常的效果
qq 20180830151433
非正常效果
qq 20180830151425

Related Code:

Others:

DialogFragment也会出现这个问题,图就没截了。

状态栏问题

Environment

  • Autosize Version: v0.8.0
  • Target Android Version: Android 4.4.4
  • Device Model: Galaxy E7
  • Device Resolution: 720*1280
  • Design Size On AndroidManifest: 375*667

Bug Description:

设计给的图片是750px 1334px 然后我在AndroidManifest设置的是375667
发现状态栏和标题栏之间有点空隙。暂时只测了红米note5 和 金立S9L 没问题

Log:

d3d9924b-b40d-42c3-9245-76c9a2e606a9

Screenshot

screenshot_2018-08-28-17-42-02

Related Code:

获取状态栏高度的代码

   public static int getStatusBarHeight(Context context) {
        int result = 0;
        int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }

Others:

  还有个问题就是,字体也可以用px吗 ?

透明状态栏高度适配问题

Environment

  • Autosize Version: 0.7.0
  • Target Android Version: 5.0
  • Device Model: simulator
  • Device Resolution: 1440*2560
  • Design Size On AndroidManifest: 360dp * 640dp -->

我自定义了一个titlebar,并且设置为全屏模式,正常情况下我会获取状态栏高度(除刘海屏外一般为25dp左右),然后设置titlebar的topPadding为状态栏高度以实现透明状态栏.
问题出在使用该框架后25dp会被放大,但是手机的状态栏还是25dp,导致titlebar上面padding的空间会变大,该如何解决?

_20180823174603

Toast弹出有问题

坚果Pro2手机的toast弹出,我原本是只显示一句:模块不存在,请联系管理员,但是弹出Toast的时候有时候toast的弹出框就会全屏占满,然后也不显示文字,实际的截图已发送到邮箱,希望能看一下

改变单个页面的设计图尺寸

Environment

  • Autosize Version: v0.7.0
  • Target Android Version:
  • Device Model: Nexus 4
  • Device Resolution:
  • Design Size On AndroidManifest:

Bug Description:

Log:



Screenshot

Related Code:

  public class CustomAdaptActivity extends AppCompatActivity implements CustomAdapt {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_custom_adapt);
    }

    /**
     * 是否按照宽度进行等比例适配 (为了保证在高宽比不同的屏幕上也能正常适配, 所以只能在宽度和高度之中选一个作为基准进行适配)
     *
     * @return {@code true} 为按照宽度适配, {@code false} 为按照高度适配
     */
    @Override
    public boolean isBaseOnWidth() {
        return true;
    }

    /**
     * 这里使用 IPhone 的设计图, IPhone 的设计图尺寸为 750px * 1334px, 高换算成 dp 为 667 (1334px / 2 = 667dp)
     * <p>
     * 返回设计图上的设计尺寸, 单位 dp
     * {@link #getSizeInDp} 须配合 {@link #isBaseOnWidth()} 使用, 规则如下:
     * 如果 {@link #isBaseOnWidth()} 返回 {@code true}, {@link #getSizeInDp} 则应该返回设计图的总宽度
     * 如果 {@link #isBaseOnWidth()} 返回 {@code false}, {@link #getSizeInDp} 则应该返回设计图的总高度
     * 如果您不需要自定义设计图上的设计尺寸, 想继续使用在 AndroidManifest 中填写的设计图尺寸, {@link #getSizeInDp} 则返回 {@code 0}
     *
     * @return 设计图上的设计尺寸, 单位 dp
     */
    @Override
    public float getSizeInDp() {
        return 375;
    }
}

为什么这种写法按照高度适配的时候是正常的,按照宽度适配的时候就出现问题了呢

Others:

红米5plus适配问题

我的红米5plus,在manifest中设置了基准宽是375dp。基准高是667dp,然后在页面中view的高度设置为667dp,并没有充满页面,底部空余了非常大的空间,感
screenshot_2018-08-22-10-48-16-034_com hr autosizeapp
tim 20180822105441

觉没有适配

JessYan: 今日头条屏幕适配方案常见问题汇总,提问前必看!

在这里陈列的内容是 AndroidAutoSize 框架和 今日头条屏幕适配方案 的常见 Issues 以及解决方案,如果在这里没找到您需要的答案,不妨前往 历史 Issues 碰碰运气

这里会持续更新 今日头条屏幕适配方案 的相关问题以及解决方案,如果您发现有什么重要的与 今日头条屏幕适配方案 相关的已知或未知的问题在这里未收录,都可以通过留言或者新增 Issues 的方式告知我,并不仅限于 AndroidAutoSize 框架的问题,不管您是不是使用 AndroidAutoSize 框架,我们都可以共同出力,让 今日头条屏幕适配方案 更完善、更稳定!

+ 如果你想用好 AndroidAutoSize,少出问题,请认真看完下面的所有文字,不要嫌字数长,拒绝做伸手党!!!


Tips: 今日头条适配方案的原理来源于修改 DisplayMetrics#density,因为 DisplayMetrics#density 是全局的,所以只要 DisplayMetrics#density 一经修改,项目中的所有页面、所有控件都可以奏效,包括三方库控件和系统控件,这就是今日头条屏幕适配方案天然拥有优于其他屏幕适配方案的低成本和低侵入性

但 DisplayMetrics#density 是公有的,谁都有权限修改,AndroidAutoSize 可以把 DisplayMetrics#density 修改成一个可以完成屏幕适配的值,其他三方库、Android 系统、以及项目成员就可以把 DisplayMetrics#density 修改或恢复成另一个值,这都将导致屏幕适配的失效,特别是在某些定制系统上,因为这个定制系统做的某些特殊操作都是未知的 (但 AndroidAutoSize 开源这么久,大多数系统都是很稳定的)

但这个问题 AndroidAutoSize 却无能为力,因为 DisplayMetrics#density 是公有的,AndroidAutoSize 只不过是修改 DisplayMetrics#density 中的一员,系统并没有赋予 AndroidAutoSize 可以锁死 DisplayMetrics#density 为某一特定值的权限,而只要其他代码拥有修改 DisplayMetrics#density 的权限,就有不稳定性的产生

所以该问题目前唯一的解决方案就是确保在页面显示到屏幕上的 0.0000000000000000000000000001 秒之前,将 DisplayMetrics#density 修改为期望的值,哪怕页面显示完的后一秒,DisplayMetrics#density 又被修改为其他值,只要这个页面不重建,就不会影响已经显示了的页面,也就是下面的第一个解决方案

+ 以下内容是大部分 issues 出现的核心原因,本框架上手容易,但是要想真正的驾驭,需要熟悉其中的原理!


由于 DisplayMetrics#density 在整个 Application 中是公有并且唯一的,所以并不存在在每一个 Activity 或者 Fragment 中都拥有一个独立的 DisplayMetrics#density,框架之所以能实现每个 Activity 或 Fragment 都可以拥有不同的设计图尺寸,是因为框架自动在每个 Activity 或 Fragment 显示 UI 之前将 DisplayMetrics#density 更改为了它期望的正确值,但是框架并不知道项目中的每个 UI 需要显示或更新到屏幕上的正确时机,只是默认在 setContentView() 之前修改了 DisplayMetrics#density,但在实际开发中,业务何其复杂,有些时候 UI 的显示或更新并不只局限于 setContentView(),比如说在某些业务中会出现一些自定义事件触发自定义 View 进行 requestLayout() 、invalidate() ,或者 RecyclerView 在某些时机需要再次更新 Item 中的内容,但要注意的是,在所有会影响 UI 显示的方法之前都应该保证 DisplayMetrics#density 切换到正确的值,如果框架在你的自定义事件中并未在 UI 显示或更新前将 DisplayMetrics#density 设置为期望的值,就会出现屏幕适配异常的问题,请你辅助框架在 UI 显示或更新之前调用 AutoSize 中的方法,将 DisplayMetrics#density 更改为期望的值。

但如果你对框架原理不是非常熟悉,请不要频繁的更改 DisplayMetrics#density(更改设计图尺寸,以及横竖屏切换都会导致 DisplayMetrics#density 的更改),如果又不懂原理,又喜欢更改 DisplayMetrics#density,那就有一定概率出现你们经常在 issues 中提到的一些屏幕适配失效或者异常的问题,这有很大概率是因为你们自己不懂原理又瞎鸡巴乱搞导致的!出现这个问题的原因就是因为更改 DisplayMetrics#density 后导致期望的 DisplayMetrics#density 与实际的 DisplayMetrics#density 不一致,什么叫懂原理?请把 *年你的屏幕适配方式该升级了! 系列文章都看一遍,再认真看下 AndroidAutoSize 中核心类的源码,别问我核心类是哪些,问就是全部!

一般情况下,下面的 万能解决方案 就能解决大部分的问题,因为在每个与 UI 相关的方法执行时,都会调用 getResources() 方法, 但这个解决方案只能保证一个 Activity 只存在一个设计图尺寸,如果你的一个 Activity 出现了多个设计图尺寸,比如说嵌入了系统 View、第三方 View (系统 View 或第三方 View 的设计图尺寸有很大概率和你项目的设计图尺寸不一致)或者不同设计图尺寸的 Fragment,那这个 万能解决方案 也不能解决所有问题。

  • 万能解决方案,看这里!!! 这里要感谢 Blankj 老师提供的解决方案,在任何情况下本来适配正常的布局突然出现适配失效,适配异常等问题,只要重写 Activity 的 getResources() 方法即可,如果是 Dialog、PopupWindow 等控件出现适配失效或适配异常,同样在每次 show() 之前调用 AutoSize#autoConvertDensity() 即可
    @Override
    public Resources getResources() {
        //需要升级到 v1.1.2 及以上版本才能使用 AutoSizeCompat
        AutoSizeCompat.autoConvertDensityOfGlobal(super.getResources());//如果没有自定义需求用这个方法
        AutoSizeCompat.autoConvertDensity(super.getResources(), 667, false);//如果有自定义需求就用这个方法
        return super.getResources();
    }
  • 新的解决方案,当 getResources() 失效时可以试试,重写 父布局 的 generateLayoutParams(AttributeSet) 方法,具体内容请看 这里
@Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        AutoSizeCompat.autoConvertDensityOfGlobal(getResources());//如果没有自定义需求用这个方法
        AutoSizeCompat.autoConvertDensity(getResources(), 667, false);//如果有自定义需求就用这个方法
        return super.generateLayoutParams(attrs);
    }

  • 如果想让 AndroidAutoSize 适配多个进程的页面,请在 App 初始化时调用 AutoSize#initCompatMultiProcess(Context)AutoSize#checkAndInit(Application),像 这样(有些插件化框架可能会默认开启多进程)

  • 使用代码布局或者创建自定义控件时,在工具类 AutoSizeUtils 中,使用对应的方法,将其他单位转换为 px,作为控件尺寸,即可完成屏幕适配

  • 如果不想让 App 内的字体大小跟随系统设置中字体大小的改变,请调用 AutoSizeConfig.getInstance().setExcludeFontScale(true); 即可

  • 如果想适配 Bitmap,需要在创建 Bitmap 时指定修改后的 DisplayMetrics
    Bitmap bitmap = Bitmap.createBitmap(activity.getResources().getDisplayMetrics(),width,height,config);

WindowManager中获取DisplayMetrics问题

WindowManager windowManager = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
这样获取到的metrics中的density,densityDpi,scaledDensity,是否适配后的?
如果不是,是否可以考虑保存了原始density,densityDpi,scaledDensity后,hook直接修改
小弟入行时间不长,勿喷!只是提出自己的一些想法!

导入包后 报错 Class

Environment

  • Autosize Version: 0.9.1
  • Target Android Version: 22
  • Device Model: 联想pad
  • Device Resolution: 1080*1920
  • Design Size On AndroidManifest:

Bug Description:

Log:

java.lang.NoClassDefFoundError: me.jessyan.autosize.FragmentLifecycleCallbacksImpl
        at me.jessyan.autosize.ActivityLifecycleCallbacksImpl.<init>(ActivityLifecycleCallbacksImpl.java:45)
        at me.jessyan.autosize.AutoSizeConfig.init(AutoSizeConfig.java:206)
        at me.jessyan.autosize.AutoSizeConfig.init(AutoSizeConfig.java:146)
        at me.jessyan.autosize.InitProvider.onCreate(InitProvider.java:37)
        at android.content.ContentProvider.attachInfo(ContentProvider.java:1801)
        at android.content.ContentProvider.attachInfo(ContentProvider.java:1776)
        at android.app.ActivityThread.installProvider(ActivityThread.java:5427)
        at android.app.ActivityThread.installContentProviders(ActivityThread.java:5000)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4940)
        at android.app.ActivityThread.-wrap1(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1549)
        at android.os.Handler.dispatchMessage(Handler.java:111)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5728)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)

Screenshot

Related Code:

Others:

如果布局中有webview,这种自动适配会失效

我最近遇到的问题,
以下的布局,没有webview时候,适配是ok的,但是如果有webview的化,这种是适配就失效了
不知楼主有没有好的方案

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <WebView
        android:id="@+id/webView"
        android:layout_width="180dp"
        android:layout_height="180dp"
        android:background="#FF0000" />

    <View
        android:layout_width="180dp"
        android:layout_height="180dp"
        android:background="#00FF00" />
</LinearLayout>

偶发崩溃:Please call the AutoSizeConfig#init() first

我也遇到过类似的问题,报错日志:Please call the AutoSizeConfig#init() first
崩溃场景:华为,小米等多部手机没问题,后来公司同事用乐视手机就出现这个崩溃
解决办法:注释掉setAutoAdaptStrategy(new AutoAdaptStrategy())方法就不会崩溃了
查看代码:

//第一步:查看源码有两个地方有这个文字提示
Preconditions.checkNotNull(mApplication, "Please call the AutoSizeConfig#init() first");
Preconditions.checkNotNull(mActivityLifecycleCallbacks, "Please call the AutoSizeConfig#init() first");

//第二步:再进去看代码如下所示
//可知传进来的reference为null空值导致出现问题
    public static <T> T checkNotNull(T reference, Object errorMessage) {
        if (reference == null) {
            throw new NullPointerException(String.valueOf(errorMessage));
        } else {
            return reference;
        }
    }

//第三步:查看什么时候创建mApplication和mActivityLifecycleCallbacks对象
//mActivityLifecycleCallbacks对象是在AutoSizeConfig类中的init方法中创建的,第206行
//mApplication对象实在AutoSizeConfig类中init方法中赋值的,第171行
//而init初始化的操作又是在InitProvider类中的onCreate方法中初始化的,(Application) getContext().getApplicationContext()获取全局application会不会出现问题呢?而这个需要的application上下文能否让开发者传递进来呢?

    @Override
    public boolean onCreate() {
        AutoSizeConfig.getInstance()
                .setLog(true)
                .init((Application) getContext().getApplicationContext())
                .setUseDeviceSize(false);
        return true;
    }

出现bug原因分析
还不清楚,很奇怪,希望得到大神解答

崩溃日志信息

java.lang.RuntimeException: Unable to create application com.paidian.hwmc.base.SophixStubApplication: java.lang.NullPointerException: Please call the AutoSizeConfig#init() first
                                                     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5210)
                                                     at android.app.ActivityThread.-wrap3(ActivityThread.java)
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1659)
                                                     at android.os.Handler.dispatchMessage(Handler.java:111)
                                                     at android.os.Looper.loop(Looper.java:207)
                                                     at android.app.ActivityThread.main(ActivityThread.java:5981)
                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749)
                                                  Caused by: java.lang.NullPointerException: Please call the AutoSizeConfig#init() first
                                                     at me.jessyan.autosize.utils.Preconditions.checkNotNull(Preconditions.java:77)
                                                     at me.jessyan.autosize.AutoSizeConfig.setAutoAdaptStrategy(AutoSizeConfig.java:247)
                                                     at com.paidian.hwmc.base.BaseApplication.initAutoSizeConfig(BaseApplication.java:385)
                                                     at com.paidian.hwmc.base.BaseApplication.onCreate(BaseApplication.java:133)
                                                     at com.taobao.sophix.a.c.b(Sophix:722)
                                                     at com.taobao.sophix.a.e.a(Sophix:177)
                                                     at com.taobao.sophix.SophixApplication.onCreate(Sophix:17)
                                                     at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1018)
                                                     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5207)
                                                     at android.app.ActivityThread.-wrap3(ActivityThread.java) 
                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1659) 
                                                     at android.os.Handler.dispatchMessage(Handler.java:111) 
                                                     at android.os.Looper.loop(Looper.java:207) 
                                                     at android.app.ActivityThread.main(ActivityThread.java:5981) 
                                                     at java.lang.reflect.Method.invoke(Native Method) 
                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888) 
                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:749) 

android 9.0问题

android 9.0限制私有api的访问,这个库里面有反射,会不会有影响?

适配小米8及屏幕翻转

Environment

  • Autosize Version: v0.7.0
  • Target Android Version:Android 8.0
  • Device Model: 小米8
  • Device Resolution: 2248x1080像素
  • Design Size On AndroidManifest: 365 655

Bug Description:

1、适配是下方有一小块空白
2、当屏幕翻转的时候,适配就不成功了

Log:

Screenshot

autosize1
screenshot_2018-08-23-09-37-13-207_com jzk common

Related Code:

Others:

.9图片拉伸变形

  • Autosize Version:v0.9.1
  • Target Android Version: Android 8.1
  • Device Model:诺基亚X6
  • Device Resolution: 1080px * 1920px
  • Design Size On AndroidManifest: 360dp * 640dp

.9图片拉伸变形,没有按照制定好的拉伸范围进行拉伸。当去掉AndroidAutoSize后,.9图片就可以正常按照制定的拉伸范围拉伸。

高度和宽度一维适配的讨论

我们公司车载项目我采用的是适配:
https://github.com/yatoooon/AndroidScreenAdaptation

private float calculateValue(float value) {
    if ("px".equals(unit)) {
        return value * ((float) actualWidth / (float) designWidth);
    } else if ("dp".equals(unit)) {
        int dip = dp2pxUtils.px2dip(actualDensity, value);
        value = ((float) designDpi / 160) * dip;
        return value * ((float) actualWidth / (float) designWidth);

    }
    return 0;
}

原本设计以宽度作为标准进行适配,后面发现一个问题:byd车载的屏幕是:1000x1920 ; 按照标准图(宽高640x360(16:9) ),1920/640 = 3; 结果实际高度1000 < 1080 ;导致底部view被遮挡。

后面,我修改了该方法:

 /**
 * Description: 标准宽高640x360(16:9) density = 1.0 dpi = 160
 * 1. 高度低于设计高度,以高度作标准缩放;
 * 2. 高度高于设计高度,但是高度:宽度 < 9:16,以高度作标准缩放;
 * 3. 其余以宽度作标准缩放;
 * @param
 * @return
 */
public float calculateValue(float value) {
    if ("px".equals(unit)) {
          return value * ((float) actualWidth / (float) designWidth);
      } else if ("dp".equals(unit)) {
        int dip = dp2pxUtils.px2dip(actualDensity, value);
         value = ((float) designDpi / 160) * dip;
         if (actualHeight < designHeight || actualWidth * designHeight / designWidth > actualHeight) {
            return value * ((float) actualHeight / (float) designHeight);
        }
        return value * ((float) actualWidth / (float) designWidth);
    }
    return 0;
}

我提的问题是:
头条的方案,本质也是缩放,也会存在这个问题?不知你同意否?

Please call the AutoSizeConfig#init() first

Environment

  • Autosize Version:
  • Target Android Version:
  • Device Model:
  • Device Resolution:
  • Design Size On AndroidManifest:

Bug Description:

Log:

  java.lang.RuntimeException: Unable to create application com.crest.crest_parent.application.MyApplication: java.lang.NullPointerException: Please call the AutoSizeConfig#init() first
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4710)
        at android.app.ActivityThread.-wrap1(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:148)
        at android.app.ActivityThread.main(ActivityThread.java:5417)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
     Caused by: java.lang.NullPointerException: Please call the AutoSizeConfig#init() first
        at me.jessyan.autosize.utils.Preconditions.checkNotNull(Preconditions.java:77)
        at me.jessyan.autosize.AutoSizeConfig.setAutoAdaptStrategy(AutoSizeConfig.java:247)
        at com.crest.crest_parent.application.MyApplication.initAutoSizeConfig(MyApplication.java:179)
        at com.crest.crest_parent.application.MyApplication.onCreate(MyApplication.java:70)
        at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1013)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4707)
        at android.app.ActivityThread.-wrap1(ActivityThread.java) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405) 
        at android.os.Handler.dispatchMessage(Handler.java:102) 
        at android.os.Looper.loop(Looper.java:148) 
        at android.app.ActivityThread.main(ActivityThread.java:5417) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Screenshot

Related Code:

Others:

在模拟器上运行,有底部导航栏的情况,适配的时候会有一条白底

Environment

  • Autosize Version: v0.8.0
  • Target Android Version: Android 9.0
  • Device Model: Pixel XL
  • Device Resolution: 1440px * 2560px
  • Design Size On AndroidManifest: 360dp * 640dp

Bug Description:

在模拟器上运行,有底部导航栏的话,适配的时候会有一条白底,用命令隐藏底部导航栏 adb shell settings put global policy_control immersive.navigation=* 就没有白底了。有人在真机测试中遇到类似的情况吗?

Log:

SettingActivity Info: isBaseOnWidth = true, designWidthInDp = 360.000000, targetDensity = 4.000000, targetScaledDensity = 4.000000, targetDensityDpi = 640

Screenshot

screenshot_1535510571

Related Code:

Others:

在模拟器上运行,有底部导航栏的情况,适配的时候会有一条白底

Environment

  • Autosize Version: v0.8.0
  • Target Android Version: Android 9.0
  • Device Model: Pixel XL
  • Device Resolution: 1440px * 2560px
  • Design Size On AndroidManifest: 360dp * 640dp

Bug Description:

在模拟器上运行,有底部导航栏的话,适配的时候会有一条白底,用命令隐藏底部导航栏 adb shell settings put global policy_control immersive.navigation=* 就没有白底了。有人在真机测试中遇到类似的情况吗?

Log:

    SettingActivity Info: isBaseOnWidth = true, designWidthInDp = 360.000000, targetDensity = 4.000000, targetScaledDensity = 4.000000, targetDensityDpi = 640

Screenshot

screenshot_1535510571

Related Code:

Others:

和Tinker热更新有冲突

Environment

  • Autosize Version: 0.9.1
  • Target Android Version: Android 8.0
  • Device Model: Samsung S9+
  • Device Resolution: 1440px * 2960px
  • Design Size On AndroidManifest: 360dp * 640dp
  • Tinker Version: 1.9.2

Bug Description:

Log:

09-04 15:04:36.299 7450-7450/xx.xx D/AndroidAutoSize: designWidthInDp = 0, designHeightInDp = 0, screenWidth = 1440, screenHeight = 2960
09-04 15:04:36.300 7450-7450/xx.xx D/AndroidAutoSize: initDensity = 3.5, initScaledDensity = 2.8


Screenshot

image

这是全部日志,可以看到没有执行DefaultAutoAdaptStrategy中的方法打印出相应的log
image
这是AutoSizeConfig中获取到的appcation的相关信息

Related Code:

Others:

整合了tinker(DefaultLifeCycle注解的方式)之后就不起作用了,DefaultAutoAdaptStrategy中的applyAdapt都不会执行。适配失败

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.