Layout für einen AlertDialog

  • 15 Antworten
  • Neuester Beitrag
Diskutiere Layout für einen AlertDialog im Android App Entwicklung im Bereich Betriebssysteme & Apps.
P

Patpa

Neues Mitglied
Hallo Community! ich beschäftige mich seit etwa 2 Wochen mit der App Programmierung für Android. Davor hab ich nur Kleinigkeiten in c++ programmiert. Leider verrenne ich mich ständig in irgendwelchen Fehlern über die wahrscheinlich erfahrene Programmier nur lachen können :)

Vor paar Tagen hab ich entdeckt, dass ich in einem AlertDialog auch eine Layout.xml(Name vom Layout ist "input") aufrufen kann was ist für meine App echt super finde. In diesem neuen Layout will ich unter anderem einen Spinner einbauen. Dieser Spinner läuft momentan wunderbar in meiner activity_main.xml. Jetzt hab ich gedacht wenn ich in meiner Methode die ID meines neuen Spinners einfach ändere würde das reichen, da die ID ja ohne Probleme akzeptiert wird. Leider bleibt mein Spinner nach Aufruf meines neuen Layouts leer. Hier mal Teile meines Quelltextes. Erstmal die Methode in der ich meinen Spinner fülle.
Code:
private void getbtDevices(BluetoothAdapter btAdapter, Spinner btspinner)
    {
    	if (btAdapter == null)
    		return;
    	Set<BluetoothDevice> btDevices = btAdapter.getBondedDevices();
    	List<String> list = new ArrayList<String>();
    	Iterator<BluetoothDevice> btIt = btDevices.iterator();
    	BluetoothDevice btDev = null;
    	adresses.clear();
    	while (btIt.hasNext())
    	{ 
    		btDev = btIt.next();
    		list.add(btDev.getName());
    		adresses.add(btDev.getAddress());
    	}
    	ArrayAdapter<String> Adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_spinner_item, list);
	    Adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
	    btspinner = (Spinner) findViewById(R.id.spinner2);
	    btspinner.setAdapter(Adapter);
	    
	    btspinner.setOnItemSelectedListener(new OnItemSelectedListener()
	    {
			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,int arg2, long arg3) 
			{
				currentAddress = adresses.elementAt(arg2);
				adresswahl.setText("Adresse:"+currentAddress);
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) 
			{
			}
	    	
	    });
    }
Und hier mal den Quelltext des Layouts welches mittels Menü aufgerufen wird

Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="300dp"
    android:layout_height="50dp"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="89dp"
        android:layout_height="wrap_content"
        android:text="Rover"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Spinner
        android:id="@+id/spinner2"
        android:layout_width="wrap_content"
        android:layout_height="32dp" />

</LinearLayout>
Da ich leider echt nicht weiß woran es liegt kommt hier jetzt auch noch das Menü

Code:
protected Dialog onCreateDialog (int id, Bundle savedInstanceState) 
    {
   	 switch (id) 
   	 {
   	 case 10:
   		 Builder builder = new AlertDialog.Builder(this);
   		 builder.setMessage("Applikation wird geschlossen!");
   		 builder.setCancelable(true);
   		 builder.setPositiveButton("OK", new DialogInterface.OnClickListener() 
   		 {
   			 public void onClick(DialogInterface dialog, int which) 
   			 {
   				 unbindService(mConnection);
   				 MainActivity.this.finish();	 
   			 }
   		 });
   		 builder.setNegativeButton("Nein, doch nicht!", new DialogInterface.OnClickListener() 
   		 {
   			 public void onClick(DialogInterface dialog, int which) 
   			 {
   				 Toast.makeText(getApplicationContext(), "Applikation wird fortgesetzt", Toast.LENGTH_LONG).show();
   			 }
   		 }); 
   		 return builder.create();
   		 
   	 case 100:
   			 Builder builder1 = new AlertDialog.Builder(this);
   			 LayoutInflater inflater = this.getLayoutInflater();
   			 builder1.setView(inflater.inflate(R.layout.input,  null));
   		 
   			 builder1.setPositiveButton("OK", new DialogInterface.OnClickListener() 
   			 {
   				 public void onClick(DialogInterface dialog, int which) 
   				 {
   					 unbindService(mConnection);
   					 MainActivity.this.finish();	 
   				 }
   			 });
   			 builder1.setNegativeButton("Close", new DialogInterface.OnClickListener() 
   			 {
   			 public void onClick(DialogInterface dialog, int which) 
   			 {
   				 Toast.makeText(getApplicationContext(), "Applikation wird fortgesetzt", Toast.LENGTH_LONG).show();
   			 }
   			 }); 
   			 return builder1.create();
   	 	}
   	 	return super.onCreateDialog(id);
    }
Ich weiß die Button machen momentan noch keinen Sinn bin halt am testen :)
Wäre super wenn mich jemand in die richtige Richtung stumpen könnte. Denke mal ist echt nur eine Kleinigkeit. Was wahrscheinlich daran liegt dass ich das ganze zusammenspiel noch nicht so ganz verstanden habe.
Vielen Danke!
Gruß
Pat

Ach ja falls das eine Rolle spielt benutze Eclipse.
 
StefMa

StefMa

Experte
Das Problem ist folgendes:
Jedes mal wenn du
Code:
builder1.setView(inflater.inflate(R.layout.input,  null));
aufrufst, wird das layout "geholt" und in den builder1 gesetzte.
D.h. dein Spinner hat genau die eingeschaften, die du in der input.xml definiert hast.
Code:
<Spinner
        android:id="@+id/spinner2"
        android:layout_width="wrap_content"
        android:layout_height="32dp" />
Dort ist dein Spinner leer. Also wird er leer angezeigt.

Lösung:
Nachdem du dein Layout inflatet hast, musst du den Spinner dein input geben. D.h. [Pseudocode]:
Code:
// Hole Layout inflater
// hole Spinner vom Layout
// erstelle Items vom Spinner
// setzte items auf den Spinner
// setzte das View auf den aBuilder
Eine andere Möglichkeit wäre, die wahrhscienlich "schlechter ist", dass du nicht jedesmal dein Layout neu inflaterst sondern nur einmal.
D.h. [Pseudo]
Code:
// hole Layout beim Start der App
// hole den Spinner von der App
// erstelle items für den spinner
// setzte items für den Spinner
// halte das layout fest - als Klassenvariable

// Im AlertDialog must du dann nicht immer infaltern
// sondern kannst direkt das Layout setzten
Gruß
 
P

Patpa

Neues Mitglied
Danke, StefMa für deine Antwort! muss ehrlich zugeben so ganz verstehen tue ich es nicht. Denke mal ich muss die Methode in der ich meinen Spinner fülle integrieren? Werde es mal ausprobieren.
Gruß
Patpa
 
ui_3k1

ui_3k1

Gesperrt
Hey,
ich denke StefMa meint, dass du deinen AlertDialog an einen LayoutInflater übergeben sollst.
Über diesen wird via Code veranlasst dass das Layout angezeigt wird.
Vielleicht hilft dir dieses Beispiel auf die Sprünge. :smile:
 
P

Patpa

Neues Mitglied
Hallo StefMa und ui_3k1!
es funktioniert ja soweit, dass mein erstelltes Layout angezeigt wird. Auch mit den Buttons funktioniert alles wunderbar. Mein Problem ist wie zu vor immer noch mein Spinner welches leer bleibt. Hab jetzt mal versuch den PseudoCode von StefMa umzusetzen und hab jetzt mehr oder weniger den selben Aufbau wie in deinem Beispielquelltext nur habe ich die Zeile
Code:
View dialogView = inflater.inflate(R.layout.input, null);
weggelassen da ich diesen nicht verwende bzw. nicht weiß wofür ich diesen benötige. Brauch ich diesen? ist diese Zeile erforderlich?
An deiner Stelle wo du den Kommentar eingefügt hast "Spinner mit Items füllen" hab ich jetzt folgenden Quelltext
Code:
Set<BluetoothDevice> btDevices = btAdapter.getBondedDevices();
   	    	 List<String> list1 = new ArrayList<String>();
   	    	 Iterator<BluetoothDevice> btIt = btDevices.iterator();
   	    	 BluetoothDevice btDev = null;
   	    	 while (btIt.hasNext())
   	    	 { 
   	    	 	 btDev = btIt.next();
   	    		 list1.add(btDev.getName());
   	    	 }
   	    	 ArrayAdapter<String> Adapter1 = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, list1);
   		     Adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
   		     btspinner.setAdapter(Adapter1);
Kann das Projekt compilieren und starte es mittels USB-Debugging auf meinem Tablet. Startet auch nur sobald ich die Funktion im Menü aufrufe hängt er sich auf. Eclipse zeigt mir an, dass der Fehler bei
Code:
btspinner.setAdapter(Adapter1);
entsteht. Glaube die Fehlermeldung ist "suspended (exception nullpointer exception)". Weiß ehrlich gesagt nicht wo man die genaue Fehlermeldung angezeigt bekommt steht oben links unter Debug. Hab jetzt schon bissel rumprobiert und werde es natürlich auch weiterhin. Wenn ich die Zeile einfach auskommentiere kann ich das Layout über das Menü aufrufen bleibt der Spinner aber leer. Ich glaube ich entschuldige mich am besten mal an dieser Stelle für meine Inkompetenz :p. Wenn ihr mir sagen könntet was ich schon wieder falsch mache wäre ich euch sehr dankbar :)
 
StefMa

StefMa

Experte
Patpa schrieb:
nur habe ich die Zeile
Code:
View dialogView = inflater.inflate(R.layout.input, null);
weggelassen
Genau hier liegt das Problem ;)

Du bekommst auch dein Nullpointer, da du vwahrscheinlich mit
Code:
Spinner spinner = (Spinner) findViewById(R.id.spinnderId);
zrugreifst?!
Das ist selbstverständlich null. Weil er findet in deinem "Main-Layout" keine spinnerId. Diese befindet sich nämlich im Dialog-Layout. Und genau den bekommst du über das oben erstelle View! (Also über den dialogView).

Dann sollte es klappen.

Gruß
 
P

Patpa

Neues Mitglied
Ja, so ist es. Heißt das also für mich dass ich zuerst den dialogView definieren muss und dann erst über die ID den Spinner zuordnen kann? Danke werde es mal ausprobieren :)
 
StefMa

StefMa

Experte
Habe dir mal zum Verständniss ein Bildchen gemalt (Anhang).
Kurz erklärt:
Die Activity "zeigt" auf Layout 1. Dort ist kein Spinner enthalten!
In der Activity definierst du das View
Das View "zeigt" auf Layout Dialog. Dort ist der Spinner enthalen!

Somit kannst du mit dem View auf die Elemente vom Layout Dialog zugreifen.
Ansosten schaut deine Activity auf Layout 1 und bringt eben ein NUllPointer, weil dort kein Spinner enthalten ist.

Gruß
 

Anhänge

P

Patpa

Neues Mitglied
Funktioniert leider nicht. Da fehlt doch sicherlich noch irgendein Verweis oder sowas? weil er sagt mir ja das dialogView nicht verwendet wird. An welcher Stelle und wie muss ich diesen den einbauen? Am besten post ich nochmal meinen Quelltext

Code:
Builder builder1 = new AlertDialog.Builder(this);
   			 LayoutInflater inflater = this.getLayoutInflater();
   			 View dialogView = inflater.inflate(R.layout.input, null);
   			
   	    	 btspinner1 = (Spinner) findViewById(R.id.spinner2);
   	    	 
   	    	 Set<BluetoothDevice> btDevices = btAdapter.getBondedDevices();
   	    	 List<String> list1 = new ArrayList<String>();
   	    	 Iterator<BluetoothDevice> btIt = btDevices.iterator();
   	    	 BluetoothDevice btDev = null;
   	    	 while (btIt.hasNext())
   	    	 { 
   	    	 	 btDev = btIt.next();
   	    		 list1.add(btDev.getName());
   	    	 }
   	    	 ArrayAdapter<String> Adapter1 = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, list1);
   		     Adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
   		     btspinner1.setAdapter(Adapter1);
   		     
   		     builder1.setView(inflater.inflate(R.layout.input,  null));
Sry, falls ich mich wirklich blöd anstelle :/

Der ursprüngliche Beitrag von 13:30 Uhr wurde um 13:37 Uhr ergänzt:

Okay, kleiner Fortschritt mit
Code:
btspinner1 = (Spinner) dialogView.findViewById(R.id.spinner2);
hängt er sich immerhin nicht mehr auf aber Spinner bleibt leer schau jetzt mal ob es an meinem Quelltext liegt
 
StefMa

StefMa

Experte
Keine Ahnung was du da für Daten hast, aber versuch doch einfach mal eine einfache Liste zu erstellen und statische Daten einzutragen...
 
ui_3k1

ui_3k1

Gesperrt
Steinigt mich nicht, denn soooo viel Ahnung habe ich auch nicht. Aber seid ihr euch sicher, dass das mit dem "this" an diesen Stellen so okay ist? Bei mir entstehen da gerne mal Fehler...
 
P

Patpa

Neues Mitglied
Ups, jetzt sehe ich dass du genau das in deinem Beispiel Quelltext stehen hast.

Der ursprüngliche Beitrag von 14:34 Uhr wurde um 14:36 Uhr ergänzt:

hab mal ein einfaches Stingarray angelegt. Inhalt wird nicht angezeigt. Hab mal Breakpoints gesetzt in der list1 stehen alle gekoppelten Bluetoothgeräte. Hab in meinem "Layout1" also in der activity_main.xml den selben spinner noch einmal dort wird alles angezeigt.

Der ursprüngliche Beitrag von 14:36 Uhr wurde um 14:38 Uhr ergänzt:

also hab den Quelltext aus meinem ersten Post immer noch in meinem Projekt. Nur dass ich spinner1 im activity_main.xml definiert habe.
 
P

Patpa

Neues Mitglied
In deinem Quelltexthandelt es sich bei der onCreateDialog Methode um eine private void methode. ich hab eine protected. Kann es vielleicht daran liegen? hab den Quelltext jetzt weitestgehend übernommen und der Spinner bleibt leer.
 
P

Patpa

Neues Mitglied
Guten Morgen! :)
Nach ewig langem rumprobieren hab ich es jetzt endlich mit folgendem Quelltext zu laufen gebracht
Code:
protected Dialog onCreateDialog (int id) 
    {
   	 switch (id) 
   	 {
   	 case 10:
   		 Builder builder = new AlertDialog.Builder(this);
   		 builder.setMessage("Applikation wird geschlossen!");
   		 builder.setCancelable(true);
   		 builder.setPositiveButton("OK", new DialogInterface.OnClickListener() 
   		 {
   			 public void onClick(DialogInterface dialog, int which) 
   			 {
   				 unbindService(mConnection);
   				 MainActivity.this.finish();	 
   			 }
   		 });
   		 builder.setNegativeButton("Nein, doch nicht!", new DialogInterface.OnClickListener() 
   		 {
   			 public void onClick(DialogInterface dialog, int which) 
   			 {
   				 Toast.makeText(getApplicationContext(), "Applikation wird fortgesetzt", Toast.LENGTH_LONG).show();
   			 }
   		 }); 
   		 return builder.create();
   		 
   	 case 100:
   		LayoutInflater infl = MainActivity.this.getLayoutInflater();
        View dialogView = infl.inflate(R.layout.input, null);
        		        
        List<String> list2 =  new ArrayList<String>();
        Set<BluetoothDevice> btDevices = btAdapter.getBondedDevices();
    	Iterator<BluetoothDevice> btIt = btDevices.iterator();
    	BluetoothDevice btDev = null;
    	adresses.clear();
    	while (btIt.hasNext())
    	{ 
    		btDev = btIt.next();
    		list2.add(btDev.getName());
    		adresses.add(btDev.getAddress());
    	}
        		    
        ArrayAdapter<String> Adapter1 = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_spinner_item, list2);
        Adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        		    
        Spinner sp = (Spinner) dialogView.findViewById(R.id.spinner2);
        sp.setAdapter(Adapter1);
        		    
        AlertDialog.Builder aBuilder = new AlertDialog.Builder(MainActivity.this);
        aBuilder.setView(dialogView);	    
   		 
   			 aBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() 
   			 {
   				 public void onClick(DialogInterface dialog, int which) 
   				 {
   					 unbindService(mConnection);
   					 MainActivity.this.finish();	 
   				 }
   			 });
   			 aBuilder.setNegativeButton("Close", new DialogInterface.OnClickListener() 
   			 {
   			 public void onClick(DialogInterface dialog, int which) 
   			 {
   				 Toast.makeText(getApplicationContext(), "Applikation wird fortgesetzt", Toast.LENGTH_LONG).show();
   			 }
   			 
   			 }); 
   			aBuilder.create().show();
   	 	}
   	 	return super.onCreateDialog(id);
    }
Danke für eure Hilfe :) !!!!!
 
Ähnliche Themen - Layout für einen AlertDialog Antworten Datum
1