今天模拟手Q的发送图片界面做一个toolBar,布局如下:
<RelativeLayout
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/photo_select_bottom_bg"
android:layout_alignParentBottom="true" >
<Button
android:id="@+id/preview_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="@string/preview"
android:textColor="@color/photopreview_btn_text"
android:textSize="14dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:background="@drawable/photopreview_bottom_left_btn_selector" />
<Button
android:id="@+id/magic_stick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:background="@drawable/pic_icon_edit" />
<Button
android:id="@+id/send_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="15dp"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:text="@string/photo_send"
android:textColor="@color/photopreview_btn_text"
android:textSize="14dp"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:background="@drawable/photo_select_preview_btn" />
</RelativeLayout>
所有的元素都设置了一个backgroundDrawable,但是运行后得出的界面非常奇怪,
仔细检查了各项设置参数,均正常,无奈之下各种求助google,度娘,终于解决,现记录笔记如下:
相关知识
- dip
device independent pixels(设备独立像素),与屏幕密度无关的像素,这是一个基于屏幕物理的抽象单位。密度可以理解为每英寸所包含的像素个数,而1dp实际上相当于160dpi(即密度)上的一个点,也就是说,当密度为160时,1dp和1px是等价的。由于android手机的分辨率千差万别,为了让同一个高度/宽度值在不同分辨率的手机上看上去一致,android官方推出了dip的概念。
- dip和px之间的区别和联系
dp和px的转换公式为px=dip*(density/160)
。px就是像素,打个比方,要画一条240px的横线,在480宽的屏幕上看是1半屏款,而在320宽的屏幕上看是2/3(同一个尺寸的屏幕)。而画一条160dip的横线,无论在320还是480宽的屏幕上,长度都是一样的。
- 关于density
上面给出了dip和px之间的转化公式,其中涉及到了density,注意,这里的density并非设备实际的density,而是归一化后的density。google将所有的设备分为四种120(low),160(medium),240(high),320(xhigh)。可以使用getResources().getDisplayMetrics().densityDpi
查看自己设备的dpi。依照这四种dpi,android4.0时代,新建android工程,会自动生成drawable,drawalbe-ldpi,drawable-mdpi,drawable-hdpi,drawable-xhdpi五个目录,系统会根据设备dpi的大小区相应的文件夹拉取相应的资源文件。
得出结论
根据上面的知识,终于发现了问题所在,我的手机屏幕分辨率是240,因此,图片文件应该放在drawable-xhdpi下,但是我却错误的将文件放在了drawable-mdpi,这里又涉及到了几个问题,当资源文件放在了错误的文件夹下,会造成什么样的影响呢,这么多资源文件夹,系统到底是按照什么顺序来加载呢?通过各种资料查询加上试验,终于得出结论如下:
-
当图片资源放在了错误的资源文件夹下时,图片会根据相应dpi做缩放,拿本例来说,图片原始大小高度95,当将其放在了drawable-mdpi下时,会通过下列公式计算出大致新的高度
95*(240/160) = 142
,等于说是在纵向拉伸了图片,这就是为什么我们在上图中看到的元素都大了一号,其实是被背景图给撑大的。 -
加载顺序。如果我在drawable-(xdpi,hdpi,mdpi,ldpi)以及drawable这几个文件夹下放置同一个图片,那么系统是按照什么顺序来加载的呢。其实它会先到对应dpi的文件夹下找,找不到就会往比自己高的dpi文件夹下找,然后才会往比自己低的dpi文件夹下找。
至此,问题解决,正常界面: