Android资源选择布局 - 和值 - 不一致

时间:2012-10-18 22:56:50

标签: android android-layout android-resources android-screen-support

我遇到的问题表明,为给定活动的layout XML选择的资源桶与从values文件夹中选择的资源不一致,尽管每个资源都使用完全相同的资源限定符一套文件夹。

实施例

在我的应用程序的抽象父活动中放置一些日志记录代码后,我可以看到,当通过Nexus 7类型模拟器(Android 4.1)启动我的应用程序时,最小宽度确实是600dp,layout-sw600dp-*文件夹正被用于获取活动的UI,但values使用的文件夹为values-large-*。我期待这是values-sw600dp-*因此向我提供关于活动所运行的资源桶的重要信息。

代码在我的应用程序的父活动中记录所有android.app.Activity s

  protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    final Configuration config = getResources().getConfiguration();
    Log.i(this.getClass().getSimpleName(), String.format("Smallest width is [%s]", config.smallestScreenWidthDp));
    configurationContext = SupportedDeviceConfiguration.fromResourceQualifer(getString(string.resourceQualifier));
    Log.i(this.getClass().getSimpleName(), String.format("Running under the [%s] configuration context.", configurationContext.getResourceQualifier()));
...

在Nexus 7类型设备上运行此代码时记录输出;

[Logging fluff] Smallest width is [600]
[Logging fluff] Running under the [layout-large-land] configuration context.

我知道你在想什么 - layout-large-land 派生的来源是什么?请继续阅读...

背景

我正在试用一种概述here的方法,它允许我在运行时检查正在使用的资源桶。基本上我实现的方法具有以下资源限定符结构;

- res
  + layout                   // Default portrait layout.
  + layout-land              // Default landscape layout
  + layout-large-land        // pre 3.2 phablet landscape layout (Galaxy Note at v2.3.3)
  + layout-xlarge-land       // pre 3.2 tablet landscape layout
  + layout-xlarge-port       // pre 3.2 tablet portrait layout
  + layout-sw520dp-port      // post 3.1 phablet portrait layout (Galaxy Note at v4.0.3)
  + layout-sw520dp-land      // post 3.1 phablet landscape layout
  + layout-sw600dp-port      // post 3.1 mini-tablet portrait layout (Nexus 7)
  + layout-sw600dp-land      // post 3.1 mini-tablet-landscape layout 
  + layout-sw700dp-port      // post 3.1 tablet portrait layout
  + layout-sw700dp-land      // post 3.1 tablet landscape layout
  - values                   // Contains the root strings.xml
     strings.xml
  - values-land
     default-config.xml            
  - values-large-land
     default-config.xml        
  - values-xlarge-land
     default-config.xml     
  - values-xlarge-port
     default-config.xml     
  - values-sw520dp-port
     default-config.xml     
  - values-sw520dp-land
     default-config.xml     
  - values-sw600dp-port
     default-config.xml     
  - values-sw600dp-land
     default-config.xml     
  - values-sw700dp-port
     default-config.xml     
  - values-sw700dp-land
     default-config.xml

基本上values限定词反映了layout限定符的限定符。在每个values-*文件夹下,我定义了一个名为device-config.xml的XML文件,其中包含内容;

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="resourceQualifier">layout-{qualifier of values folder}</string>
</resources>

因此,例如values-sw600dp-land文件夹的device-config.xml包含一个值为layout-sw600dp-land的字符串。这里的目标是让我的代码与屏幕上显示的资源布局保持同步。这是必要的,这样我的代码就不会因为涉及房地产而在“通过id查找”显示布局中不存在的某个项目。

(可选)为什么我这样做的更深层次的推理

想要了解在运行时使用的存储桶的更深层次的理由源于我的单片段所有配置代码变得难以通过各种基于交换机的逻辑来管理,这种逻辑不透明且经常来自其他布局的重复功能...就好像我需要某种Fragment Inheritance ...如果你按照链接这就是我所做的。这样做的缺点是,在指示框架实例化x,y或z片段之前,我需要知道我正在使用的屏幕,安全地知道正在创建的片段永远不会与布局不同步意在膨胀。这种继承有效,并且允许更易于管理的片段堆栈(Sonar也更快乐,这很好)。

摘要

但是,我被框架选择的布局文件夹和值文件夹之间明显的差异所阻挠。每个都有相同的限定符,因此利用layout-sw600dp-land UI XML的Activity不会使用values-sw600dp-land资源?我希望我有一些错误,因为这是我在上面讨论的SO讨论中发布的最有可能的解决方案。

2 个答案:

答案 0 :(得分:17)

我确定你正在处理用于选择的资源优先级。

如果您提供文件夹:

layout-sw600dp-*
values-large-*
values-sw600dp-*

Android没有义务将选择文件夹与 layout 的文件夹匹配,而是分别对布局使用相同的优先级逻辑,并为值文件夹单独使用。

您可以在此处了解此选择算法: http://developer.android.com/guide/topics/resources/providing-resources.html#BestMatch

答案 1 :(得分:1)

我正在为Android 4.0.3做一个应用程序。 如果你使用sw600dp,sw720dp,那么使用下一个是必要的吗?:    - values-sw600dp-port      默认-config.xml中
   - values-sw600dp-land      默认-config.xml中
   - values-sw700dp-port      默认-config.xml中
   - values-sw700dp-land      默认-config.xml中 因为我没有使用res / values-XXX,它似乎工作正常。