8 votes

La mise en œuvre d'une vue étendue/personnalisée génère un message NoSuchMethod pour le constructeur.

J'ai un TextView personnalisé qui implémente les trois constructeurs de View (nb, c'est mon premier essai sur une application Android) :

public class DynamicGeometryTextView extends TextView {

    public DynamicGeometryTextView (Context con) { super(con); }

    public DynamicGeometryTextView (Context con, AttributeSet attrs) {
        super(con, attrs);
    }

    public DynamicGeometryTextView (Context con, AttributeSet attrs, int style) {
        super(con, attrs, style); 
    }

Il s'agit d'une classe interne non statique, car elle doit accéder aux données d'instance de la classe externe. Elle apparaît dans un modèle .xml :

<view class="cogdis.chalkboard.DisplayText$DynamicGeometryTextView"
    android:id="@+id/chalkboard"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" /> 

Tout se compile et s'installe correctement, mais au moment de l'exécution :

Caused by: android.view.InflateException: Binary XML file line #7: Error inflating class cogdis.chalkboard.DisplayText$DynamicGeometryTextView
    at android.view.LayoutInflater.createView(LayoutInflater.java:596)                                                                         
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:687)                                                                  
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)                                                                           
    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)                                                                            
    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)                                                                            
    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)                                                                            
    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:256)                                                       
    at android.app.Activity.setContentView(Activity.java:1867)                                                                                 
    at cogdis.chalkboard.DisplayText.onCreate(DisplayText.java:26)                                                                             
    at android.app.Activity.performCreate(Activity.java:5008)                                                                                  
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)                                                             
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)                                                              
    ... 11 more                                                                                                                                
Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]                       
    at java.lang.Class.getConstructorOrMethod(Class.java:460)                                                                                  
    at java.lang.Class.getConstructor(Class.java:431)                                                                                          
    at android.view.LayoutInflater.createView(LayoutInflater.java:561)                                                                         
    ... 22 more                                    

À mon avis, cela implique qu'il ne peut pas trouver la version (Context, AttributeSet) du constructeur... mais elle existe. J'ai regardé quelques autres messages de l'OS, tels que Constructeur de vue personnalisée Android J'ai lu le guide API sur les composants personnalisés à plusieurs reprises, mais cela fait plus d'une heure que je suis bloqué sur cette question.

Quelqu'un a une idée ? Y a-t-il un moyen de déboguer ce problème ?

POUR LA POSTERIE Pour les novices comme moi, les classes internes non statiques sont à proscrire si votre vue personnalisée est référencée dans une mise en page XML, mais si vous la créez par programme, cela peut fonctionner, par exemple :

    LayoutInflater lif = getLayoutInflater();
    ViewGroup layout = (ViewGroup)lif.inflate(R.layout.board, null);

    tv = new DynamicGeometryTextView(this);

    layout.addView((View)tv);

Dans ce cas, vous ne devez faire correspondre que les constructeurs que vous utilisez réellement. Les paramètres de mise en page (WRAP_CONTENT, etc.) peuvent être définis dans le constructeur par l'intermédiaire de setLayoutParams() qui est hérité de View.

9voto

Dheeraj V.S. Points 6384

Il n'existe aucun moyen d'instancier une classe interne non statique. sans référence à une instance de la classe externe .

OuterClass.InnerClass innerObject = outerObject.new InnerClass();

Cela pourrait donc être la raison pour laquelle l'inflateur de mise en page n'a pas réussi à gonfler votre classe. Rendez votre classe statique après avoir supprimé les références aux membres de la classe externe.

9voto

Salil Pandit Points 1230

Changez :

public class DynamicGeometryTextView extends TextView {

A :

public static class DynamicGeometryTextView extends TextView {

Afin de pouvoir le référencer correctement, il doit être une static classe intérieure

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