强制设备从资源文件夹获取资源

3
我知道这种行为并不是预期的或标准的,但我很好奇是否能够实现。Google也意识到正常-大-超大屏幕计划并不是最好的选择,因此在Android 3.2版本中已经被弃用(layout-swXXXdp对我来说是最好的选择)。
然而,我必须支持一些低于3.2版本的设备,并且可能因此而发生错误。
主要问题是:Galaxy Note 1和Galaxy tab 1(以及其他具有相同规格的设备)从同一个layout-large文件夹中选择资源。但是合理地说,在7英寸以下和7英寸以上的屏幕上需要制作不同的布局。我知道我可以为“异常设备”制作单独的文件夹(例如,如此处所述的layout-large-xhdpi-1280x800),但那样的话,我将不得不维护几乎或完全相同的xml文件,并将它们放置在不同的文件夹中,仅仅因为这些特定的设备。
因此,目标是只维护一个xml包(文件夹)用于7英寸以下的设备和一个用于7英寸以上的设备。我知道有一些技巧,例如:
  1. 给xml文件起不同的名字(例如main.xml和main-large.xml),然后在代码中决定使用哪个,但是即使设备无法从代码中确定自己的确切大小(例如7英寸平板电脑可以返回6.8到7.8英寸的比例)。此外,我想使用更“Android风格”的资源文件夹。
  2. 保留我提到的异常文件夹。 layoutlayout-largelayout-specifictags1layout-specifictags2等,列表可以扩展。同时specifictags1、tags2和normal具有完全相同的xml文件,但需要为设备提供,以免从layout-large中选择。整个原因是为了避免这种情况。
  3. 编辑)@Joe Malin提出了使用别名的想法。不幸的是,我不能在layout-large-xhdpi-1280x800中创建一个名为main.xml的别名,该别名指向layout中的main.xml,因为它会引用自身(形成无限循环)。所以我必须在layout-large-xhdpi-1280x800中维护一个fakemain.xml,它指向只存在于layout中的main.xml。但是,我还需要一个在layout中的fakemain.xml,因为那样我就不必关心代码中的布局,只使用别名的fakemain.xml。然而,这个解决方案仍然可能有效,但实际上并不起作用。如果我在galaxy note上的layoutlayout-largelayout-large-xhdpi-1280x800中都有一个fakemain.xml,则该别名将指向layout-large,使用别名没有任何效果。

问题:

layout-sw600dp概念将授予我最佳和所需的行为,但在API级别13以下不支持。

  • 是否有一种方法可以强制设备从此文件夹中选择,或者编写其变量(使用Java反射?- 我知道那非常糟糕)以像普通屏幕一样而不是大屏幕?
  • 是否有一种方法只维护两个xml包(文件夹):
    • 一个用于7英寸以下的设备,
    • 和一个用于7英寸以上的设备。
3个回答

1

然而,我必须支持3.2以下的设备。

这样的设备并不多。

有没有一种方法可以强制设备从这个文件夹中选择,或者通过Java反射来覆盖它的变量(我知道这很糟糕)以像正常屏幕一样而不是大屏幕?

没有。但是,您可以找出那些少数设备的型号,并选择为它们加载不同的布局(例如,对于API级别13以下的少数7英寸平板电脑,通常为R.layout.main,而对于其他型号则为R.layout.you_are_worrying_about_this_way_too_much)。

有没有一种方法只维护两个xml包(文件夹):一个用于小于7英寸的设备,另一个用于大于7英寸的设备?

为了安全起见,我建议使用三个:

  • res/layout/ 适用于小于7英寸的设备
  • res/layout-sw600dp/ 适用于7英寸及以上的设备
  • res/layout-xlarge/,可以使用别名指向res/layout-sw600dp/中的布局,用于少数未升级到3.2的XOOMs、Tab 10.1等设备

谢谢,这三个文件夹很好用。那么我只需要覆盖7英寸未升级的GalaxyTab1设备,这将具有电话设计(这对我来说很好,但客户会有不同的想法)。 - abbath
然而,如果我在代码中决定(通过测试英寸)选择哪种布局,我可以加载任何布局,并且不让Android进行选择。这是一个糟糕的选择吗?我感觉这不太像Android的风格,但是这样我就可以完全控制布局了。 - abbath
@abbath:“这是一个糟糕的选择吗?”总的来说,是的,因为有太多的设备。即使你能找到所有这些设备的详细信息,拥有一个包含一千个条目的switch语句也将难以维护。打个比方:在Web应用程序中使用用户代理嗅探来提供针对IE6的解决方法是合理的。但通常不会说你要尝试为每个平台的每个浏览器版本进行分类,以尝试制作自己的浏览器到目标Web内容的映射。 - CommonsWare
不,我想我只会检查设备的尺寸,并检查它是否在7英寸以下或以上。这不是一个拥有一千个选项的switch语句,只是一个在xml加载之前必须检查的两种情况。这合理吗? - abbath
只要你对自己的计算结果感到可靠,那就没问题。 - CommonsWare
我认为我找到了一个不需要任何计算的解决方案。我不知道有另一种类型的别名可用于xml。 - abbath

1

最终我找到了最好的解决方案。但不知何故,我没有注意到有两种别名:一种是 @Joe Malin linked,另一种是 this type

不幸的是,第一种类型不是解决方案,但第二种正是我所需的,开发者页面描述的解决方案正是我需要的:

res/layout/main.xml:单面板布局

res/layout-large:多面板布局

layout res/layout-sw600dp:多面板布局

这两个文件是相同的,因为其中一个将与Android 3.2设备匹配, 而另一个则是为早期版本的Android平板电脑和电视机提供的。

为了避免对平板电脑和电视机重复使用相同的文件(以及由此产生的维护问题),您可以使用别名文件。

所以我需要在layout文件夹内与其他名称的布局中制作布局差异; 比如layout/mainnormal.xmllayout/mainlarge.xml。 然后我需要在不同的values文件夹中创建layout.xml,并根据上述link定义创建别名。
例如,我将需要一个values/layout.xml,一个values-large-xhdpi-1280x800/layout.xml(用于Galaxy Note),一个values-large/layout.xml(用于更大的设备),可能还需要一个layout-sw600dp/layout.xml
在前两个例子中,我需要为mainnormal.xml创建别名,对于其他布局,则需要为mainlarge.xml创建别名。这样,我就不需要在代码中知道我正在使用哪种类型,只需使用一个ID,例如R.layout.main
在前两种情况下的layout.xml:
<resources>
    <item name="main" type="layout">@layout/mainnormal</item>
</resources>

在后一种情况下:
<resources>
    <item name="main" type="layout">@layout/mainlarge</item>
</resources>

0

很遗憾,我无法在layout-large-xhdpi-1280x800中创建一个名为xyz.xml的别名,该别名指向layout中的xyz.xml,因为它会引用自身(造成无限循环)。我将在编辑中进一步解释。 - abbath
我找到了一个解决方案,它使用别名,但不是你提供的那种类型。 - abbath

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接