我们先来复习一下店dp、dpi、px
- dp(density-independent pixel )设备独立像素值,根据系统转换成px
- dpi(dots per inch) 每英寸包含的像素点
- px 像素点,假如我们的手机分辨率是7201280,手机横向有720个像素点(720px),纵向1280个点(1280px)
20190709142158952.png
如图,假如手机分辨率7201280,5英寸,勾股定理求出对角线的像素点,然后除以5,就是dpi=294.
在Android中,160dpi中,1dp=1px(一个基准),我们这个294dpi,此时1dp=1.8px,
UI出图7201280,5英寸,设计图中有一个button要占屏幕一半,在720的上是360px,换算成dp是200dp。那如果我们在10801920 5.5英寸下,设置同样的200dp呢?在此分辨率下dpi=400,1dp=2.5px,那么200dp对应的是500px,不是屏幕的一半微信图片_20200318103705.png
此时问题就在2.5这个数上,那如果想要屏幕的一半,2.5应该换成2.7
1080/400 不是正好是2.7吗,1080是我们当前分辨率的水平像素,400从哪里来的呢?400就是设计图宽度400dp
现在来看看2.5和2.7的关系?
2.5是用常规方式求出来的,也就是说1080*1920分辨率下,系统的默认的就是2.5,我们需要把密度2.5换成2.7,这不就解决适配了吗
public class Density {
private static final float WIDTH =400;//参考设备的宽,理解成设计图
private static float appDensity;//表示屏幕密度
private static float appScaleDensity; //字体缩放比例,默认appDensity
public static void setDensity(final Application application, Activity activity){
//获取当前app的屏幕显示信息
DisplayMetrics displayMetrics = application.getResources().getDisplayMetrics();
if (appDensity == 0){
//初始化赋值操作
appDensity = displayMetrics.density;
appScaleDensity = displayMetrics.scaledDensity;
//添加字体变化监听回调
application.registerComponentCallbacks(new ComponentCallbacks() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
//字体发生更改,重新对scaleDensity进行赋值
if (newConfig != null && newConfig.fontScale > 0){
appScaleDensity = application.getResources().getDisplayMetrics().scaledDensity;
}
}
@Override
public void onLowMemory() {
}
});
}
//计算目标值density, scaleDensity, densityDpi
float targetDensity = displayMetrics.widthPixels / WIDTH; // 720/ 400 = 1.8
float targetScaleDensity = targetDensity * (appScaleDensity / appDensity);
int targetDensityDpi = (int) (targetDensity * 160); 基准是160 1dp=1px
//替换Activity的density, scaleDensity, densityDpi
DisplayMetrics dm = activity.getResources().getDisplayMetrics();
dm.density = targetDensity;
dm.scaledDensity = targetScaleDensity;
dm.densityDpi = targetDensityDpi;
}
}
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Density.setDensity(getApplication(), this);
setContentView(R.layout.activity_main);
}
}
网友评论