当我们要在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,则系统会去读取屏幕的密度,再根据密度比例来计算真正要展现在屏幕上的像素,效果会好很多。

更多相关文章

  1. 仿写Android屏幕解锁小应用
  2. Android以当前Activity为基准进行截屏
  3. android中常用的数据单位和尺寸
  4. ios模仿android屏幕密度控件自动适配
  5. 二十一、Android上常见度量单位【xdpi、hdpi、mdpi、ldpi】解读
  6. Android(安卓)关于适配
  7. Android界面设计适配不同屏幕的尺寸和密度解读
  8. Android中DP,PX,DPI及分辨率的关系
  9. Android的px,dpi,dip三者的关系详解

随机推荐

  1. 介绍一个力软敏捷开发框架
  2. 什么是委托?总结.net中重要的特性委托
  3. szq.orm.sql更新说明
  4. .net 1.x中的委托实例详解
  5. szq.orm.sql框架系列
  6. asp.net MVC 网站图片怎么实现防盗链?
  7. 怎么在Webforms 下搭建WebAPI?
  8. 总结委托和事件的联系和区别
  9. dotnet 命令如何使用?
  10. .net 2.0中的委托实例讲解