大多数情况下,我们要考虑手机的适配问题,以前做项目的时候,都是以480为标准,现在手机越来越发达,都以720为标准(大多数)进行屏幕适配.进行适配的话,免不了用dimens文件,在文件中存储需要用到的值,然后根据不同的手机设置不同的文件夹,这是比较通用的解决方案,当然,这肯定不是唯一的.在dp能解决大多数的适配问题的时候,一些局部的适配我们通常是在代码里设置,根据不同的屏幕密度,获取不同的像素值来设置.
获取像素值的方法,一般我们是写一个工具类,将要设置的dp转成不同的px来进行适配.
例如这样:
<span style="white-space:pre"> </span>/**
* 获取屏幕密度
*
* @return float
* @throws
*/
public static float getDensity(Context context) {
DisplayMetrics dm = new DisplayMetrics();
dm = context.getResources().getDisplayMetrics();
return dm.density;
}
/**
* dp转px
*
* @param dpValue
* dp
* @return int px
* @throws
*/
public static int dp2px(Context context, float dpValue) {
return (int) (dpValue * getDensity(context) + 0.5f);
}
这样就能比较方便的设置控件的位置,并且做到适配的目的.
但是,Android本身是不是已经有方法帮助我们转化了,貌似大多数人都没有考虑过.这就是接下来要说的TypedValue这个类.
先看一段demo代码:
<span style="white-space:pre"> </span>public class MainActivity extends Activity {
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>protected void onCreate(Bundle savedInstanceState) {
<span style="white-space:pre"> </span>super.onCreate(savedInstanceState);
<span style="white-space:pre"> </span>setContentView(R.layout.activity_main);
<span style="white-space:pre"> </span>TextView tView = (TextView) findViewById(R.id.dimen);
<span style="white-space:pre"> </span>float dimension = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, this.getResources().getDisplayMetrics());
<span style="white-space:pre"> </span>tView.setText("dimen : "+dimension);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>/**
<span style="white-space:pre"> </span> * 当单位是dp时,320*480上的值是5.0,720*1280是的值是10.0
<span style="white-space:pre"> </span> * 当单位是sp时,320*480上的值是5.0,720*1280是的值是10.0
<span style="white-space:pre"> </span> * 当单位是px时,320*480上的值是5.0,720*1280是的值是5.0
<span style="white-space:pre"> </span> *
<span style="white-space:pre"> </span> * 以此总结,此函数方法可通过不同的像素密度将不同的值根据单位不同全部转化成该设备的px值.
<span style="white-space:pre"> </span> */
<span style="white-space:pre"> </span>}
看注释的内容是不是发现了,没错,这个就是Android提供给我们的转化成不同px的方法.
<span style="white-space:pre"> </span>TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, this.getResources().getDisplayMetrics());<span style="font-family: Arial, Helvetica, sans-serif;">里,第一个参数是你的单位,这里写的是DIP,同样注释里写的是执行后的结果,我们发现通过这个方法,5dp就被转化成不同的px了.</span>
现在我们点进applyDimension方法里,看它里面的代码:
public static float applyDimension(int unit, float value,
DisplayMetrics metrics)
{
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}
一目了然!
这就是Android给我们做的通过不同的硬件来转换不同的px.可以看到,dip是跟density有关的,而sp是跟缩放比例有关的.其他的如PI,IN,MM则是跟xdpi有关,那么xdpi是什么东东,我们继续看下源码:
<span style="white-space:pre"> public void setToDefaults() {
widthPixels = 0;
heightPixels = 0;
density = DENSITY_DEVICE / (float) DENSITY_DEFAULT;
densityDpi = DENSITY_DEVICE;
scaledDensity = density;
xdpi = DENSITY_DEVICE;
ydpi = DENSITY_DEVICE;
noncompatWidthPixels = 0;
noncompatHeightPixels = 0;
}</span>
不难找到这些代码,我们发现设置xdpi和density的初始值的时候,他们的区别在于density多除了一个default的值.所以xdpi同样是跟硬件的density息息相关.
知道了这些,以后在代码里就不用自己写dp2px这类的转化工具了.
有问题请留言,多多指正.谢谢~~
转载请注明出处,尊重下劳动成果,嘿嘿~~