問(wèn)題
最近開(kāi)發(fā)的時(shí)候發(fā)現(xiàn)Activity橫屏之后矩动,布局發(fā)生錯(cuò)亂有巧,找了好久沒(méi)有問(wèn)題,研究AutoSize看出了一點(diǎn)問(wèn)題悲没。
分析
我們從源碼的角度查看一下問(wèn)題
AutoSize初始化注冊(cè)橫豎屏監(jiān)聽(tīng)篮迎,每次橫豎屏都會(huì)回調(diào)該監(jiān)聽(tīng)
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() {
}
});
}
當(dāng)每次進(jìn)入Activity的時(shí)候都會(huì)根據(jù)AutoSizeConfig初始化設(shè)置的參考值進(jìn)行初始化 activity.getResources().getDisplayMetrics();通過(guò)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));
}
問(wèn)題出在橫豎屏之后甜橱,Activity的Resources()重新創(chuàng)建了,而AutoSize沒(méi)有重新給它賦值栈戳,導(dǎo)致UI使用的是默認(rèn)的Resources()參數(shù)渲染岂傲。
解決
我們通過(guò)AutoSize#autoConvertDensityOfGlobal()重新給Activity的Resources()賦值,這也是網(wǎng)上解決的方案子檀。
@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設(shè)計(jì)圖上的總高度
AutoSize.autoConvertDensityBaseOnHeight(this, 640);
Log.i(TAG, "onConfigurationChanged: 橫屏" + newConfig.orientation);
} else {
//豎屏
AutoSize.autoConvertDensityOfGlobal(this);
Log.i(TAG, "onConfigurationChanged: 豎屏" + newConfig.orientation);
}
}
這兩句特別重要譬胎,由于Activity#onConfigurationChanged()執(zhí)行快于application#registerComponentCallbacks()#onConfigurationChanged(),則先需要重新設(shè)置屏幕寬高命锄,再去重新更新Resources()堰乔。
AutoSizeConfig.getInstance().setScreenWidth(ScreenUtils.getScreenSize(this)[0]);
AutoSizeConfig.getInstance().setScreenHeight(ScreenUtils.getScreenSize(this)[1]);