8

我有一个奇怪的问题。

在你想出一个抨击我的想法之前,我正在制作一个定制的果冻豆。因此,“通常的好方法”在这里可能行不通,必须做出肮脏的变通办法。

我有一个 APK,其中包含以下资产:

layout
layout-mdpi
layout-land
layout-large-mdpi
layout-large-land-mdpi
layout-large-hdpi
layout-large-xhdpi

其他一些指标代码返回了这个:

D/AppDemo( 2091): measured width: 1920 PE width: 1920 scaleFactor = 1.0
D/AppDemo( 2091): [ANDROID] measured width: 1920 measured height: 1080
D/AppDemo( 2091): [ANDROID] scale for resources: 2.0 xdpi: 320.0 ydpi: 320.0
D/AppDemo( 2091): [ANDROID] screen density: xhdpi
D/AppDemo( 2091): [ANDROID] screen size: large
D/AppDemo( 2091): [ANDROID] using layout: layout-mdpi

那么,查看指标​​,为什么没有layout-large-xhdpi被加载?

请告诉我在哪里可以查到这个。我真的需要找到一种方法来强制 Layout/Resource/AssetManager加载特定的布局。

我知道在这个问题上最受欢迎的评论是“你不需要/为什么你有layout-xhdpi,你应该有drawable-xhdpilayout-large”但是,请耐心等待。

即使是关于在哪里看和寻找什么的小提示,我也会非常感激。到目前为止,AssetManager似乎是开始挖掘/记录的地方。

当我省略layout-mdpi时,应用程序在我身上崩溃,缺少资源。该错误似乎是即使代码返回xhdpi,它也假定在mdpi其他地方。我需要找到它并修复它,这样我的应用程序看起来就和它们在 ICS 上一样好:)

我正在以一种简单的方式确定哪个布局被加载 - 所有根布局都有一个android:tag元素,当setContentView(R.layout.main_layout)我抓住根元素上的标签并知道哪个文件夹被加载时。除了视觉反馈之外,这最终必须与我的设备配置相匹配。

提前致谢。

4

3 回答 3

4

市场上有很多像Micromax Funbook这样的被黑设备,它们的屏幕尺寸很大,但使用 mdpi 资源,相信我,我曾与他们合作过,这非常令人沮丧。

正如您所提到的,您的应用程序在其他所有设备上都运行良好,只是不适用于此实用平板电脑,您可能需要实施此处发布的此类解决方案

http://android-developers.blogspot.in/2011/07/new-tools-for-managing-screen-sizes.html

您必须阅读此页面上的最后一段,它肯定会有所帮助。

在这里总结一下,建议的方法是使用不同的资源创建一个具有不同名称的单独布局。

您在这里推动资源挑选过程,而不是系统。这可能很耗时,但肯定会有所帮助。

public class MyActivity extends Activity {
    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate();

        Configuration config = getResources().getConfiguration();
        if (config.smallestScreenWidthDp >= 600) {
            setContentView(R.layout.main_activity_tablet);
        } else {
            setContentView(R.layout.main_activity);
        }
    }
}  
于 2013-03-07T05:41:22.617 回答
3

有趣的问题。我看了看,但这一切都在兔子洞里。没有这样的答案,但也许我的分析会让你朝着正确的方向前进。

我看着setContentView前方发生的事情。显然,此时您是在谈论与密度无关的布局参考(例如R.layout.main_layout),然后它将变成对 APK 中特定文件的参考。您的问题是何时何地。

我使用了横向/纵向限定符,以便我可以在运行时更改质量,并且我使用了一个带有 Android 源代码的调试器。

这是一个流程,从某种方式开始。

  1. Resources.getLayout(int)
  2. Resources.loadXmlResourceParser(int, String)
  3. Resources.getValue(int, TypedValue, boolean)
  4. AssetManager.getResourceValue(int, int, TypedValue, boolean)
  5. StringBlock.get(int)
  6. StringBlock.nativeGetString(int,int)

让我们向后工作。

第 6 步是返回限定引用的本机 (C) 方法,例如/res/layout-land/yourview.xml. 然而,它的参数是一个索引,它会根据我们是横向还是纵向而变化。

要查看它的来源,我们必须回到第 4 步。索引是 TypedValue 中的一个字段,但在将它传递给此方法时,它最初设置不正确。

第 4 步调用另一个本地方法 ,AssetManager.loadResourceValue()它会更改传入的 TypedValue 并适当地设置索引。

也许您可以为此开始查看 C 并查看您的进展情况。

于 2013-03-06T19:38:44.773 回答
1

我不知道我是否正确,您正在构建自定义 AndroidOS,并且您希望此自定义 AndroidOS 始终加载相同的布局资源,在您的情况下是 layout-large-xhdpi?

如果是这样,我认为您已经自定义了Configuration Class。如果你想要它又快又脏,你可以覆盖第 72 行及以下的 int-Constants。

具体的,改变:

....
100     public static final int SCREENLAYOUT_SIZE_LARGE = 0x03;
108     public static final int SCREENLAYOUT_SIZE_XLARGE = 0x04;

到:

....
100     public static final int SCREENLAYOUT_SIZE_LARGE = 0x04;
108     public static final int SCREENLAYOUT_SIZE_XLARGE = 0x04;

其他方法可能是覆盖构造函数和 setToDefaults()-Method,以便它始终加载相同的屏幕布局。

我没有尝试过,我不知道它是否有效,并且我没有可靠和/或官方的来源(不包括官方 Android 代码),但我希望我能帮助你。

于 2013-03-01T09:51:14.203 回答