美文网首页
关于AutoSize Activity横竖屏布局错乱问题解决

关于AutoSize Activity横竖屏布局错乱问题解决

作者: 戎码虫 | 来源:发表于2021-09-09 21:42 被阅读0次

问题

最近开发的时候发现Activity横屏之后,布局发生错乱,找了好久没有问题,研究AutoSize看出了一点问题。

分析

我们从源码的角度查看一下问题

AutoSize初始化注册横竖屏监听,每次横竖屏都会回调该监听
AutoSizeConfig#init(final Application application, boolean isBaseOnWidth, AutoAdaptStrategy strategy)

 AutoSizeConfig init(final Application application, boolean isBaseOnWidth, AutoAdaptStrategy strategy) {
    ···
        application.registerComponentCallbacks(new ComponentCallbacks() {
            @Override
            public void onConfigurationChanged(Configuration newConfig) {
                if (newConfig != null) {
                    if (newConfig.fontScale > 0) {
                        mInitScaledDensity =
                                Resources.getSystem().getDisplayMetrics().scaledDensity;
                        AutoSizeLog.d("initScaledDensity = " + mInitScaledDensity + " on ConfigurationChanged");
                    }
                    isVertical = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT;
                    int[] screenSize = ScreenUtils.getScreenSize(application);
                    mScreenWidth = screenSize[0];
                    mScreenHeight = screenSize[1];
                }
            }

            @Override
            public void onLowMemory() {

            }
        });
    }

当每次进入Activity的时候都会根据AutoSizeConfig初始化设置的参考值进行初始化 activity.getResources().getDisplayMetrics();通过setDensity()、
setScreenSizeDp()重新赋值。

AutoSize#autoConvertDensity(Activity activity, float sizeInDp, boolean isBaseOnWidth)

  public static void autoConvertDensity(Activity activity, float sizeInDp, boolean isBaseOnWidth) {
       ···
        setDensity(activity, targetDensity, targetDensityDpi, targetScaledDensity, targetXdpi);
        setScreenSizeDp(activity, targetScreenWidthDp, targetScreenHeightDp);

        AutoSizeLog.d(String.format(Locale.ENGLISH, "The %s has been adapted! \n%s Info: isBaseOnWidth = %s, %s = %f, %s = %f, targetDensity = %f, targetScaledDensity = %f, targetDensityDpi = %d, targetXdpi = %f, targetScreenWidthDp = %d, targetScreenHeightDp = %d"
                , activity.getClass().getName(), activity.getClass().getSimpleName(), isBaseOnWidth, isBaseOnWidth ? "designWidthInDp"
                        : "designHeightInDp", sizeInDp, isBaseOnWidth ? "designWidthInSubunits" : "designHeightInSubunits", subunitsDesignSize
                , targetDensity, targetScaledDensity, targetDensityDpi, targetXdpi, targetScreenWidthDp, targetScreenHeightDp));
    }

问题出在横竖屏之后,Activity的Resources()重新创建了,而AutoSize没有重新给它赋值,导致UI使用的是默认的Resources()参数渲染。

解决

我们通过AutoSize#autoConvertDensityOfGlobal()重新给Activity的Resources()赋值,这也是网上解决的方案。

 @Override public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    AutoSizeConfig.getInstance().setScreenWidth(ScreenUtils.getScreenSize(this)[0]);
    AutoSizeConfig.getInstance().setScreenHeight(ScreenUtils.getScreenSize(this)[1]);

    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
      //横屏 640设计图上的总高度
       AutoSize.autoConvertDensityBaseOnHeight(this, 640);
      Log.i(TAG, "onConfigurationChanged: 横屏" + newConfig.orientation);
    } else {
      //竖屏
      AutoSize.autoConvertDensityOfGlobal(this);
      Log.i(TAG, "onConfigurationChanged: 竖屏" + newConfig.orientation);
    }
  }

这两句特别重要,由于Activity#onConfigurationChanged()执行快于application#registerComponentCallbacks()#onConfigurationChanged(),则先需要重新设置屏幕宽高,再去重新更新Resources()。

AutoSizeConfig.getInstance().setScreenWidth(ScreenUtils.getScreenSize(this)[0]);
AutoSizeConfig.getInstance().setScreenHeight(ScreenUtils.getScreenSize(this)[1]);

完结

相关文章

网友评论

      本文标题:关于AutoSize Activity横竖屏布局错乱问题解决

      本文链接:https://www.haomeiwen.com/subject/rrswwltx.html