文章链接,之前确实没有接触过,我简单看了一遍,可以说,这也是相对比较完美的方案,我先简单说一下这个方案的思路,它是通过修改density值,强行把所有不同尺寸分辨率的手机的宽度dp值改成一个统一的值,这样就解决了所有的适配问题。
比如,设计稿宽度是360px,那么开发这边就会把目标dp值设为360dp,在不同的设备中,动态修改density值,从而保证(手机像素宽度)px/density这个值始终是360dp,这样的话,就能保证UI在不同的设备上表现一致了。
这个方案侵入性很低,而且也没有涉及私有API,应该也是极不错的方案,我暂时也想不到强行修改density是否会有其他影响,既然有今日头条的大厂在用,稳定性应当是有保证的。
但是根据我的观察,这套方案对老项目是不太友好的,因为修改了系统的density值之后,整个布局的实际尺寸都会发生改变,如果想要在老项目文件中使用,恐怕整个布局文件中的尺寸都可能要重新按照设计稿修改一遍才行。因此,如果你是在维护或者改造老项目,使用这套方案就要三思了。
具体代码实现为:
// 今日头条的屏幕适配方案
// 通过修改density值,强行把所有不同尺寸分辨率的手机的宽度dp值改成一个统一的值,这样就解决了所有的适配问题
// @param activity
// @param application
private static float sNoncompatDensity;
private static float sNoncompatScaledDensity;
public static void setCustomDensity(@NonNull Activity activity, @NonNull final Application application){
DisplayMetrics appDisplayMetrics=application.getResources().getDisplayMetrics();
if (sNoncompatDensity==0){
sNoncompatDensity=appDisplayMetrics.density;
sNoncompatScaledDensity=appDisplayMetrics.scaledDensity;
application.registerComponentCallbacks(new ComponentCallbacks() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (newConfig!=null&&newConfig.fontScale>0){
sNoncompatScaledDensity=application.getResources().getDisplayMetrics().scaledDensity;
}
}
@Override
public void onLowMemory() {
}
});
}
float targetDensity=appDisplayMetrics.widthPixels/360;
float targetScaleDensity=targetDensity*(sNoncompatScaledDensity/sNoncompatDensity);
int targetDensityDpi=(int)(160*targetDensity);
appDisplayMetrics.density=targetDensity;
appDisplayMetrics.scaledDensity=targetScaleDensity;
appDisplayMetrics.densityDpi=targetDensityDpi;
final DisplayMetrics activityDisplayMetrics=activity.getResources().getDisplayMetrics();
activityDisplayMetrics.density=targetDensity;
activityDisplayMetrics.scaledDensity=targetScaleDensity;
activityDisplayMetrics.densityDpi=targetDensityDpi;
}