14

I have a custom preferences control that I have defined a few attributes for in values/attrs.xml. Just to focus the conversation, here is an example of attributes that could be found in 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>

To use the attributes, you use an xmlns tag where you want to use it, and it looks something like this:

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

Herein lies the problem: the xmlns definition refers to the LIBRARY's package name, and this resource compiles fine in the LIBRARY project. However, the Android project that includes the Library project has a different package name and Android tries to merge all the resources. When it gets to this xmlns definition, it balks because the package name is different in the including Android project.

Anybody got any ideas for using xmlns references in Library projects that are still valid in including Android projects?

Were declare-styleables just an oversight by the Android team when they considered libraries?

Jonathan Schneider
  • 26,852
  • 13
  • 75
  • 99
  • Does it work if the lib package lies within the app package, i.e. the app package is "com.conundrum.app" and in the lib classes are in "com.conundrum.app.lib"? And, have you tried using the full class name tags in your layout files, instead of prefixing them? – manmal Jun 26 '11 at 14:58
  • My package names are currently such as you recommend. The problem is you really can't use the full class name, as the package is different depending on the perspective of the builder (whether you are currently in the library project or the Android project). Also, in this case, I am using the xmlns reference in a preferences file, not a layout. – Jonathan Schneider Jun 27 '11 at 20:41

6 Answers6

9

I actually played a lot with styleable and libraries and have the following observations:

Imagine that you have a project that has main project and included library:

main
   |--- library
  • there is no problem with compiling an application with included library even when the library contains styleable. You can for example include one of my libraries ( http://code.google.com/p/tree-view-list-android/ ). You will find a number of styleable attributes there (like collapsible) and some XMLs using it inside the library.. All compiles and works well whether you compile library alone or as included library... So here it looks good.....
  • now, you might experience strange problems with compilation of the main project when you have resources with the same name in both - library and main project. I initially did not understood it, but now I know how it works. For example if you have in your library main.xml which has android:id="@+id/some_id" and then in your main project you have another main.xml (without some_id id), then the R.id.some_id will be generated when you compile the library, but will NOT be generated in the main project - this might lead to compilation errors of the main project because included library .java files most likely will use R.id.some_id (which will be missing). I initially misunderstood the problem and tried to get id dynamically, but it was not needed at the end - it was enough to make sure your layout xmls in library use some kind of privateish namespace.
  • and now the most interesting part - how to refer to the styleable parameters in layout.xmls of the project? As you noticed, the following won't work: xmlns:custom="http://schemas.android.com/apk/res/YOUR_LIBRARY_PACKAGE" Surprisingly what works instead is xmlns:custom="http://schemas.android.com/apk/res/YOUR_MAIN_APP_PACKAGE" (!) It indeed looks like an overlook from android team, but once you know it, it works flawlessly.
Jarek Potiuk
  • 19,317
  • 2
  • 60
  • 61
  • Jarek, you are close to the problem. I can indeed use the xmlns declaration in the main application and refer to styleable attributes in the library. But what if the library itself has a common preference file or layout that needs to refer to the styleable attributes? In this case, in the library you must use the library package name, but when this preference or layout is merged into the main project, it no longer compiles. It seems that there is no way around this other than duplicating any common layout or preference file that has a reference to styleable attributes? – Jonathan Schneider Jun 28 '11 at 19:16
  • Somehow - I do not have that problem in my libraries. My library actually DOES compile when I refer to attrs using library-package-xmlns. It only does not compile in the case I described (when ids are referred to by the layout which was "shadowed" in main project). Try it yourself and use my library in your project and it should correctly compile even if I have main_demo.xml layout has reference to "collapsible" attribute.... – Jarek Potiuk Jun 28 '11 at 21:14
6

Use http://schemas.android.com/apk/res-auto

I found this solution given casually as a side-note in the AndroidSVG project:

Aside: Note the special schema URL in the namespace. If you were using a custom View from your own project you would use a URL based on your package name. For example http://schemas.android.com/apk/res/com.example.customview. But since the custom View is in an included library you should use the res-auto short-cut. The real schema URL will be automatically inserted when your app is built.

(I fixed a typo - missing /res/ subfolder - in the quoted text above)

Abid H. Mujtaba
  • 1,890
  • 1
  • 24
  • 20
5

This is a known issue in Android. A fix is expected in the next release (r13) of the development tools.

Graham Borland
  • 60,055
  • 21
  • 138
  • 179
  • And the short answer in the bug report is that now you can use: http://schemas.android.com/apk/res-auto instead of any other namespace uri and it all just works. – Damon Smith May 06 '14 at 04:18
3

Me too had the same problem. My app not detected the library-project styleable xml.

I tried this:

My Library Project package : com.lib.mylibrary My Application Project package : com.app.myapp

I tried xmlns:custom="http://schemas.android.com/apk/res/com.app.myapp

instead of xmlns:custom="http://schemas.android.com/apk/res/com.lib.mylib

It worked fine ie. try

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

instead of

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

I got this idea here

Mahendran
  • 2,719
  • 5
  • 28
  • 50
1

Maybe a bit late, but the issue appears to be fixed in the latest (r14) release of the dev tools.

Mopper
  • 1,677
  • 2
  • 18
  • 41
0

This fixed it for me. I also remember having this issue with Xamarin and the same solution worked for Xamarin.

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