2010-01-20 3 views
52

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

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èmes. Maintenant, cependant, mon point de vue devient de plus en plus complexe, donc je le fais partie d'un FrameLayout afin que je puisse en faire la vue de base et y ajouter un widget Spinner. Le problème est, quand je fais ce que je reçois 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 [email protected] 

So- ce point de vue travaillé avant quand je lié à directement, mais quand j'ai essayé de l'ajouter dans le fichier main.xml dans le cadre d'un framelayout J'ai l'erreur ci-dessus. J'ai également essayé de mettre dans une mise en page avec seulement il être affiché 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 d'obtenir les erreurs InflateException/ClassNotFoundException. Il se plaint de "ligne # 3" dans le fichier XML binaire, et s'il parle de main.xml c'est la déclaration du paquet que j'ai triplement vérifiée.

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 autour j'ai trouvé quelques messages disant que la balise XML devrait ressembler à ceci:

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

Ie, un signe de dollar devrait être utilisé pour séparer la classe interne de la classe principale. Cependant, Eclipse barre à ce sujet, l'appelle une erreur, et refuse de me laisser construire ou déployer avec ce personnage là. Alors maintenant la question devient: comment fait-on référence à une vue qui est une classe interne?

Répondre

146

Pour les classes internes de la syntaxe devient:

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

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

+5

Juste une note ici, la balise xml doit être "plus proche" de votre classe que la balise 'View' (dans mon cas, j'avais besoin d'un' ViewGroup') –

+0

Bien que je ne reçoive pas d'erreur, quand je récupère la vue (en utilisant findViewById), j'obtiens une instance de 'android.view.View', pas une instance de la classe interne. Ce qui donne? – yoaquim

+4

Assurez-vous que la balise de vue xml est minuscule, alors vous devriez pouvoir la convertir dans la classe que vous avez spécifiée – wkarl

0

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

Etes-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 comme des classes imbriquées, il existe une légère aberration, voir Use Custom component de ce document.

+0

Ahhhh ... vous m'avez rattrapé - j'essayais d'éditer ce post pour plus de clarté et seulement fini par introduire une "erreur de publication". OK - Je vais juste couper et coller de sorte qu'il reflète le code réel. – IcedDante

+0

D'accord, la question reflète maintenant les vrais noms de paquets. Mais oui, c'est toujours un problème. – IcedDante

+0

Voir la section «Utiliser la section des composants personnalisés» de cette page: http://developer.android.com/intl/fr/guide/topics/ui/custom-components.html#modification – Samuh

2
<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. Quand j'ai omis certains éléments comme layout_width, mon programme s'est écrasé. J'ai aussi dû rendre statique la classe de vue pour que cela fonctionne. À la fin, ça aurait été la même chose si je l'avais juste sorti de son nid. L'exemple de note android utilise une classe imbriquée.

36

J'avais le même problème. La syntaxe dans le fichier XML était correcte, cependant.Ce qui a fini par résoudre le problème pour moi était que la classe interne doit être déclarée comme statique. Par exemple:

public static class myWebView extends WebView 
+1

Thnx pour cette astuce importante! – Skip

+0

Même ici. Mot-clé statique manquant était mon problème aussi bien. –

11

pour la classe intérieure:

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

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

public static InnerClass 

static est besoin.

1

Voici quelques points clés pour faire une vue personnalisée dans une classe interne ...

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 nécessaire (au moins un)

fichier XML

  • vue tag (avec minuscules REGARDEZ PAS) est nécessaire
  • tag classe avec le chemin à votre classe interne, en utilisant
  • $ au lieu de "." avant votre nom SubClassView
+1

Merci d'avoir souligné la minuscule vue – Jello

Questions connexes