【问题标题】:Android library project uses declare-styleable -- how to compile?Android库项目使用declare-styleable——如何编译?
【发布时间】:2011-09-22 05:44:52
【问题描述】:

我有一个自定义首选项控件,我在 values/attrs.xml 中定义了一些属性。为了集中讨论,这里有一个可以在 values/attrs.xml 中找到的属性示例:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyCustomView">
        <attr name="android:text"/>
        <attr name="android:textColor"/>            
        <attr name="extraInformation" format="string" />
    </declare-styleable>
</resources>

要使用属性,你可以在你想使用它的地方使用一个 xmlns 标签,它看起来像这样:

xmlns:custom="http://schemas.android.com/apk/res/com.conundrum.app.lib"

问题就出在这里:xmlns 定义引用了 LIBRARY 的包名,并且该资源在 LIBRARY 项目中编译得很好。但是,包含 Library 项目的 Android 项目具有不同的包名称,Android 会尝试合并所有资源。当它到达这个 xmlns 定义时,它会因为包含 Android 项目中的包名称不同而犹豫不决。

有人对在包含 Android 项目中仍然有效的库项目中使用 xmlns 引用有任何想法吗?

declare-styleables 是否只是 Android 团队在考虑库时的疏忽?

【问题讨论】:

  • 如果 lib 包位于 app 包中,即 app 包是“com.conundrum.app”并且 lib 类位于“com.conundrum.app.lib”中,它是否有效?而且,您是否尝试过在布局文件中使用完整的类名标签,而不是为其添加前缀?
  • 我的包名目前是你推荐的。问题是你真的不能使用完整的类名,因为包的不同取决于构建器的角度(无论你当前是在库项目中还是在 Android 项目中)。此外,在这种情况下,我在首选项文件中使用 xmlns 引用,而不是布局。

标签: android declare-styleable


【解决方案1】:

我实际上玩了很多样式和库,并有以下观察结果:

假设您有一个包含主项目和包含库的项目:

main
   |--- library
  • 即使库包含 styleable,使用包含的库编译应用程序也没有问题。例如,您可以包含我的一个库 (http://code.google.com/p/tree-view-list-android/)。您会在那里找到许多可样式化的属性(如可折叠)和一些在库中使用它的 XML。无论您单独编译库还是作为包含库,所有编译和工作都很好......所以这里看起来不错......
  • 现在,当您在库和主项目中都有同名的资源时,您可能会在编译主项目时遇到奇怪的问题。起初我不理解它,但现在我知道它是如何工作的。例如,如果您的库 main.xml 中有 android:id="@+id/some_id",然后在您的主项目中有另一个 main.xml(没有 some_id id),那么 R.id.some_id 将编译库时会生成,但不会在主项目中生成 - 这可能会导致主项目的编译错误,因为包含的库 .java 文件很可能会使用 R.id.some_id (将丢失)。我最初误解了这个问题并尝试动态获取 id,但最终不需要它 - 确保库中的布局 xml 使用某种私有命名空间就足够了。
  • 现在是最有趣的部分——如何在项目的 layout.xmls 中引用可样式化的参数?正如您所注意到的,以下内容不起作用:xmlns:custom="http://schemas.android.com/apk/res/YOUR_LIBRARY_PACKAGE" 令人惊讶的是,xmlns:custom="http://schemas.android.com/apk/res/YOUR_MAIN_APP_PACKAGE" (!) 它确实看起来像是 android 团队的一个疏忽,但是一旦你知道它,它就会完美地工作。

【讨论】:

  • Jarek,你已经接近问题所在了。我确实可以在主应用程序中使用 xmlns 声明并引用库中的可样式属性。但是,如果库本身有一个需要引用样式属性的通用首选项文件或布局怎么办?在这种情况下,在库中您必须使用库包名称,但是当此首选项或布局合并到主项目中时,它不再编译。除了复制任何引用样式属性的通用布局或首选项文件之外,似乎没有其他方法可以解决这个问题?
  • 不知何故 - 我的图书馆没有这个问题。当我使用 library-package-xmlns 引用 attrs 时,我的库实际上会编译。它仅在我描述的情况下无法编译(当 id 被主项目中“隐藏”的布局引用时)。自己尝试并在您的项目中使用我的库,即使我有 main_demo.xml 布局引用“可折叠”属性,它也应该正确编译....
【解决方案2】:

这是 Android 中的known issue。预计会在开发工具的下一版本 (r13) 中进行修复。

【讨论】:

【解决方案3】:

可能有点晚了,但该问题似乎已在最新 (r14) 版本的开发工具中得到修复。

【讨论】:

    【解决方案4】:

    我也有同样的问题。我的应用未检测到库项目可样式化 xml。

    我试过了:

    我的图书馆项目包:com.lib.mylibrary 我的应用项目包:com.app.myapp

    我试过xmlns:custom="http://schemas.android.com/apk/res/com.app.myapp

    而不是xmlns:custom="http://schemas.android.com/apk/res/com.lib.mylib

    它工作得很好,即。 试试

    xmlns:custom="http://schemas.android.com/apk/res/<your app package>
    

    而不是

    xmlns:custom="http://schemas.android.com/apk/res/<your lib project package>
    

    我有这个想法here

    【讨论】:

      【解决方案5】:

      使用http://schemas.android.com/apk/res-auto

      我在AndroidSVG 项目中偶然发现了这个解决方案作为旁注:

      旁白:注意命名空间中的特殊架构 URL。如果您在自己的项目中使用自定义视图,您将使用基于您的包名称的 URL。例如http://schemas.android.com/apk/res/com.example.customview。但是由于自定义视图在包含的库中,您应该使用 res-auto 快捷方式。构建应用时会自动插入真实的架构 URL。

      (我修正了一个错字 - 缺少 /res/ 子文件夹 - 在上面引用的文本中)

      【讨论】:

        【解决方案6】:

        这为我解决了问题。我还记得 Xamarin 遇到过这个问题,同样的解决方案也适用于 Xamarin。

        xmlns:ab="http://schemas.android.com/apk/res-auto"

        【讨论】:

          猜你喜欢
          • 2016-08-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-07
          • 1970-01-01
          相关资源
          最近更新 更多