38

我遇到的问题表明,为给定活动的layoutXML 选择的资源存储桶与从文件夹中选择的资源不一致,values尽管在每组文件夹中使用了完全相同的资源限定符。

例子

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

在我的应用程序的父活动中为所有android.app.Activitys进行日志记录的代码

  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.

我知道你在想什么 -大地布局的推导是从哪里来的?继续阅读...

背景

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

- 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包含一个带有 value 的字符串layout-sw600dp-land。这里的目标是让我的代码与屏幕上显示的资源布局保持同步。这是必需的,这样我的代码就不会“通过 id 查找”某些由于涉及的房地产而在显示的布局上不存在的项目。

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

想要知道在运行时使用的存储桶的更深层次的原因是因为意识到我的单一片段的所有配置代码变得难以使用各种基于开关的逻辑进行管理,这些逻辑不透明并且经常重复来自其他布局...好像我需要某种片段继承...如果您点击链接,这正是我所做的。这样做的缺点是,在指示框架实例化 x、y 或 z 片段之前,我需要知道我正在使用哪个屏幕,确保正在创建的片段永远不会与它的布局不同步是为了膨胀。这种继承有效并允许更易于管理的片段堆栈(Sonar 也更快乐,这很好)。

概括

但是,我被框架选择的布局文件夹和值文件夹之间的明显差异所挫败。每个都有相同的限定符,因此为什么利用 layout-sw600dp-landUI XML 的 Activity 不使用values-sw600dp-land资源?我希望我有问题,因为它是我在上面链接到的 SO 讨论中发布的最简洁的潜在解决方案。

4

2 回答 2

17

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

如果您提供文件夹:

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

Android 没有义务将values selection 文件夹与layout匹配,而是对 layout 和 values 文件夹分别使用相同的优先级逻辑。

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

于 2012-10-22T04:44:59.637 回答
1

我正在为 android 4.0.3 做一个应用程序。如果使用sw600dp、sw720dp,是否需要使用下一个?: - values-sw600dp-port default-config.xml
- values-sw600dp-land default-config.xml
- values-sw700dp-port default-config.xml
- values-sw700dp-land default-config.xml 因为我没有使用 res/values-XXX 并且它似乎工作正常。

于 2013-03-08T11:21:41.313 回答