40 votes

Aide concernant les attributs d'une vue personnalisée dans un projet de bibliothèque Android

J'ai une vue PieTimer personnalisée dans un projet de bibliothèque Android.

package com.mysite.android.library.pietimer;

public class PieTimerView extends View {
...

Je dispose également d'un fichier d'attributs XML que j'utilise dans mon PieTimer.

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

Le fichier XML stylisable ressemble à ceci

<?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>

J'ai le PieTimer dans un fichier de mise en page pour un projet qui utilise la bibliothèque, comme ceci

<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>

Auparavant, j'utilisais le xmlns:app comme espace de nom pour les attributs tels que app:ok_color mais lorsque j'ai fait de mon projet un projet de bibliothèque et que j'ai une version gratuite et complète mettant en œuvre la bibliothèque, j'ai constaté que cela ne fonctionnait plus et j'ai donc ajouté l'espace de nom pie.

La PieTimerView s'affiche mais les attributs ne fonctionnent pas, ils utilisent la valeur par défaut (ce qui ne se produisait pas auparavant), il y a donc un conflit d'espace de noms.

Quelle est la manière correcte de procéder ?

0 votes

Avez-vous trouvé une meilleure solution ?

0 votes

Dites-moi qu'il existe une meilleure façon de procéder. J'ai le même problème en incluant des publicités admob dans un projet de bibliothèque.

0 votes

Bonne question. Je suis également confronté au même problème. Tous sont les bienvenus pour donner leurs idées.

92voto

JRaymond Points 6348

Je sais que ce message est très ancien, mais si quelqu'un cherche, ce problème a été corrigé dans la révision 17+ d'ADT. Tous les services ou activités déclarent l'espace de nom comme :

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

res-auto sera remplacé au moment de la construction par le paquetage actuel du projet, donc assurez-vous de configurer vos noms d'attributs pour éviter les collisions si possible.

réf : 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/

3 votes

+1 Belle photo, le lien original est ici : Révisions pour ADT 17.0.0 .

1 votes

Question : Est-ce que la cible de notre construction est importante pour que cela fonctionne ? (Je suppose que non, mais je ne suis pas tout à fait certain...)

2 votes

@ArtOfWarfare Ça ne devrait pas, ça fait partie des outils et ça modifie votre source. Cela ne devrait avoir d'importance que pour la version des outils que vous avez installée.

9voto

NitroG42 Points 2421

Après deux heures de travail avec mon collègue, nous avons trouvé comment faire fonctionner le système :

Bibliothèque : com.library

mywidget.java avec une classe MyWidget

attrs.xml :

    <declare-styleable name="MyWidget">

et mettez votre attr.

Au lieu d'avoir votre layout (main.xml par exemple) avec votre widget déclaré dedans, créez simplement un my_widget.xml dans le dossier layout de votre bibliothèque.

mon_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>

pour l'inclure dans votre mise en page, il suffit de mettre

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

App : com.myapp

Il suffit de dupliquer mon_widget.xml ici, et de changer l'espace de nom :

<?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>

Et normalement, ça marche !

4voto

inazaruk Points 37760

Il y a un bogue connu et il est décrit ici : bogue #9656 . J'ai également décrit pourquoi cela se produit dans mon blog. poste .

0voto

itemon Points 297
xmlns:app="http://schemas.android.com/apk/res/com.mysite.android.library.myapp"

Peut-être que le package (com.mysite.Android.library.myapp) que vous avez spécifié n'est pas au bon endroit. Vous pouvez vérifier l'attribut package de l'élément minifest dans le fichier AndroidMinifest.xml. Ils devraient être identiques.

1 votes

Ils ne sont pas identiques, car il s'agit d'un projet de bibliothèque (contenant toute la logique et les mises en page), le sous-projet a un espace de nom différent et c'est ce qui cause le problème. comme ceci, com.mysite.android.library.myapp.lite y com.mysite.android.library.myapp.upgrade

0 votes

J'ai contourné ce problème en copiant manuellement tous les fichiers de mise en page dans les sous-projets et en changeant l'espace de noms... mais c'est une solution vraiment désagréable, surtout lorsque vous avez un certain nombre de mises en page.

0voto

whitebrow Points 116

Cette solution a fonctionné pour moi :

https://gist.github.com/1105281

Il n'utilise pas le TypedArray et exige que le nom du paquetage du projet de la bibliothèque soit codé en dur dans la vue.

Il n'utilise pas non plus les valeurs stylisables au niveau programmatique. Vous devez coder en dur les chaînes d'attributs dans la vue également.

Vous devez cependant déclarer ces mêmes noms d'attributs comme pouvant être stylisés pour que Lint n'affiche pas d'erreur lorsque vous écrivez la partie XML.

Un lien vers l'article original sur code.google.com :

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

C'est certainement mieux que de copier les fichiers et de changer les espaces de noms, mais ce n'est toujours pas aussi élégant que cela devrait l'être. Profitez-en.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X