我有一个要求,我必须在我的应用程序中提供不同的layout
资源。
这个应用程序应该在许多屏幕尺寸上运行(一如既往),我希望能够尽可能精确地解决其中许多问题。
截至目前,我的目标是屏幕尺寸:
为此,我创建了一个这样的布局结构:
在XML中,我已宣布以下支持:
<supports-screens android:resizeable="true"
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true"/>
我正在测试它的模拟器,问题是:它接受layout-w480dp-land
xml,但是当我进入纵向模式时,它会回退到默认布局。
知道我可能会出错吗?
答案 0 :(得分:3)
正如我在Android
聊天室中所说,Pixels
和Density-independent pixel (dp)
不同:
与密度无关的像素(dp)
您应该使用的虚拟像素单元 在定义UI布局时使用,以表达布局尺寸或位置 以密度无关的方式。与密度无关的像素是 相当于160 dpi屏幕上的一个物理像素,即 系统为“中等”密度屏幕假定的基线密度。 在运行时,系统透明地处理dp的任何缩放 必要时,根据使用中屏幕的实际密度单位。 dp单位到屏幕像素的转换很简单:px = dp *(dpi / 160)。例如,在240 dpi屏幕上,1 dp等于1.5物理 像素。在定义时,应始终使用dp单位 应用程序的UI,以确保在屏幕上正确显示您的UI 不同的密度。
当你有一个名为layout-w480dp的文件夹时,你所说的是:
“只要宽度尺寸等于或大于480 dp ,就使用此布局文件夹。”
现在,如果您的设备具有240dpi,屏幕尺寸为480x800像素(这很可能),那么您实际上只有 320dp 可以使用 - 解释为什么您现在正在使用文件夹跳过。
dp = px /(dpi / 160)
320dp = 480px /(240dpi / 160)
答案 1 :(得分:1)
我可以推荐您参加Reto Meier的Google I / O 2011会议之一:
支持最新设备同时支持旧设备的一种方法 版本是使用“垫片”活动来决定什么平台 设备正在运行。它没有UI。 Reto显示了一些代码 根据系统版本启动不同的活动。这是一个 并行活动模式......
Link to session - 他的演示文稿也可以下载,并行模式原理从幻灯片10开始
答案 2 :(得分:0)
我听说过以下布局资源:
res/layout-sw600dp
res/layout-sw720dp
不确定您的问题,但我没有听说过 w480dp ,可能是 sw480dp 。
答案 3 :(得分:0)
使用
ldpi Resources for low-density (ldpi) screens (~120dpi).
mdpi Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.)
hdpi Resources for high-density (hdpi) screens (~240dpi).
xhdpi Resources for extra high-density (xhdpi) screens (~320dpi).
而不是w480dp
并按照下表进行操作。 Android docs
答案 4 :(得分:0)
好吧,我从来没有按照你的方式做到,但我所做的是在运行时测量屏幕尺寸和密度,并在开头的onCreate()中应用布局。 以下是供您参考的代码,可能会帮助您:
/**
* To acknowledge the density of the application so as to use the layout
* according to the phone density
*/
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
switch(metrics.densityDpi){
case DisplayMetrics.DENSITY_LOW:
setContentView(R.layout.x);
break;
case DisplayMetrics.DENSITY_MEDIUM:
setContentView(R.layout.y);
break;
case DisplayMetrics.DENSITY_HIGH:
setContentView(R.layout.z);
break;