Help with a custom View attributes inside a Android Library Project
Asked Answered
W

6

40

I have a custom PieTimer View in an Android Library Project

package com.mysite.android.library.pietimer;

public class PieTimerView extends View {
...

I also have a XML attributes file which I use in my PieTimer

    TypedArray a = context.obtainStyledAttributes(attrs,
        R.styleable.PieTimerView);

The XML styleable file looks like this

<?xml version="1.0" encoding="utf-8"?>
<resources>
     <declare-styleable name="PieTimerView">
        <attr name="max_size" format="dimension" />
        <attr name="start_angle" format="string" />
        <attr name="start_arc" format="string" />
        <attr name="ok_color" format="color" />
        <attr name="warning_color" format="color" />
        <attr name="critical_color" format="color" />
        <attr name="background_color" format="color" />
    </declare-styleable>
</resources>

I have the PieTimer in a layout file for a project that uses the library, like this

<RelativeLayout 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root" android:layout_gravity="center_horizontal"
    xmlns:app="http://schemas.android.com/apk/res/com.mysite.android.library.myapp"
    xmlns:pie="com.mysite.library.pietimer"
    >

<com.mysite.library.pietimer.PieTimerView
    pie:start_angle="270" 
    pie:start_arc="0" 
    pie:max_size="70dp"
    pie:ok_color="#9798AD"
    pie:warning_color="#696DC1"
    pie:critical_color="#E75757"
    pie:background_color="#D3D6FF"

    android:visibility="visible"
    android:layout_height="wrap_content" android:id="@+id/clock"
    android:layout_width="wrap_content" 
    android:layout_alignParentRight="true">
</com.mysite.library.pietimer.PieTimerView>

Previously I was using the xmlns:app as the namespace for attributes like app:ok_color but when I made my project a library project and has a Free and Full version implementing the library, I found it no longer worked so I added the pie namespace.

The PieTimerView displays but the attributed do not work, they use the default (this was not occurring before) so there is some namespace conflict hapenning here.

What is the correct way of doing this?

Weimer answered 16/12, 2010 at 13:49 Comment(4)
did you find a better solution?Coverley
Please tell me there is a better way to do this. I'm having the same problem while including admob ads in a library project.Easterling
Good question.Im also facing the same problem.All are welcome to give their ideas.Dalenedalenna
@Dalenedalenna - JRaymond gave the correct answer for this (it's the top rated answer for this question as of my writing this comment.)Bughouse
C
92

I know this post is super old, but if anyone comes looking, this problem has been fixed in ADT revision 17+ . Any services or Activities declare the namespace as:

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

res-auto will be replaced at build time with the actual project package, so make sure you set up your attribute names to avoid collisions if at all possible.

ref: http://www.androidpolice.com/2012/03/21/for-developers-adt-17-sdk-tools-r17-and-support-package-r7-released-with-new-features-and-fixes-for-lint-build-system-and-emulator/

Chilung answered 18/4, 2012 at 20:50 Comment(3)
+1 Nice shot, the original link is here: Revisions for ADT 17.0.0.Omar
Question: Does it matter what our build target is for this to work? (I'd guess not, but I'm not quite certain...)Bughouse
@Bughouse It shouldn't, this is part of the toolset and it tweaks your source. Should only matter what version of the tools you have installedChilung
E
9

After two hours of work with my coworker, we figure out how to make this work :

Library : com.library

mywidget.java with a class MyWidget

attrs.xml :

    <declare-styleable name="MyWidget">

and put your attr.

Instead of having your layout (main.xml for example) with your widget declared in it, just create a my_widget.xml in the layout folder of your library.

my_widget.xml :

<?xml version="1.0" encoding="utf-8"?>
<com.library.MyWidget
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:widget="http://schemas.android.com/apk/res/com.library"
    android:id="@+id/your_id"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    widget:your_attr>
</com.library.MyWidget>

for including it in your layout, just put

<include layout="@layout/my_widget"></include>

App : com.myapp

You just have to duplicate my_widget.xml here, and change the namespace :

<?xml version="1.0" encoding="utf-8"?>
<com.library.MyWidget
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:widget="http://schemas.android.com/apk/res/com.myapp" <---- VERY IMPORTANT
    android:id="@+id/your_id"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    widget:your_attr>
</com.library.MyWidget>

And normally it will work !

Edyth answered 11/4, 2011 at 13:27 Comment(0)
T
4

There is a known bug and its described here: bug #9656. I have also described why this happens in my blog post.

Tactic answered 11/2, 2011 at 8:58 Comment(0)
L
1

For all APIs this is the receipt ( if the library is linked as JAR , but should work also as android library project reference)

Library project: AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.myapp.library1" 
... 
</manifest>

Library project: Attrs.xml

<?xml version="1.0" encoding="utf-8"?> 
<resources>    
<declare-styleable name="MyCustStyle" >
      <attr name="MyAttr1" format="dimension" />  
    ..  
</resources>

App project MainLayout.xml (or the layout where u use the custom control)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:library1="http://schemas.android.com/apk/com.myapp.library1"
...
>

<com.myapp.library1.MyCustomView 
        library1:MyAttr1="16dp"
...
/>
</RelativeLayout>

In App Code if you want to access resources from library use (ex. array "MyCustomArray" defined in the arrays.xml fromthe lib) use:

getResources().getStringArray(com.myapp.library1.R.array.MyCustomArray)
Lues answered 25/9, 2015 at 20:18 Comment(0)
A
0
xmlns:app="http://schemas.android.com/apk/res/com.mysite.android.library.myapp"

maybe the package(com.mysite.android.library.myapp) you specified is a wrong place. you can check the package attribute of the minifest element in the AndroidMinifest.xml file. they should be identical.

Affection answered 16/12, 2010 at 15:27 Comment(2)
The are not identical, because this is a Library Project (containing all logic and layouts), the sub project have a different namespace and this is causing the problem. like this, com.mysite.android.library.myapp.lite and com.mysite.android.library.myapp.upgradeWeimer
I did get around this by manually copying all layout files to the sub projects and changing the namespace...but this is a really nasty solution, especially when you have a number of layouts.Weimer
D
0

This solution worked for me:

https://gist.github.com/1105281

It doesn't use the TypedArray and requires the view to have the library's project package name hardcoded in it.

It also does not use the styleable values on the programmatic level. You have to hardcode the attribute strings into the view as well.

You should however declare those same attribute names styleable for Lint to not show an error when you write the XML part.

A link to the original post on code.google.com:

http://code.google.com/p/android/issues/detail?id=9656#c17

It definitely beats copying the files and changing the namespaces but it still isn't as elegant as should be. Enjoy.

Dortch answered 1/2, 2012 at 19:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.