57 votes

Erreur de référencement d'une classe interne View dans layout/main.xml

Grrr...

Je crée une sous-classe de view comme classe interne dans mon Activity. Avant, j'établissais simplement un lien vers cette vue depuis mon activité avec :

setContentView(new CustomView(this));

sans problèmes.

Cependant, ma vue devient de plus en plus complexe. Je l'intègre donc à un FrameLayout afin d'en faire la vue de base et d'y ajouter un widget Spinner. Le problème est que lorsque je fais cela, j'obtiens une erreur :

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.grafightscratch.ochemmer/com.grafightscratch.ochemmer.MoleculeTablet}: android.view.InflateException: Binary XML file line #4: Error inflating class com.grafightscratch.ochemmer.MoleculeTablet.MoleculeTabletView
...
Caused by: android.view.InflateException: Binary XML file line #4: Error inflating class com.grafightscratch.ochemmer.MoleculeTablet.MoleculeTabletView
...
Caused by: java.lang.ClassNotFoundException: com.grafightscratch.ochemmer.MoleculeTablet.MoleculeTabletView in loader dalvik.system.PathClassLoader@43b74a28

Ainsi, cette vue fonctionnait auparavant lorsque j'établissais un lien direct avec elle, mais lorsque j'ai essayé de l'ajouter dans le fichier main.xml en tant que partie d'un framelayout, j'ai obtenu l'erreur ci-dessus. J'ai également essayé de l'intégrer dans une mise en page avec uniquement l'affichage via :

<com.grafightscratch.ochemmer.MoleculeTablet.MoleculeTabletView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/molecule_tablet_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>

Rien ne fonctionne. Je continue à obtenir les erreurs InflateException/ClassNotFoundException. Il se plaint de la "ligne 3" dans le fichier XML binaire, et s'il s'agit de main.xml, c'est la déclaration du paquet que j'ai vérifiée trois fois.

EDITAR J'ai essayé de faire de cette vue une classe séparée (c'est-à-dire pas une classe interne) et cela fonctionne. Après quelques recherches, j'ai trouvé des messages disant que la balise xml devrait ressembler à ceci :

<com.grafightscratch.ochemmer.MoleculeTablet$MoleculeTabletView ...>

En d'autres termes, un signe de dollar doit être utilisé pour séparer la innerclass de la classe principale. Cependant, Eclipse se rebiffe sur ce point, l'appelle une erreur et refuse de me laisser construire ou déployer avec ce caractère. La question qui se pose est donc la suivante : comment référencer une vue qui est une classe interne ?

154voto

Romain Guy Points 57114

Pour les classes internes, la syntaxe devient :

<view class="com.grafightscratch.ochemmer.MoleculeTablet$MoleculeTabletView" />

La raison en est que $ est un caractère illégal dans les balises XML.

39voto

Whatzit Toya Points 369

J'avais le même problème. La syntaxe du fichier XML était pourtant correcte.

Ce qui a fini par résoudre le problème pour moi, c'est que la classe interne doit être déclarée comme statique. Par exemple :

public static class myWebView extends WebView

11voto

Pour la classe intérieure :

<view class="{package}.{ParentClass}${innerClass}" />

et pour les classes internes, vous devez déclarer votre classe :

public static InnerClass

static est nécessaire.

2voto

karenms Points 1098

Voici quelques points clés pour réaliser une vue personnalisée à l'intérieur d'une classe interne...

public static class MainClass {
    ....
    ....
        public class SubClassView extends LinearLayout {
           public SubClassView(Context context, AttributeSet attrs) {
                super(context, attrs);
                .....
           }
    ....
    ....
       }
    }

La mise en page doit être la suivante :

<view class = ".MainClass$SubClassView"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:id="@+id/button"/>

Classe Java

  • statique est nécessaire
  • Constructeur avec AttributeSet est requis (au moins un)

Fichier XML

  • voir La balise (avec une minuscule NOT View) est requise
  • étiquette de classe avec le chemin d'accès à votre classe interne, en utilisant
  • $ au lieu de "." devant le nom de votre SubClassView

2voto

justin Points 11
<view xmlns:android="http://schemas.android.com/apk/res/android"
    class="com.example.Myproject.Myactivity$Myview"
     android:layout_width="fill_parent" android:id="@+id/name" android:visibility="visible" android:layout_gravity="bottom" android:layout_height="fill_parent" android:focusableInTouchMode="true"
/>

ce code a fonctionné pour moi. Lorsque j'ai omis certains éléments comme layout_width, mon programme s'est planté. J'ai également dû rendre ma classe de vue statique pour que cela fonctionne. Au final, cela aurait été la même chose si je l'avais simplement sortie de son nid. L'exemple de la note Android utilise une classe imbriquée.

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