Was ist der Schnellste Weg, um mehrere Ansichten zu einem LinearLayout?

Ich habe eine LinearLayout Ansicht, dass bereits viele Elemente enthält. Ich möchte hinzufügen, viel mehr Ansichten, um es programmatisch. Und weil dies innerhalb einer ScrollView alles wird gescrollt werden.

Also, was ich tun ist, gehen durch meine Liste, und fügen Sie neue Instanzen meiner benutzerdefinierte Ansicht zu. Das benutzerdefinierte Ansicht bläst ein XML-layout und fügt ein paar Methoden.

Dieser Ansatz gut funktioniert. Das problem ist, dass es super langsam, auch ohne crazy-code... eine Liste mit 10 items dauert etwa 500ms zu instanziieren. Als user-experience-Sicht ist das schwer zu schlucken.

Meine Frage ist, ist das der richtige/beste Ansatz? Android scheint zu viel Zeit in Anspruch nehmen aufblasen das layout, auch wenn "R. layout.my_list_item" ist super einfach. Ich Frage mich, ob es einen Weg gibt, um vielleicht wiederverwenden "aufgeblasen" layouts für zusätzliche Ansichten, irgendwie Zwischenspeichern, die komplexere Analyse?

Habe ich versucht, dies mit einer ListView (und adapter und wrapper) und es scheint zu sein, viel schneller. Das problem ist, dass ich nicht verwenden können, ein einfaches ListView; mein layout komplexer ist als eine einfache Liste (die LinearLayout selbst enthält zusätzliche benutzerdefinierte Symbole, und es hat den anderen Elternteil mit noch mehr Aussicht, bevor es eingewickelt durch den ScrollView).

Aber gibt es eine Möglichkeit, einen adapter für ein LinearLayout? Wäre das schneller, als Sie versuchen, um den Blick auf mich selbst?

Jede Hilfe ist willkommen. Ich würde gerne, um diese schneller.

Code folgt.

Haupttätigkeit:

//The LinearLayout that will contain everything
lineList = (LinearLayout) findViewById(R.id.lineList);

//Add a lot of items for testing
for (int i = 0; i < 10; i++) {
    addListItem("Item number " + i);
}

protected void addListItem(String __title) {
    MyListItem li;
    li = new MyListItem(this);
    li.setTitle(__title);
    lineList.addView(li);       
}

MyListItem:

public class MyListItem extends RelativeLayout {

    protected TextView textTitle;

    public MyListItem(Context __context) {
        super(__context);
        init();
    }

    public MyListItem(Context __context, AttributeSet __attrs) {
        super(__context, __attrs);
        init();
    }

    public MyListItem(Context __context, AttributeSet __attrs, int __attrsdefStyle) {
        super(__context, __attrs, __attrsdefStyle);
        init();
    }

    protected void init() {
        //Inflate the XML layout
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.my_list_item, this);

        //Create references
        textTitle = (TextView)findViewById(R.id.textTitle);
    }

    public void setTitle(String __text) {
        textTitle.setText(__text);
    }
}

Was ich versuche zu erreichen ist. Betrachten Sie dieses layout:

Was ist der Schnellste Weg, um mehrere Ansichten zu einem LinearLayout?

Dieses layout ist ein FrameLayout (Umkarton) mit einer ImageView (in Grau), eine TextView (innere Rechteck, oben) und eine LinearLayout (innere Rechteck, unten). Diese LinearLayout Rechteck ist die eine, die ich dynamisch füllen mit ein paar items.

Nachdem ich ihn bevölkern, möchte ich das Ergebnis dieser (wo jedes neue Rechteck ist eine neue MyListItem Instanz):

Was ist der Schnellste Weg, um mehrere Ansichten zu einem LinearLayout?

Das ist alles, was ist Scrollbar (hintergrund Bild, zum Beispiel, ist ausgerichtet auf die Oberseite). Die LinearLayout ist nicht Scrollbar von selbst (alles andere folgt) das ist der Grund, warum ein ListView, von dem was ich weiß, würde nicht gut funktionieren
in meinem Fall.

  • Wie viele Elemente haben Sie in dieser Tätigkeit, und Sie haben keine individuelle Klasse erbt, die UI-Elemente?
  • ListViews sind so schnell, da Sie recyceln den Artikel-layouts. Blasen Sie die Anzahl des Artikel-layouts erforderlich, um den Bildschirm zu füllen. Wenn Sie nach unten scrollen, einen Blick an der Spitze steht, verdeckt und eine auf der Unterseite wird angezeigt. Die listview nimmt die alten, unsichtbaren, von oben und setzen Sie die neuen Daten auf der Unterseite. Teure inflation. Gesamteindruck: Dieser hier sieht sehr ineffizient, ich bin mir ziemlich sicher, dass was auch immer Sie tun möchten, können erreicht werden mit einer listview. Wenn Sie zeigen, was du versucht hast und poste eine Skizze Ihres gewünschten layout können wir Ihnen helfen, das herausfinden.
  • Paul: das werden nicht viele Elemente. Vielleicht 4 oder 5. Ja, einige von Ihnen sind benutzerdefinierte Klassen Erben von der Grundstruktur. alextsc: danke für die Erklärung. Ich habe ein Diagramm, dass besser erklärt meine situation so klar ist, ob und wie könnte ich mit einem ListView statt (oder auch nicht).
  • Es kann nicht viel helfen, aber die Tatsache, dass Sie sind "immer" die LayoutInflater jedes mal in init() kann das hinzufügen eines fairen Betrag von Zeit für jeden Anruf. Ich würde sofort den inflater, einmal in der Haupt-Aktivität und dann übergeben Sie einen Verweis, um ihn in init(). So, Sie rufen nur getSystemService(Context.LAYOUT_INFLATER_SERVICE) einmal, und Sie brauchen nicht die getContext() rufen Sie entweder als Haupt-Aktivität kann es direkt tun. Nur eine Idee - es könnte die Dinge beschleunigen leicht.
  • danke. Eine gültige Idee. Ich habe versucht es aber keinen Unterschied in der Zeit. Ich bin mir ziemlich sicher, dass es mehr optimiert zu tun, aber der performance-Unterschied zu vernachlässigen ist.
  • Ok, ich sehe, dass diese etwas komplexer, als ich zunächst aber. Bevor ich Schreibe eine lange Antwort, wie dies zu tun: ich schrieb eine kurze Wegwerf-layout-Prototyp-Projekt mit einer ListView. Werfen Sie einen Blick und sehen, ob diese ist ca. das Ergebnis, die Sie wollen. Es ist ein bisschen vereinfacht: Der hintergrund ist nicht ein Bild, sondern ein einfaches Grau. Sie können das ändern, indem Sie die Einstellung des listviews android:background um ein Bild aus dem drawable-Ordner (in main.xml). Auch die Elemente der Liste sind einfache Standard-Elemente. Dies kann leicht geändert werden, indem mithilfe einer benutzerdefinierten adapter.
  • danke. Dies ist hilfreich. Das Bild ist immer noch ein problem, da, wie es ausgerichtet ist/skaliert (ich konnte es nicht haben, als eine einfache Hintergrundbild). Vielleicht ist der Weg, es zu tun mit einem ListView ist durch anschließen einer Veranstaltung der ListView's scrollen und dann Blättern Sie eine LinearLayout parallel auf dem hintergrund, mit allen Elementen, die ich brauche. Ein bisschen hacky, aber es könnte funktionieren. Ich wünschte nur, es war ein Weg zur Optimierung der ein linearlayout.addView() ein bisschen, obwohl, es wäre genug für meinen Fall (es ist nicht eine riesige Liste).
  • OK, ich dachte, es würde nicht viel helfen. Übrigens, testen Sie diese auf einem realen Gerät oder mit einem AVD-emulator? Es gibt einen großen Unterschied in der Leistung (sorry, wenn Sie schon realisieren, aber dachte, ich würde es erwähnen).
  • Follow-up - entweder Sie testen diese auf einem emulator oder Ihre Liste Einzelteile sind extrem Komplex (viel mehr als in deinem Beispiel-code). Mit Ihrem code mit MyListItem wie von Ihnen dargestellt, auf einem HTC Desire, die ich erzeugen kann, die 10 in unter 20ms und 500 in unter 500ms. Ich weiß, Sie sagen, dass die Liste Elemente, die Sie anzeigen möchten, enthalten Symbole etc, aber die Erzeugung dauert 10 500ms??? Das ist ein 25-facher Anstieg auf, was es braucht, meine Lust zu erzeugen, die einfache TextView-basierte Elemente - einen großen Unterschied.
  • Ich Teste auf einem Gerät (Nexus One, Android 2.3, Projekt-Ziele 2.3). Die Artikel sind nicht sehr Komplex - im Grunde 2 ImageViews, und eine TextView, die alle in einem RelativeLayout. Gut zu wissen, dass Ihre Ergebnisse; vielleicht mache ich etwas anderes falsch? Meine apk ist nur ein test und nicht zipaligned oder irgendetwas, vielleicht einen Einfluss hat. Der code auf meinen post ist ein bisschen vereinfacht, aber es gibt nichts verrücktes Hinzugefügt. Ich werde benchmark mehr, nehme ich an, um zu sehen, wo der Engpass ist (obwohl meine ersten tests wirklich gemacht, es so Aussehen, wie das aufblasen der übeltäter war).
  • Das Nexus One hat einen 1GHz Snapdragon-Prozessor (wenn ich das richtig verstanden habe) - das ist das gleiche wie das Desire. Können Sie nach dem layout-und Artikel-inflater-code, schließt die ImageViews als auch, was die Größe der Bilder sind und wo Sie sich befinden (/res/drawable-oder SD-Karte etc.)? Ich werde führen Sie einige tests mit den Bildern und sehen, wie es vergleicht.

InformationsquelleAutor zeh | 2011-12-16
Schreibe einen Kommentar