重要概念:
1,什么是屏幕尺寸、屏幕分辨率、屏幕像素密度?
2,什么是 dp、dip、dpi、sp、px,之间关系是什么?
3,什么是 mdpi、hdpi、xdpi、xxdpi?如何计算和区分?
屏幕尺寸 :手机屏幕对角线长度,单位:英寸。一英寸 = 2.54厘米。一英寸 = 0.76寸。
屏幕分辨率 :手机屏幕上的有多少个像素点,单位:px,1px = 1像素点。1960*1080代表 纵像素1960,横像素1080。
屏幕像素密度:手机屏幕一英寸包含多少像素点,单位:dpi。尺寸越小,分辨率越高,则像素密度越大。
px :分辨率单位。
dp :等同 dip。160dpi为标准,1dip = 1px;320dpi下,1dip = 2px;480dpi下,1dip = 3px。
dpi:像素密度,单位。160dpi代表,一英寸有160个像素。
sp : 与 dp类似,常用于设置字体大小。
mdpi、hdpi、xdpi、xxdpi是什么?
根据 Android官方标准:
mdpi:120 ~ 160dpi。
hdpi:160 ~ 240dpi。
xhdpi:240 ~ 320dpi。
xxhdpi:320 ~ 480dpi。
xxxhdpi:480 ~ 640dpi。
比例为:2:3:4:6:8。若图片48*48 为dp,则在 mdpi屏幕为 48*48 px。
根据次比例,mdpi = 48 * 48;hdpi = 72*72;xhdpi:96*96;xxhdpi = 144*144;xxxhdpi = 192*192
常见问题:
1、多使用 wrap_content、match_parent、layout:weight。
2、如何使用 layout_weight?
LinearLayout设置 orientation="vertical",两个Btn设置 width = 0,weight分别为1和2。
那么,Btn1宽度为 1/(1+2) = 1/3,Btn2的宽度则是2/(1+2) = 2/3。
3、为什么设置 width = match_parent,其他不变,最后反而 Btn1宽度为 2/3,Btn2的宽度则是 1/3?
先搞清楚概念:android:layout_weight的真实含义是:如果View设置了该属性并且有效,那么该 View的宽度等于原有宽度。(android:layout_width)加上剩余空间的占比。
原理:若屏幕宽度为L,那么每个Btn的宽度也为L,剩余宽度就等于L-(L+L)= -L。
Btn1的weight=1,剩余宽度占比为1/(1+2)= 1/3,所以最终宽度为L+1/3*(-L)=2/3L,Btn2的计算类似,最终宽度为L+2/3(-L)=1/3L。
4、可以使用 RelativeLayout,禁止使用 AbsoluteLayout。
使用限定符
使用尺寸限定符
简单来说,就是针对各种屏幕配置备用布局。
例子:
res/layout/main.xml,单面板(默认)布局:
android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="match_parent" />
res/layout-large/main.xml,双面板布局:
android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="400dp" android:layout_marginRight="10dp"/> android:layout_height="fill_parent" android:name="com.example.android.newsreader.ArticleFragment" android:layout_width="fill_parent" />
由于使用了 large限定符,系统会自动在较大的屏幕(7英寸或更大)上选择此布局。
使用最小宽度限定符
场景:“较大”这屏幕尺寸范围比较模糊,大于5寸或7寸都算“较大”,那要如何准确为7寸适配屏幕?
res/layout/main.xml,单面板(默认)布局:
android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="match_parent" />
res/layout-sw600dp/main.xml,双面板布局
android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="400dp" android:layout_marginRight="10dp"/> android:layout_height="fill_parent" android:name="com.example.android.newsreader.ArticleFragment" android:layout_width="fill_parent" />
总结:使用 sw-600dp,就可以对于 最小宽度大于或等于 600dp设备,使用双面板布局。
使用布局别名
最小宽度仅适用于 Android 3.2及以上。
场景:我们需要在手机显示单面板、7英寸平板电脑、电视或其他较大设备电视多面板,我们需要
res/layout/main.xml: 单面板布局
res/layout-large: 多面板布局
res/layout-sw600dp: 多面板布局
后两文件相同,一个与3.2适配,一个为版本低的平板电脑和电视准备。你可以这样做:
res/layout/main.xml,单面板布局
res/layout/main_twopanes.xml,双面板布局
res/values-large/layout.xml:
res/values-sw600dp/layout.xml:
总结:后两文件内容一样,但并未实际定义布局,将 main设置 main_twopanes别名,由于都包含
large和 sw600dp。这样无论 Android版本如何,都会成功适配。
使用屏幕方向限定符
场景:有时,我们需要为每个布局分配各种屏幕配置,例如。
小屏幕,纵向:单面板,带徽标
小屏幕,横向:单面板,带徽标
7 英寸平板电脑,纵向:单面板,带操作栏
7 英寸平板电脑,横向:双面板,宽,带操作栏
10 英寸平板电脑,纵向:双面板,窄,带操作栏
10 英寸平板电脑,横向:双面板,宽,带操作栏
电视,横向:双面板,宽,带操作栏
res/layout/onepane.xml:(单面板)
android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="match_parent" />
res/layout/onepane_with_bar.xml:(单面板带操作栏)
android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> android:id="@+id/linearLayout1" android:gravity="center" android:layout_height="50dp"> android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/logo" android:paddingRight="30dp" android:layout_gravity="left" android:layout_weight="0" /> android:id="@+id/view1" android:layout_width="wrap_content" android:layout_weight="1" /> android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="match_parent" />
res/layout/twopanes.xml:(双面板,宽布局)
android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="400dp" android:layout_marginRight="10dp"/> android:layout_height="fill_parent" android:name="com.example.android.newsreader.ArticleFragment" android:layout_width="fill_parent" />
res/layout/twopanes_narrow.xml:(双面板,窄布局)
android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"> android:layout_height="fill_parent" android:name="com.example.android.newsreader.HeadlinesFragment" android:layout_width="200dp" android:layout_marginRight="10dp"/> android:layout_height="fill_parent" android:name="com.example.android.newsreader.ArticleFragment" android:layout_width="fill_parent" />
将布局定义完,我们可用 布局别名技术做到这点:
res/values/layouts.xml:
res/values-sw600dp-land/layouts.xml:
res/values-sw600dp-port/layouts.xml:
res/values-large-land/layouts.xml:
res/values-large-port/layouts.xml:
最后总结:
1、必须 dp指定两个视图间的间距。
2、最好使用 sp指定文字大小。
3、可以情况下,最好多用 match_parent或 wrap_content或weight,尽可能少用 dp指定控件长度。
4、提供备用位图,如果为 xhdpi准备了 200*200图片,那么也应该为hdpi、mdpi准备缩小后的图片。
参考资料:https://blog.csdn.net/zhaokaiqiang1992/article/details/45419023