web-dev-qa-db-fra.com

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

Grrr ...

Je crée une sous-classe de vue en tant que classe interne dans mon activité. Avant j'ai simplement lié cette vue de mon activité avec:

setContentView(new CustomView(this));

sans problème.

Maintenant, cependant, ma vue devient plus complexe, donc je l'intègre à un FrameLayout afin que je puisse en faire la vue de base et ajouter un widget Spinner par-dessus. 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

Donc, cette vue fonctionnait auparavant lorsque je l'ai liée directement, mais quand j'ai essayé de l'ajouter dans le fichier main.xml dans le cadre d'un framelayout, j'ai eu l'erreur ci-dessus. J'ai également essayé de mettre dans une mise en page avec seulement elle affichée 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 à recevoir 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 de package que j'ai vérifiée trois fois.

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

C'est-à-dire qu'un signe dollar devrait être utilisé pour séparer la classe interne de la classe principale. Cependant, Eclipse s'interrompt, appelle cela une erreur et refuse de me laisser construire ou déployer avec ce personnage là-bas. Alors maintenant, la question devient: comment référencer une vue qui est une classe interne?

56
IcedDante

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.

152
Romain Guy

J'avais le même problème. Cependant, la syntaxe du fichier XML était 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
39
Whatzit Toya

pour la classe intérieure:

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

et pour la classe interne, vous devez déclarer votre classe:

public static InnerClass

static est requis.

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 écrasé. J'ai également dû rendre ma classe de vues statique pour qu'elle fonctionne. Au final, cela aurait été pareil si je l'avais juste sorti de son nid. L'exemple de note Android utilise une classe imbriquée.

2
justin

Voici quelques points clés pour créer 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 disposition 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 requis
  • constructeur avec AttributeSet est requis (au moins un)

Fichier XML

  • afficher la balise (en minuscules PAS Afficher) est requise
  • tag de classe avec le chemin d'accès à votre classe interne, en utilisant
  • $ au lieu de "." avant votre nom SubClassView
1
karenms

Vous devez spécifier le nom complet de votre classe d'affichage dans le XML pour que l'inflation fonctionne et que la classe d'affichage soit trouvée par le système d'exécution.
Puisque vous avez déclaré votre vue en tant que classe interne de votre activité, le nom complet serait: <your_package_name>.OuterClassName.InnerClassName

Êtes-vous sûr com.grafightscratch.ochemmer.CustomView est le nom complet de votre classe?

EDIT: Merci de me le rappeler. Lorsque les vues sont déclarées en tant que classes imbriquées, il y a une légère aberration, voir tiliser un composant personnalisé de ce document.

0
Samuh