Die Android-App, die ich gerade entwickle, hat eine Hauptaktivität, die ziemlich groß geworden ist. Dies liegt hauptsächlich daran, dass es eine TabWidget
mit 3 Registerkarten enthält. Jede Registerkarte enthält einige Komponenten. Die Aktivität muss alle diese Komponenten gleichzeitig steuern. Ich denke, Sie können sich vorstellen, dass diese Aktivität etwa 20 Felder enthält (ein Feld für fast jede Komponente). Außerdem enthält es viel Logik (klicken Sie auf Listener, Logik zum Füllen von Listen usw.).
Was ich normalerweise in komponentenbasierten Frameworks mache, ist, alles in benutzerdefinierte Komponenten aufzuteilen. Jede benutzerdefinierte Komponente hätte dann eine klare Verantwortung. Es würde einen eigenen Satz von Komponenten und alle anderen mit dieser Komponente verbundenen Logik enthalten.
Ich habe versucht herauszufinden, wie dies gemacht werden kann, und ich habe in der Android-Dokumentation etwas gefunden, was sie gerne als "Compound Control" bezeichnen. (Siehe http://developer.android.com/guide/topics/ui/custom-components.html#compound und scrollen Sie zum Abschnitt "Compound Controls".) Ich möchte eine solche Komponente basierend auf einer XML-Datei erstellen, die das definiert Struktur anzeigen.
In der Dokumentation heißt es:
Beachten Sie, dass Sie wie bei einer Aktivität entweder den deklarativen (XML-basierten) Ansatz zum Erstellen der enthaltenen Komponenten verwenden oder sie programmgesteuert aus Ihrem Code verschachteln können.
Das sind gute Neuigkeiten! Der XML-basierte Ansatz ist genau das, was ich will! Aber es sagt nicht, wie es geht, außer dass es "wie bei einer Aktivität" ist ... Aber was ich in einer Aktivität mache, ist der Aufruf setContentView(...)
, die Ansichten aus XML aufzublasen. Diese Methode ist nicht verfügbar, wenn Sie beispielsweise eine Unterklasse verwenden LinearLayout
.
Also habe ich versucht, das XML manuell wie folgt aufzublasen:
public class MyCompoundComponent extends LinearLayout {
public MyCompoundComponent(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.my_layout, this);
}
}
Dies funktioniert mit Ausnahme der Tatsache, dass das von mir geladene XML als Stammelement LinearLayout
deklariert wurde. Dies führt dazu, dass das aufgeblasene LinearLayout
Kind ist, von MyCompoundComponent
dem selbst schon ein LinearLayout
!! Jetzt haben wir ein redundantes LinearLayout dazwischen MyCompoundComponent
und die Ansichten, die es tatsächlich benötigt.
Kann mir bitte jemand einen besseren Weg bieten, um dies zu erreichen und zu vermeiden, dass eine redundante LinearLayout
Instanziierung durchgeführt wird?
quelle
Antworten:
Verwenden Sie das Merge- Tag als XML-Stammverzeichnis
Überprüfen Sie diesen Artikel.
quelle
Ich denke, Sie sollten Ihren Klassennamen als XML-Stammelement verwenden:
Lassen Sie dann Ihre Klasse von dem Layout ableiten, das Sie verwenden möchten. Beachten Sie, dass Sie bei Verwendung dieser Methode den Layout-Inflater hier nicht verwenden.
Und dann können Sie Ihre Ansicht wie gewohnt in XML-Layouts verwenden. Wenn Sie die Ansicht programmgesteuert erstellen möchten, müssen Sie sie selbst aufblasen:
Leider können Sie dies nicht tun,
v = new MyView(context)
da es anscheinend keinen Weg gibt, das Problem mit verschachtelten Layouts zu umgehen. Dies ist also keine vollständige Lösung. Sie können eine Methode wie diese hinzufügenMyView
, um sie ein bisschen schöner zu machen:Haftungsausschluss: Ich spreche möglicherweise von kompletten Blöcken.
quelle
<com.example.views.MyView />
und yoursetData
undonFinishInflate
calls zu verwenden, um NPEs zu werfen, und Sie haben keine Ahnung warum.