Wie funktioniert die Methode getView () beim Erstellen eines eigenen benutzerdefinierten Adapters?

101

Meine Fragen sind:

  1. Was genau ist die Funktion des LayoutInflater?
  2. Warum überprüfen alle Artikel, die ich gelesen habe, ob die Konvertierungsansicht null ist oder nicht? Was bedeutet es, wenn es null ist und was bedeutet es, wenn es nicht ist?
  3. Was ist der übergeordnete Parameter, den diese Methode akzeptiert?
GrowinMan
quelle

Antworten:

115

1: Das LayoutInflaternimmt dein Layout XML-Dateien und erstellt aus seinem Inhalt verschiedene View-Objekte.

2: Die Adapter dienen zur Wiederverwendung von Ansichten. Wenn eine Ansicht so gescrollt wird, dass sie nicht mehr sichtbar ist, kann sie für eine der neuen angezeigten Ansichten verwendet werden. Diese wiederverwendete Ansicht ist die convertView. Wenn dies null ist, bedeutet dies, dass keine recycelte Ansicht vorhanden ist und wir eine neue erstellen müssen. Andernfalls sollten wir sie verwenden, um zu vermeiden, dass eine neue erstellt wird.

3: Das parentwird bereitgestellt, damit Sie Ihre Ansicht für korrekte Layoutparameter aufblasen können.

All dies zusammen kann verwendet werden, um effektiv die Ansicht zu erstellen, die in Ihrer Liste angezeigt wird (oder eine andere Ansicht, die einen Adapter benötigt):

public View getView(int position, @Nullable View convertView, ViewGroup parent){
    if (convertView == null) {
        //We must create a View:
        convertView = inflater.inflate(R.layout.my_list_item, parent, false);
    }
    //Here we can do changes to the convertView, such as set a text on a TextView 
    //or an image on an ImageView.
    return convertView;
}

Beachten Sie die Verwendung von LayoutInflater, parentdie als Argument dafür verwendet werden kann, und wie sie convertViewwiederverwendet wird.

Jave
quelle
5
Convertview == null ist nützlich, wenn alle Ihre Elemente dem gleichen Layout folgen. Wenn Sie beispielsweise nach einem Optionsfeld oder einer aktivierten Schaltfläche suchen und das Layout für jedes Element ändern müssen, müssen Sie es neu aufblasen, sonst wird die zwischengespeicherte Ansicht angezeigt.
Sagits
Keine Notwendigkeit zu aufblasen. Sie müssen lediglich den Schalter oder die if-else-Leiter in getview schreiben und die Ansichten entsprechend Ihrem Fall aufblasen, public int getItemViewType (int position) und public int getViewTypeCount () überschreiben. @sagits
Prashanth Debbadwar
Wenn Anweisungen normalerweise funktionieren, aber wenn Sie Optionsfelder verwenden, Texte bearbeiten und solche Dinge, die ich mit zwischengespeicherten Ansichten in Schwierigkeiten hatte, gibt es einige Fragen zu diesen Dingen beim Stapelüberlauf.
Sagits
71

getView()Verfahren in Adapter ist für Ansicht des Erzeugungsstück ein ListView, Gallery...

  1. LayoutInflaterwird verwendet , um das View - Objekt zu erhalten , die Sie in einem Layout XML (das Root - Objekt, in der Regel eines zu definieren LinearLayout, FrameLayoutoder RelativeLayout)

  2. convertViewist für das Recycling. Angenommen, Sie haben eine Listenansicht, in der nur 10 Elemente gleichzeitig angezeigt werden können. Derzeit wird Element 1 -> Element 10 angezeigt. Wenn Sie ein Element nach unten scrollen, wird Element 1 nicht auf dem Bildschirm angezeigt und Element 11 wird angezeigt . Um die Ansicht für Element 11 zu generieren, wird die Methode getView () aufgerufen. convertViewHier ist die Ansicht von Element 1 (die nicht mehr erforderlich ist). Erstellen Sie stattdessen ein neues Ansichtsobjekt für Element 11 (was teuer ist). Warum nicht wiederverwenden convertView? => wir prüfen convertViewnur, ob null ist oder nicht, wenn null neue Ansicht erstellen, sonst wiederverwenden convertView.

  3. parentViewist die ListView oder Galerie ..., die die Ansicht des Elements enthält, die getView()generiert wird.

Hinweis : Sie rufen diese Methode nicht direkt auf, sondern müssen sie nur implementieren, um der übergeordneten Ansicht mitzuteilen, wie die Ansicht des Elements generiert werden soll.

Anh Tuan
quelle
2
AUSGEZEICHNETE Erklärung für die Elternansicht, kann keine bessere Erklärung finden als diese, +1
Ahmed Adel Ismail
Erstaunliche Erklärung!
Gabi
tolle Erklärung +1
tpk
8

Sie können sich dieses Video über die Listenansicht ansehen. Es stammt aus den letzten Jahren von Google IO und ist für mich immer noch die beste Durchsicht auf Listenansichten.

http://www.youtube.com/watch?v=wDBM6wVEO70

  1. Es bläst Layouts (die XML-Dateien in Ihrem res / layout / Ordner) in Java-Objekte wie LinearLayout und andere Ansichten auf.

  2. Wenn Sie sich das Video ansehen, werden Sie über die Verwendung der Konvertierungsansicht auf dem Laufenden gehalten. Im Grunde handelt es sich um eine recycelte Ansicht, die darauf wartet, von Ihnen wiederverwendet zu werden, um zu vermeiden, dass ein neues Objekt erstellt und das Scrollen Ihrer Liste verlangsamt wird.

  3. Ermöglicht es Ihnen, auf Ihre Listenansicht vom Adapter aus zu verweisen.

Erbsman
quelle
5

Was genau ist die Funktion des LayoutInflater?

Wenn Sie mit XML entwerfen, sind alle Ihre UI-Elemente nur Tags und Parameter. Bevor Sie diese UI-Elemente verwenden können (z. B. TextView oder LinearLayout), müssen Sie die tatsächlichen Objekte erstellen, die diesen XML-Elementen entsprechen. Dafür ist der Inflater da. Der Inflater verwendet diese Tags und die entsprechenden Parameter, um die tatsächlichen Objekte zu erstellen und alle Parameter festzulegen. Danach können Sie mit findViewById () einen Verweis auf das UI-Element erhalten.

Warum überprüfen alle Artikel, die ich gelesen habe, ob die Konvertierungsansicht null ist oder nicht? Was bedeutet es, wenn es null ist und was bedeutet es, wenn es nicht ist?

Dies ist eine interessante. Sie sehen, getView () wird jedes Mal aufgerufen, wenn ein Element in der Liste gezeichnet wird. Bevor das Objekt gezeichnet werden kann, muss es erstellt werden. Jetzt ist convertView im Grunde die zuletzt verwendete Ansicht zum Zeichnen eines Elements. In getView () blasen Sie zuerst die XML auf und verwenden dann findByViewID (), um die verschiedenen UI-Elemente des Listenelements abzurufen. Wenn wir nach (convertView == null) suchen, überprüfen wir, ob eine Ansicht (für das erste Element) null ist, und erstellen sie dann. Wenn sie bereits vorhanden ist, können Sie sie erneut verwenden, ohne den Aufblasvorgang erneut durchführen zu müssen . Macht es viel effizienter.

Sie müssen auch in getView () auf ein Konzept von ViewHolder gestoßen sein. Dies macht die Liste effizienter. Wir erstellen einen Ansichtsinhaber und speichern den Verweis auf alle UI-Elemente, die wir nach dem Aufblasen erhalten haben. Auf diese Weise können wir vermeiden, die zahlreichen findByViewId () aufzurufen, und viel Zeit sparen. Dieser ViewHolder wird in der Bedingung (convertView == null) erstellt und mit setTag () in der convertView gespeichert. In der else-Schleife erhalten wir es einfach mit getView () zurück und verwenden es wieder.

Was ist der übergeordnete Parameter, den diese Methode akzeptiert?

Das übergeordnete Element ist eine ViewGroup, an die Ihre von getView () erstellte Ansicht endgültig angehängt wird. In Ihrem Fall wäre dies die ListView.

Hoffe das hilft :)

Shubhayu
quelle
4
  1. Der Layout Inflator bläst / fügt Ihrer aktuellen Ansicht externes XML hinzu.

  2. getView () wird mehrfach aufgerufen, auch beim Scrollen. Wenn die Ansicht bereits aufgeblasen ist, möchten wir dies nicht noch einmal tun, da das Aufblasen ein kostspieliger Prozess ist. Deshalb prüfen wir, ob es null ist, und blasen es dann auf.

  3. Die übergeordnete Ansicht ist eine einzelne Zelle Ihrer Liste.

ngesh
quelle
3
Die übergeordnete Ansicht wird hier falsch erklärt. Es wird die ListView sein, nicht das ListItem
Varun Jain
2

LayoutInflaterwird verwendet, um dynamische Ansichten des XML für das ListViewElement oder in onCreateViewdem Fragment zu generieren .

ConvertViewwird im Wesentlichen verwendet, um die Ansichten zu recyceln, die derzeit nicht in der Ansicht enthalten sind. Angenommen, Sie haben eine scrollbare ListView. Beim Scrollen nach unten oder oben wird convertViewdie Ansicht angezeigt, die gescrollt wurde. Diese Wiederverwendung spart Speicher.

Der übergeordnete Parameter der getView()Methode gibt einen Verweis auf das übergeordnete Layout mit der ListView an. Angenommen, Sie möchten die ID eines Elements in der übergeordneten XML-Datei abrufen, die Sie verwenden können:

ViewParent nv = parent.getParent();

while (nv != null) {

    if (View.class.isInstance(nv)) {
        final View button = ((View) nv).findViewById(R.id.remove);
        if (button != null) {
            // FOUND IT!
            // do something, then break;
            button.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    // TODO Auto-generated method stub
                    Log.d("Remove", "Remove clicked");

                    ((Button) button).setText("Hi");
                }
            });
        }
        break;
    }

 }
user936414
quelle
1

getView()Methode neu erstellen Viewoder ViewGroupfür jede Zeile Listviewoder Spinner. Sie können dies Viewoder ViewGroupin einer Layout XMLDatei im res/layoutOrdner definieren und den Verweis darauf gebenAdapter Klasse Object .

Wenn Sie 4 Elemente in einem Array haben, die an den Adapter übergeben werden. getView()Methode erstellt 4 Ansicht für 4 Zeilen von Adaper.

Die LayoutInflater-Klasse verfügt über eine Methode inflate (), mit der ein Ansichtsobjekt aus dem XML-Ressourcenlayout erstellt wird.

Ravi1187342
quelle
0

Nützliche Informationen zu getView finden Sie auch auf der Adapter-Oberfläche in der Datei Adapter.java. Es sagt;

/**
 * Get a View that displays the data at the specified position in the data set. You can either
 * create a View manually or inflate it from an XML layout file. When the View is inflated, the
 * parent View (GridView, ListView...) will apply default layout parameters unless you use
 * {@link android.view.LayoutInflater#inflate(int, android.view.ViewGroup, boolean)}
 * to specify a root view and to prevent attachment to the root.
 * 
 * @param position The position of the item within the adapter's data set of the item whose view
 *        we want.
 * @param convertView The old view to reuse, if possible. Note: You should check that this view
 *        is non-null and of an appropriate type before using. If it is not possible to convert
 *        this view to display the correct data, this method can create a new view.
 *        Heterogeneous lists can specify their number of view types, so that this View is
 *        always of the right type (see {@link #getViewTypeCount()} and
 *        {@link #getItemViewType(int)}).
 * @param parent The parent that this view will eventually be attached to
 * @return A View corresponding to the data at the specified position.
 */
View getView(int position, View convertView, ViewGroup parent);
Hamza Polat
quelle