Programmgesteuertes Hinzufügen von Ansichten zu Ansichten
177
Angenommen, ich habe eine LinearLayoutin meinem Programm aus dem Java-Code und möchte dieser eine Ansicht hinzufügen. Welche Methode wird dafür verwendet? Ich frage nicht, wie es in XML gemacht wird, was ich weiß, sondern wie ich etwas in Anlehnung an diesen Beispielcode tun kann.
Anrufen addViewist die richtige Antwort, aber Sie müssen etwas mehr tun, damit es funktioniert.
Wenn Sie eine Ansicht über einen Konstruktor erstellen (z. B. Button myButton = new Button();), müssen Sie setLayoutParamsdie neu erstellte Ansicht aufrufen und eine Instanz der inneren Klasse LayoutParams der übergeordneten Ansicht übergeben, bevor Sie Ihr neu erstelltes untergeordnetes Element zur übergeordneten Ansicht hinzufügen.
Beispielsweise könnte der folgende Code in Ihrer onCreate()Funktion enthalten sein, vorausgesetzt, Ihr LinearLayout hat die ID R.id.main:
Es ist wichtig, dass Sie die LayoutParams festlegen. Jede Ansicht benötigt mindestens einen Parameter layout_width und einen layout_height. Es ist auch wichtig, die richtige innere Klasse zu finden. Ich hatte Probleme damit, Ansichten zu einer TableRow hinzuzufügen, damit sie ordnungsgemäß angezeigt werden, bis ich herausfand, dass ich keine Instanz von TableRow.LayoutParams an die setLayoutParams der untergeordneten Ansicht übergeben habe.
Wie würden Sie die Ansicht programmgesteuert erstellen, aber eine XML-Layoutdatei verwenden, die Sie speziell für diese neue Ansicht geschrieben haben?
SK9
8
@ SK9 Sie würden einen LayoutInflater verwenden, den Sie aus einem Kontext abrufen können, normalerweise der aktuellen Aktivität. So etwas wie: LayoutInflater myInflater = getLayoutInflater; View myView = myInflater.inflate (R.layout.myLayout, parent, false);
Brian Cooley
1
Tatsächlich stammt getLayoutInflater () aus der Window-Klasse (nicht aus Context) und ist eine praktische Methode in Activity.
Brian Cooley
2
Als Codierungspraxis können Sie in findViewById in ViewGroup oder immer die allgemeinste Form eines Objekts umwandeln, sodass Sie bei einem Wechsel von einem linearen Layout zu einem relativen Layout kein Refactoring durchführen müssen.
Joel Teply
Dies sind einige Details: D
Vivek Solanki
50
für alle, die noch interessiert sind:
Der beste Weg, den ich gefunden habe, ist die Verwendung der statischen Aufblasmethode von View.
Dabei ist yourViewXML so etwas wie R.layout.myView
Bitte beachten Sie, dass Sie eine ViewGroup benötigen, um eine Ansicht hinzuzufügen (dies ist jedes Layout, das Sie sich vorstellen können).
Nehmen wir als Beispiel an, Sie haben ein Fragment, dessen Ansicht bereits aufgeblasen wurde, und Sie wissen, dass die Stammansicht ein Layout ist, und Sie möchten ihm eine Ansicht hinzufügen:
View view = getView();// returns base view of the fragmentif(view ==null)return;if(!(view instanceofViewGroup))return;ViewGroup viewGroup =(ViewGroup) view;View popup =View.inflate(viewGroup.getContext(), R.layout.someView, viewGroup);
Sie könnten auch eine statische Methode schreiben, so etwas addView(View v){ // your code after get view }würde eine Ansicht annehmen, die mit findViewById(int resourceID)Ihrer inflatedView... gefunden oder aufgeblasen wurde, nur um Ihr Fragmentbeispiel zu erweitern.
zgc7009
22
Dies ist spät, aber dies kann jemandem helfen :) :) Um die Ansicht programmgesteuert hinzuzufügen, versuchen Sie es wie
Die Idee, Einschränkungen programmgesteuert festzulegen, kann lästig sein. Diese Lösung funktioniert für jedes Layout, egal ob Einschränkung, linear usw. Der beste Weg wäre, einen Platzhalter, dh ein FrameLayout mit geeigneten Einschränkungen (oder die richtige Platzierung in einem anderen Layout wie z. B. linear), an der Position festzulegen, an der Sie die programmgesteuert erstellte Ansicht erwarten würden haben.
Alles, was Sie tun müssen, ist, die Ansicht programmgesteuert und als untergeordnetes Element mithilfe der addChild()Methode in das FrameLayout aufzublasen . Dann wird Ihre Sicht zur Laufzeit aufgeblasen und in die richtige Position gebracht. Gemäß der Android-Empfehlung sollten Sie FrameLayout nur eine untergeordnete Ansicht hinzufügen [Link] .
So würde Ihr Code aussehen, vorausgesetzt, Sie möchten TextView programmgesteuert an einer bestimmten Position erstellen:
Schritt 1:
Platzieren Sie in Ihrem Layout, das die aufzublasende Ansicht enthalten würde, ein FrameLayout an der richtigen Position und geben Sie ihm eine ID, z. B. "Container".
Schritt 2
Erstellen Sie ein Layout mit dem Stammelement als Ansicht, die Sie zur Laufzeit aufblasen möchten. Rufen Sie die Layoutdatei als "textview.xml" auf:
Übrigens, setzen Sie die Layout-Parameter Ihres FrameLayout immer auf wrap_content, sonst wird das Frame-Layout so groß wie das übergeordnete Element, dh die Aktivität, dh der Telefonbildschirm.
Wenn nicht festgelegt, wird eine untergeordnete Ansicht des Rahmens standardmäßig links oben im Rahmenlayout angezeigt, sodass Ihre Ansicht einfach links oben auf dem Bildschirm angezeigt wird.
Schritt 3
Gehen Sie in Ihrer oncreate-Methode folgendermaßen vor:
(Beachten Sie, dass das Festlegen des letzten Parameters von findViewByIdto nullund das Hinzufügen einer Ansicht durch Aufrufen der addView()Containeransicht (frameLayout) dem einfachen Anhängen der aufgeblasenen Ansicht durch Übergeben truedes dritten Parameters von entspricht findViewById(). Weitere Informationen finden Sie hier .)
Ihr solltet auch sicherstellen, dass ihr beim Überschreiben mit allen Eigenschaften onLayoutanrufen müsst, super.onLayoutsonst wird die Aussicht nicht aufgeblasen!
für alle, die noch interessiert sind:
Der beste Weg, den ich gefunden habe, ist die Verwendung der statischen Aufblasmethode von View.
Dabei ist yourViewXML so etwas wie R.layout.myView
Bitte beachten Sie, dass Sie eine ViewGroup benötigen, um eine Ansicht hinzuzufügen (dies ist jedes Layout, das Sie sich vorstellen können).
Nehmen wir als Beispiel an, Sie haben ein Fragment, dessen Ansicht bereits aufgeblasen wurde, und Sie wissen, dass die Stammansicht ein Layout ist, und Sie möchten ihm eine Ansicht hinzufügen:
quelle
addView(View v){ // your code after get view }
würde eine Ansicht annehmen, die mitfindViewById(int resourceID)
IhrerinflatedView
... gefunden oder aufgeblasen wurde, nur um Ihr Fragmentbeispiel zu erweitern.Dies ist spät, aber dies kann jemandem helfen :) :) Um die Ansicht programmgesteuert hinzuzufügen, versuchen Sie es wie
Dadurch wird Ihre gesamte Ansicht programmgesteuert erstellt. Sie können beliebig viele Ansichten hinzufügen. Hoffe das kann helfen. :) :)
quelle
LinearLayout ist eine Unterklasse von ViewGroup mit einer Methode namens addView . Die addView- Methode sollte genau das sein, wonach Sie suchen .
quelle
Eine weitere Möglichkeit, eine Ansicht aus der Aktivität hinzuzufügen
quelle
Die Idee, Einschränkungen programmgesteuert festzulegen, kann lästig sein. Diese Lösung funktioniert für jedes Layout, egal ob Einschränkung, linear usw. Der beste Weg wäre, einen Platzhalter, dh ein FrameLayout mit geeigneten Einschränkungen (oder die richtige Platzierung in einem anderen Layout wie z. B. linear), an der Position festzulegen, an der Sie die programmgesteuert erstellte Ansicht erwarten würden haben.
Alles, was Sie tun müssen, ist, die Ansicht programmgesteuert und als untergeordnetes Element mithilfe der
addChild()
Methode in das FrameLayout aufzublasen . Dann wird Ihre Sicht zur Laufzeit aufgeblasen und in die richtige Position gebracht. Gemäß der Android-Empfehlung sollten Sie FrameLayout nur eine untergeordnete Ansicht hinzufügen [Link] .So würde Ihr Code aussehen, vorausgesetzt, Sie möchten TextView programmgesteuert an einer bestimmten Position erstellen:
Schritt 1:
Platzieren Sie in Ihrem Layout, das die aufzublasende Ansicht enthalten würde, ein FrameLayout an der richtigen Position und geben Sie ihm eine ID, z. B. "Container".
Schritt 2 Erstellen Sie ein Layout mit dem Stammelement als Ansicht, die Sie zur Laufzeit aufblasen möchten. Rufen Sie die Layoutdatei als "textview.xml" auf:
Übrigens, setzen Sie die Layout-Parameter Ihres FrameLayout immer auf wrap_content, sonst wird das Frame-Layout so groß wie das übergeordnete Element, dh die Aktivität, dh der Telefonbildschirm.
Wenn nicht festgelegt, wird eine untergeordnete Ansicht des Rahmens standardmäßig links oben im Rahmenlayout angezeigt, sodass Ihre Ansicht einfach links oben auf dem Bildschirm angezeigt wird.
Schritt 3
Gehen Sie in Ihrer oncreate-Methode folgendermaßen vor:
(Beachten Sie, dass das Festlegen des letzten Parameters von
findViewById
tonull
und das Hinzufügen einer Ansicht durch Aufrufen deraddView()
Containeransicht (frameLayout) dem einfachen Anhängen der aufgeblasenen Ansicht durch Übergebentrue
des dritten Parameters von entsprichtfindViewById()
. Weitere Informationen finden Sie hier .)quelle
Ihr solltet auch sicherstellen, dass ihr beim Überschreiben mit allen Eigenschaften
onLayout
anrufen müsst,super.onLayout
sonst wird die Aussicht nicht aufgeblasen!quelle