当我们要在Layout 中定义控件的长宽等维度时,Android的推荐是:
1)所有长宽的单位都定义成dip,除了字体的大小
2)字体的大小用sp来表示
这篇文章我们讨论一下,为什么不用像素 px, 而要用dip 表示呢? dip 跟 px 之前的关系是什么呢?
实践出真知,代码来展示。
我们先来定义两个按钮,其中一个的宽度是160 dip, 另外一个的宽度是160 px,(注意单位不同)然后来看看在不同的模拟器上有什么不一样。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView android:id="@+id/textViewSw"
android:layout_width="320dip"
android:layout_height="wrap_content"
android:background="#00CC77"
/>
<Button
android:layout_width="160dip"
android:layout_height="wrap_content"
android:text="160dip">
</Button>
<Button
android:layout_width="160px"
android:layout_height="wrap_content"
android:text="160px">
</Button>
<TextView android:id="@+id/textViewDp"
android:layout_width="160dip"
android:layout_height="wrap_content"
android:background="#00CC77"
/>
<TextView android:id="@+id/textViewPx"
android:layout_width="160dip"
android:layout_height="wrap_content"
android:background="#00CC77"
/>
</LinearLayout>
同时也定义了几个TextView, 来展示屏幕的宽度,屏幕密度比例 和 屏幕的密度。
public class DipActivity extends Activity{
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
float density = displayMetrics.density;
int densityDpi = displayMetrics.densityDpi;
int screenWidth = displayMetrics.widthPixels;
setContentView(R.layout.dip_layout);
TextView textViewSw = (TextView)findViewById(R.id.textViewSw);
textViewSw.setText("screen Width (px):" + screenWidth);
TextView dpView = (TextView)findViewById(R.id.textViewDp);
dpView.setText("Density :" + density);
TextView pxView = (TextView)findViewById(R.id.textViewPx);
pxView.setText("Density Dpi : " + String.valueOf(densityDpi));
}
}
然后我们运行代码,看看效果怎么样?如下,上面的是在480*800的模拟器上,下面是在320*480的模拟器上。
我们先来看屏幕为480*800的机器,
Button的宽度为160dip的很明显要比160px的要长,事实上,160dip的按钮占据了一半的宽度(240px),而160px的Button,就是160px.
为什么会这样呢?其实就是跟图上展示的Density有关了,我把它称为密度比例,它的值是当前屏幕的dpi (Dot Per Inch,不是dip)跟 160 的一个比例。
在屏幕密度 Density dpi 为240的手机上,密度比例Density = 240 / 160 = 1.5.
而dip 跟 px 的之间的比例 则为 px = dip * 1.5, 即当我们在布局中设置按钮的宽为160dip时,当它经过系统的换算,展现在屏幕上的已经是像素,而其值就是160 * 1.5 = 240px.
在Android手机中,一般有下面4个级别的屏幕密度,
1)120 - Low对应的density = 120 / 160 = 0.75
2)160 - Medium 对应的density = 160 / 160 = 1.0
3)240 - High 对应的density = 240 / 160 = 1.5
4)320 - Extra High 对应的density = 320 / 160 =2.0
这个值可以通过DisplayMetrics来拿到,如下:
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
float density = displayMetrics.density;
int densityDpi = displayMetrics.densityDpi;
int screenWidth = displayMetrics.widthPixels;
当我们在布局中以dip为单位的时候,中间其实会经过系统的换算,根据不同的屏幕密度,将其转换成对应屏幕的像素,从而达到适应不同屏幕分辨率的问题。
在320*480的机器上,可以看到Density Dpi = 160, 那么其Density = 160/160 = 1.0, 那么160dip 转换成像素就是 160 * 1.0 = 160px.
所以160dip的按钮跟160px的按钮在屏幕上展现是一样宽的。
综合两个图来看,当我们定义160dip的时候,无论是在上边的机器还是下边的机器,按钮都是占据屏幕的一半宽度,而如果定义成160px的话,则达不到这样的效果。
我想这也就是为什么Android会推荐用dip而不推荐px了,因为不同分辨率的手机屏幕实在是太多了,用像素的话,定死了,真不好看。
而用dip,则系统会去读取屏幕的密度,再根据密度比例来计算真正要展现在屏幕上的像素,效果会好很多。
分享到:
相关推荐
描述android的dip dp px dp等单位及其转换关系
Android中显示单位px和dip以及sp的区别
NULL 博文链接:https://1307111376.iteye.com/blog/1986752
android开发之dip,dp与px像素之间的转换工具,博文介绍:http://blog.csdn.net/qq_21376985/article/details/51704703
dip dp px sp区别 dip dp px sp区别 dip dp px sp区别
Android的计量单位px,in,mm,pt,dp,dip,sp Android的计量单位px,in,mm,pt,dp,dip,sp
简单的比较android各个单位的小程序
在屏幕密度为160的显示屏上,1dip=1px,有时候可能你的屏幕分辨率很大如480*800,但是屏幕密度没有正确设置比如说还是160,那么这个时候凡是使用dip的都会显示异常,基本都是显示过小。 dip的换算: dip(value)=...
本篇文章是对Android中dip,px,pt,sp的区别进行了详细的分析介绍,需要的朋友参考下
本篇文章是对Android中dip、dp、sp、pt和px的区别进行了详细的分析介绍,需要的朋友参考下
在xml布局文件中,我们既可以设置px,也可以设置dp(或者dip)。一般情况下,我们都会选择使用dp,这样可以保证不同屏幕分辨率的机器上布局一致。但是在代码中,如何处理呢?很多控件的方法中都只提供了设置px的方法...
RectF oval = new RectF(mIvIcon.getLeft()+UIUtils.dip2Px(5), mIvIcon.getTop()+UIUtils.dip2Px(5), mIvIcon.getRight()-UIUtils.dip2Px(5), mIvIcon.getBottom()-UIUtils.dip2Px(5)); float startAngle = -90...
mWeightRulerView.setParam(DrawUtil.dip2px(10), DrawUtil.dip2px(32), DrawUtil.dip2px(24), DrawUtil.dip2px(14), DrawUtil.dip2px(9), DrawUtil.dip2px(12)); mWeightRulerView.initViewParam(mWeight, 20.0f,...
android:width="1.0px" android:color="#33B5E5" /> android:bottomLeftRadius="10dip" android:bottomRightRadius="10dip" android:topLeftRadius="10dip" android:topRightRadius="10dip" /> </shape>
你还在为开发Android的像素而烦恼吗?赶快下载行动起来吧!里面说的非常详细!!
android sp dp px dip pt in mm 等单位