2014-10-05 5 views
18

ich den folgenden Codenicht zugänglich ist im aktuellen Kontext

public abstract class BaseAdapter<T, V extends BaseAdapter.ViewHolder> extends ArrayAdapter<T> { 
    public BaseAdapter(Context context, int resource, Collection<T> collection) { 
     // typical constructor logic 
    } 

    // some other custom defined methods 

    public static class ViewHolder { 
     // custom defined logic 
    } 
} 

public class ModelAdapter extends BaseAdapter<Model, ModelAdapter.ModelViewHolder> { 
    public ModelAdapter(Context context, int resource, Collection<Model> collection) { 
     super(context, resource, collection); 
     // typical constructor logic 
    } 

    public static class ModelViewHolder extends ViewHolder { 
     // custom defined logic 
    } 
} 

Die BaseAdapter und ModelAdapter sind in getrennten Dateien. Das Problem ist, dass ich einen Kompilierungsfehler haben beim Versuch, die ModelAdapter zu definieren: ModelViewHolder im aktuellen Kontext nicht zugänglich ist

ich diesen Fehler nicht wirklich verstehen und kann nicht herausfinden, was ich falsch mache. Kann mir jemand dieses Problem erklären oder einen Link, der diese Situation klären könnte?

+0

Können Sie die vollständige Compiler-Nachricht posten? – Fildor

+0

Das ist die komplette Compiler Nachricht – CipQuestion

Antwort

32

Creation Dead-Lock

Sie verwenden ModelAdapter.ModelViewHolder als Template-Parameter von BaseAdapter und lassen ModelAdapter erstreckt BaseAdapter, dann der Compiler ModelViewHolder zuerst erstellen versucht, aber die Klasse der ModelAdapter.ModelViewHolder (der Typ ist Klasse) ist noch nicht erstellt. Es muss auf ModelAdapter gewartet werden, da ModelViewHolder im Bereich ModelAdapter liegt.

Der Weg zu lösen ist die ModelViewHolder Klasse in eine neue * .java Datei.

+0

Gute Antwort! Ich war total verblüfft von diesem. –

+1

Ich hatte dieselbe Aufgabe. Wahrscheinlich wäre es bequemer, die ViewHolder-Klasse in eine separate * .java-Datei zu verschieben. –

+0

Ich verstehe das immer noch nicht ... Soll der ModelViewHolder statische das Problem lösen? Statischer Modifikator soll ermöglichen, dass diese Klasse initialisiert wird, ohne die Elternklasse zu initialisieren ... – BamsBamx

0

Das gleiche passiert mir bei der Erweiterung einer Basisklasse. Aber dieses Mal hatte ich es wie folgt (nach dem gegebenen Beispiel in der Frage)

BaseAdapter.java

public abstract class BaseAdapter<T, V extends BaseAdapter.ViewHolder> extends ArrayAdapter<T> { 
    public BaseAdapter(Context context, int resource, Collection<T> collection) { 
     // typical constructor logic 
    } 

    // some other custom defined methods 

    public static class ViewHolder { 
     // custom defined logic 
    } 
} 

ModelAdapter.java

import com.mypackage.ModelAdapter.ModelViewHolder; ***//NOTE THIS IMPORT!!!*** 

public class ModelAdapter extends BaseAdapter<Model, ModelAdapter.ModelViewHolder> { 
    public ModelAdapter(Context context, int resource, Collection<Model> collection) { 
     super(context, resource, collection); 
     // typical constructor logic 
    } 

    public static class ModelViewHolder extends ViewHolder { 
     // custom defined logic 
    } 
} 

That So war die Warnung weg und ModelViewHolder musste nicht in ein anderes ".java" getrennt werden Datei. Beachten Sie, dass sie sich in zwei verschiedenen Dateien befinden und in ModelAdapter.java importieren.

denke ich Fei Liang Antwort teilweise falsch ist, weil ModelViewHolder statisch wobei machen sollte ModelViewHolder zu initialisieren, ohne die übergeordnete Klasse ModelAdapter Initialisierung

+0

Ich benutze Android Studio 1.5.2 und das funktioniert nicht für mich. Android Studio sagt, dass der Import nicht verwendet wird und immer noch den Fehler gibt. – ThomasW

0

ich vor diesem Problem konfrontiert, ich bin nicht sicher, warum das geschah

aber ich beschlossen, es von

machen the not-accessible inner Klasse stand-alone Klasse (nicht innere, die in einer separaten Datei bedeutet)

1

Hier ist, wie es für mich gelöst wurde. Im Allgemeinen sollte es kein zirkuläres Abhängigkeitsproblem geben, da die geschachtelten Viewholder-Klassen statisch sind. Z.B. Sehen Sie sich die berüchtigte LayoutParams Hierarchie an, die genauso aufgebaut ist: Eine Klasse erbt eine andere Klasse, und dann haben ihre statischen verschachtelten Klassen eine entsprechende Vererbungsbeziehung.
Es sieht so aus, als käme die Zirkularität eher aus dem Sichtbarkeitsbereich.ModelViewHolder kann ViewHolder nur erweitern, wie es es kennen lernt, nachdem der äußere ModelAdapterBaseAdapter Sichtbarkeitsbereich erbt. In der Zwischenzeit kann ModelAdapterBaseAdapter nicht erben, bis die Klasse ModelViewHolder initialisiert ist, wie sie für den generischen Parameter benötigt wird. Auf der anderen Seite ist ModelViewHolder eine statische geschachtelte Klasse und hängt technisch nicht von ihrer äußeren Klasse ab.

Die Lösung besteht also darin, den Namen ViewHolder bei der Deklaration ModelViewHolder vollständig zu qualifizieren. Beachten Sie den Teil extends BaseAdapter.ViewHolder im folgenden Abschnitt. Auf diese Weise muss ModelViewHolder nicht ModelAdapter 's Bereich verwenden, um über ViewHolder zu wissen.

ModelAdapter.java

public class ModelAdapter extends BaseAdapter<Model, ModelAdapter.ModelViewHolder> { 
    public ModelAdapter(Context context, int resource, Collection<Model> collection) { 
     super(context, resource, collection); 
     // typical constructor logic 
    } 

    public static class ModelViewHolder extends BaseAdapter.ViewHolder { 
     // custom defined logic 
    } 
} 

Eine Notiz über Android Studio: Auch wenn das Problem sich nicht auf Android Studio verwandt ist, ich in sie lief von AS die "Copy-Klasse"-Funktion (mit AS 3.0). Während des Kopierens "vereinfachte" es den Code für mich und entfernte den vollständig qualifizierten Namen. Achte also auf die Intelligenz von AS!