2011-01-05 2 views
1

Ich versuche ein einfaches Spiel zu erstellen. Ich möchte ein LinearLayout auffüllen, das ich in einem XML mit mehreren RelativeLayouts definiert habe. Jedes Mal, wenn der Benutzer eine Schaltfläche drückt, möchte ich eine untergeordnete Ansicht zum LinearLayout hinzufügen. Jedes RelativeLayout würde sich basierend auf der Benutzereingabe (welche Tasten gedrückt wurden usw.) geringfügig ändern.Wie kann ich eine in einer XML-Datei definierte ViewGroup in Android mehrfach verwenden?

Ich möchte im Wesentlichen einen neuen RelativeLayout auf einem XML-Layout-Datei basiert. Ich möchte dann einige Attribute der RelativeLayout-Kind-Ansichten (speziell die src von einigen ImageViews) manipulieren und sie zu einem LinearLayout hinzufügen. Dies ist an sich nicht besonders schwierig. Ich kann mit Hilfe von findViewById auf jeden der RelativeLayout-Kinder zugreifen, aber ich habe Probleme, wenn ich n Anzahl von RelativeLayouts basierend auf demselben XML erstellen möchte. Ich bin mir ziemlich sicher, dass doppelte IDs Abstürze verursachen. Kann ein RelativeLayout ohne IDs funktionieren? Sollte ich versuchen, einen anderen Weg zu finden, die Schnittstelle mit verschiedenen ViewGroups zu erstellen? mit dem Code Alternative zu dem XML-Layout ist ein schrecklicher Gedanke

Ich bin nicht sicher, ob das, was ich bitte sogar möglich ist, aber ich weiß, dass diese Elemente on-the-fly zu erstellen.

Vielen Dank im Voraus.

Antwort

0

Ich glaube, Sie haben ein Wurzelelement zu schaffen, und dann das neue Kind hinzuzufügen.

So:

RelatoveLayout root = ....;

RelativeLayout toadd = aufblasen (Ihre XML);

durch Codeänderung anzuwenden, abhängig von den Benutzern eingegeben werden, zum Beispiel:

toadd.setBackgroundResource (....);

und schließlich das Ergebnis in der Wurzel hinzu:

root.addView (toadd).

Ich hoffe wirklich, Ihnen zu helfen!

Tschüss!

2

EDIT: Ich verlor meinen Gedankengang auf halbem Weg durch das vorherige Beispiel einige bugginess hatte. Ich habe aktualisiert.

pedr0 hat die richtige Idee, aber um es zu verdeutlichen, könnten Sie etwas in diesem Sinne versuchen (vorausgesetzt, Sie haben ein RelativeLayout in relativ.xml definiert). Dies wird nicht getestet, aber die allgemeine Idee sollte gültig sein. Sie haben nicht einmal ein separates Verfahren zu tun haben, können Sie es inline in einem Klick-Handler tun können, oder was auch immer, aber ich habe nur die addChildView Methode zum Wohl Beispiel:

LayoutInflater inflater; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    //get the LinearLayout that you plan to add rows to 
    LinearLayout linearLayout = (LinearLayout)findViewById(R.id.linear_layout); 

    //get the LayoutInflater from the system 
    inflater = getSystemService(LAYOUT_INFLATER_SERVICE); 

    //call getNewChildView with whatever drawable id you want to place 
    //as the source. If you want to pass in other types, just change 
    //the parameters (e.g. Drawable, Bitmap) 
    linearLayout.addView(getNewChildView(R.drawable.my_image)); 
} 

public RelativeLayout getNewChildView(int resId) { 
    //inflates a copy of your RelativeLayout template 
    RelativeLayout rl = (RelativeLayout)inflater.inflate(R.layout.relative, null); 

    //this assumes an ImageView in your RelativeLayout with an id of image 
    ImageView img = (ImageView)rl.findViewById(R.id.image); 
    img.setBackgroundResource(resId); 

    return rl; 
} 
+0

Vielen Dank für Ihre schnellen Antworten. Ich hatte etwas sehr ähnliches im Sinn und war tatsächlich auf einer ähnlichen Spur und mit dem LayoutInflator. – Tom

1

EDIT: Ich konnte‘ t arbeiten sogar aus, wie man die code Tags richtig verwendet seufzer

Vielen Dank für beide Ihre schnellen Antworten. Ich hatte etwas sehr ähnliches im Sinn und war tatsächlich auf dem gleichen Weg und mit dem LayoutInflator. Ich habe Ihr Beispiel ein wenig vereinfacht, da ich die ID eines Zeichners nicht weitergeben muss.

LayoutInflater inflater; 

private void drawGuess() { 
    // The top level LinearLayout to add to 
    LinearLayout topLevel = (LinearLayout) findViewById(R.id.guessList); 

    // get the inflater` 
    inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); 

    // add the view (based on stored data elsewhere) 
    topLevel.addView(getLatestGuess()); 
} 

private RelativeLayout getLatestGuess() { 
    //inflates a copy of your RelativeLayout template 
    RelativeLayout rl = (RelativeLayout)inflater.inflate(R.layout.guess_layout, null); 

    //this assumes an ImageView in your RelativeLayout with an id of image 
    ImageView guessOne = (ImageView)rl.findViewById(R.id.guess1); 
    guessOne.setImageResource(R.drawable.red); 
} 

Die Ausführung dieses Codes funktioniert, der Haken ist, es funktioniert nur beim ersten Aufruf.Beim zweiten Aufruf von getLatestGuess() stürzt es ab. Das Entfernen der IDs in der XML-Datei (z. B. rate1) aus allen untergeordneten Ansichten von RelativeLayout führt nicht mehr zum Absturz. Leider habe ich jetzt ein ziemlich nutzloses RelativeLayout, dass ich nicht mehr auf die Kindansichten von bekommen kann, da sie keine IDs haben. Vermutlich müssen IDs eindeutig sein.

+0

Vielleicht hast du es einfach weggelassen, aber du gibst nichts in deiner getLatestGuess-Methode zurück. Sie sollten Ihren Inflator auch in Ihrer onCreate() Methode initialisieren. Was meinst du damit "Crashes"? Überprüfen Sie LogCat, um herauszufinden, was falsch läuft. – kcoppock

+0

Entschuldigung, das war ein Copy/Paste-Fehler meinerseits. Ich fand einen eleganteren Weg, dieses Problem zu lösen, LinearLayout zu erweitern. Relatives Layout ist großartig, wenn Sie ein XML-definiertes Layout verwenden, bei dem jedes Element seine eigene ID hat, aber für meine Bedürfnisse war ein LinearLayout ohnehin besser geeignet. Danke für deine Hilfe. Auf einer Randbemerkung, verwirrte herum mit dem LayoutInflater einige merkwürdige Ergebnisse. Höhen und Breiten von Layouts gingen verloren, ist das erwartete Verhalten? – Tom

+0

Die Erweiterung von LinearLayout scheint für diese Situation wirklich übertrieben zu sein, aber wenn es für dich funktioniert, dann ist das großartig. Wenn Sie mit dem LayoutInflater "herumspielen", können Sie genauer sein? – kcoppock