Android库项目使用declare styleable——如何编译?
我有一个自定义首选项控件,我在values/attrs.xml中为它定义了一些属性。下面是一个可以在values/attrs.xml中找到的属性示例,以集中讨论:Android库项目使用declare styleable——如何编译?,android,declare-styleable,Android,Declare Styleable,我有一个自定义首选项控件,我在values/attrs.xml中为它定义了一些属性。下面是一个可以在values/attrs.xml中找到的属性示例,以集中讨论: <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyCustomView"> <attr name="android:text"/> <a
<?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定义指的是库的包名,而该资源在库项目中编译得很好。但是,包含Library项目的Android项目有不同的包名,Android试图合并所有资源。当涉及到这个xmlns定义时,它会犹豫,因为包名在包含Android的项目中是不同的
有没有人想到在库项目中使用xmlns引用,而这些项目在包含Android项目时仍然有效
当Android团队考虑库时,声明styleables只是他们的一个疏忽吗?我实际上在styleable和库方面做了很多工作,并有以下观察结果: 假设您有一个包含主项目和包含库的项目:
main
|--- library
- 编译包含库的应用程序时没有问题,即使库中包含可样式化的。例如,您可以包括我的一个库()。您将在库中找到许多可设置样式的属性(如可折叠属性)和一些使用它的XML。。无论您是单独编译库还是作为包含库编译,所有的编译和工作都很好。。。所以这里看起来不错
- 现在,当您在库和主项目中都有同名资源时,您可能会在编译主项目时遇到奇怪的问题。起初我不理解它,但现在我知道它是如何工作的。例如,如果您的库main.xml中有android:id=“@+id/some_id”,然后在主项目中有另一个main.xml(没有某些_id),则编译库时将生成R.id.some_id,但不会在主项目中生成-这可能会导致主项目的编译错误,因为包含的library.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“
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/
而不是
xmlns:custom="http://schemas.android.com/apk/res/<your lib project package>
xmlns:custom=”http://schemas.android.com/apk/res/
我有了这个想法使用
http://schemas.android.com/apk/res-auto
我发现这个解决方案在项目中作为旁注随意给出:
旁白:注意名称空间中的特殊模式URL。如果您使用的是来自您自己项目的自定义视图,那么您将使用基于包名称的URL。例如但是,由于自定义视图位于包含的库中,您应该使用res auto快捷方式。构建应用程序时,将自动插入真正的架构URL
(我修复了上面引用的文本中的一个打字错误-缺少/res/子文件夹)这为我修复了它。我还记得Xamarin也有这个问题,同样的解决方案也适用于Xamarin
xmlns:ab=”http://schemas.android.com/apk/res-auto“如果lib包位于应用程序包中,即应用程序包为“com.conundrum.app”,而lib类中的类位于“com.conundrum.app.lib”,则该方法是否有效?”?还有,您是否尝试过在布局文件中使用完整的类名标记,而不是在它们前面加前缀?我的包名目前与您建议的相同。问题是您确实不能使用完整的类名,因为根据构建器的角度(无论您当前在库项目还是Android项目中),包是不同的。另外,在本例中,我在首选项文件中使用xmlns引用,而不是在布局中使用。Jarek,您已经接近问题所在。我确实可以在主应用程序中使用xmlns声明,并在库中引用可设置样式的属性。但是,如果库本身有一个需要引用可设置样式属性的公共首选项文件或布局,该怎么办?在这种情况下,在库中必须使用库包名称,但当此首选项或布局合并到主项目中时,它将不再编译。似乎除了复制任何引用可设置样式属性的公共布局或首选项文件之外,没有其他方法可以解决这个问题?不知何故,我的库中没有这个问题。当我使用库包xmlns引用attrs时,我的库实际上是编译的。它只在我描述的情况下不编译(当ID被主项目中“隐藏”的布局引用时)。你自己试试,在你的项目中使用我的库,即使我有main_demo.xml布局引用了“可折叠”属性,它也应该正确编译
xmlns:custom="http://schemas.android.com/apk/res/<your app package>
xmlns:custom="http://schemas.android.com/apk/res/<your lib project package>