# ImageView wird nicht angezeigt



## Warrior7777 (12. Feb 2012)

Hallo miteinander!

Ich schreibe eine App, die folgende Elemente in einer ListView anzeigen soll:
-eine TextView
-eine ImageView
-3 Buttons

Die TextView wird angezeigt, aber die ImageView und die 3 Buttons nicht. Ich denke mal, das hat nichts  zu tun mit dem XML-File, aus dem ich die Listenelemente entfalte. Trotzdem hier noch der komplette Text:

```
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_height="match_parent"
	android:layout_width="match_parent"
	android:orientation="horizontal">
	
	<TextView android:id="@+id/textview"
		android:text=""
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
	/>
	
	<ImageView 	
		android:id="@+id/img"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:visibility="visible"
	/>
	<Button android:id="@+id/change1"
		android:text="@string/change"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
		android:visibility="visible"
	/>
	
	<Button android:id="@+id/change2"
		android:text="@string/delete"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
	/>
	
	<Button android:id="@+id/select"
		android:text="@string/select"
		android:layout_width="wrap_content"
		android:layout_height="wrap_content"
	/>
	
</LinearLayout>
```

Falls es das nicht ist, gehe ich davon aus, dass getView() meines Adapters den Fehler macht:

```
public View getView(int position, View convertView, ViewGroup parent) {
		//Build View
		Log.d(TAG, "getView(" + position + ", " + convertView + ", " + parent +")");
		if(convertView==null){
			convertView=inflator.inflate(R.layout.selection, null);
		}
		
		if(data!=null){
			//setText
			Log.d(TAG,  "data!=null");
			TextView textview=(TextView) convertView.findViewById(R.id.textview);
			String text=context.getString(R.string.img_name /*, position.toString()*/);
			
			Log.d(TAG, "textview.setText()");
			textview.setText(text);
			
			//getImage
			Bitmap img=null;
			if(getItem(position)!=null){
				img=((WallpaperSelection)getItem(position)).getImg();
				Log.d(TAG, "img geladen.");
			}
			
			//setImage
			if(img!=null){
				ImageView imageview=(ImageView) convertView.findViewById(R.id.img);
				imageview.setImageBitmap(img);
				Log.d(TAG, "imageview.setImageBitmap(img)");
			}else{
				ImageView imageview=(ImageView) convertView.findViewById(R.id.img);
				imageview.setImageResource(R.drawable.ic_launcher);
				Log.d(TAG, "imageview.setImageResource(R.drawable.ic_launcher)");
			}
			
			//set Listeners
			Log.d(TAG, "Change Button");
			Button buttonc=(Button) convertView.findViewById(R.id.change1);
			buttonc.setOnClickListener(new OnClickListener(){
				public void onClick(View v){
					//change this image
				}
			});
			
			Log.d(TAG, "Delete Button");
			Button buttond=(Button) convertView.findViewById(R.id.change2);
			buttond.setOnClickListener(new OnClickListener(){
				public void onClick(View v){
					//delete this image
				}
			});
			
			Log.d(TAG, "New Button");
			Button buttonn=(Button) convertView.findViewById(R.id.select);
			buttonn.setOnClickListener(new OnClickListener(){
				public void onClick(View v){
					//insert new image after this one
				}
			});
			
			//return the view
			Log.d(TAG, "return convertView");
			return convertView;
		}else{
			//not possible
			return null;
		}
	}
```
Entschuldigung wegen des vielen Textes; ich weiss einfach nicht mehr weiter. Besser zu viel als zu wenig Infos.  Ich bin sehr froh und dankbar für jede hilfreiche Antwort!
Noch ein schönes Rest-Wochenende!


----------



## Holger (13. Feb 2012)

Also wenn ich das richtig verstehe wird dir lediglich der Text angezeigt der in dem TextView steht?

Wenn du das Programm durchlaufen lassen hast, was steht dann in deinem Log. Durch dein logging könntest du ja schon einmal in Erfahrung bringen ob er überhaupt in die If-Schleife für das Image springt.

Bin gerade etwas kurz angebunden seh mir das später nochmal genau an, wäre aber cool wenn du eben noch das Log posten könntest.

Gruß Holger


----------



## Warrior7777 (13. Feb 2012)

Ja, das hast Du richtig verstanden: Nur die TextView wird angezeigt, aber die Buttons und die ImageView nicht.  Danke für die Antwort, Du hast natürlich recht mit den Log-Ausgaben. Hier sind sie:

```
02-13 09:41:04.751: D/Adapter(269): WallpaperChangerAdapter()
02-13 09:41:04.861: D/Adapter(269): getCount()
02-13 09:41:04.861: D/Adapter(269): getCount()
02-13 09:41:04.892: D/Adapter(269): getCount()
02-13 09:41:04.892: D/Adapter(269): getItemId(0)
02-13 09:41:04.892: D/Adapter(269): getItemId(0)
02-13 09:41:04.961: D/Adapter(269): getCount()
02-13 09:41:05.072: D/Adapter(269): getCount()
02-13 09:41:05.123: D/Adapter(269): getItemId(0)
02-13 09:41:05.123: D/Adapter(269): getCount()
02-13 09:41:05.131: D/Adapter(269): getItemId(0)
02-13 09:41:05.131: D/Adapter(269): getView(0, null, android.widget.ListView@44ef2b90)
02-13 09:41:05.291: D/Adapter(269): data!=null
02-13 09:41:05.291: D/Adapter(269): textview.setText()
02-13 09:41:05.291: D/Adapter(269): getItem(0)
02-13 09:41:05.301: D/Adapter(269): imageview.setImageResource(R.drawable.ic_launcher)
02-13 09:41:05.301: D/Adapter(269): Change Button
02-13 09:41:05.301: D/Adapter(269): Delete Button
02-13 09:41:05.332: D/Adapter(269): New Button
02-13 09:41:05.332: D/Adapter(269): return convertView
02-13 09:41:05.391: D/Adapter(269): getItemId(0)
02-13 09:41:05.391: D/Adapter(269): getCount()
02-13 09:41:05.391: D/Adapter(269): getCount()
02-13 09:41:05.391: D/Adapter(269): getItemId(0)
02-13 09:41:05.431: D/Adapter(269): getItemId(0)
```
Zuerst hab ich noch eine Ausgabe für den Konstruktur des Adapters ausgeben lassen, danach für die Callbacks und sonstigen Anweisungen.
Bei den Buttons habe ich keine Ahnung, was falsch ist. Bei der ImageView auch nicht, deshalb hab ich ja das Standard-Bild genommen, das angezeigt werden sollte, wenn noch kein Bild ausgewählt wurde. Das Auswählen sollte mit Hilfe der Buttons geschehen.


----------



## Holger (13. Feb 2012)

Also ich war vorhin etwas unaufmerksam. Und zwar liegt das Problem soweit ich das jetzt sehe in der XML Datei. Du hast dem LinearLayout das Attribut width auf match_parent gesetzt und das von dem TextView auch auf fill_parent. Diese beiden Attribvute sind equivalent. Das Problem was du nun hast ist das der TextView die ganze Breite ferwendet die der View zur Verfügung stellt. Also überdeckt der TextView Buttons und Bild. Ändere das mal auf wrap_content dann sollte es eigentlich funktionieren.

Gruß
Holger


----------



## Holger (13. Feb 2012)

Und für die Höhe könntest du eventuell am besten das Attribut so setzten:

[XML]
android:layout_height="?android:attr/listPreferredItemHeight"
[/XML]


----------



## Warrior7777 (13. Feb 2012)

Ok vielen Dank, es funktioniert! :applaus: Trotzdem hab ich noch eine Frage: Kann man mit einem LinearLayout die einzelnen Elemente untereinander anzeigen oder sollte man da besser ein RelativeLayout verwenden?


----------



## Warrior7777 (13. Feb 2012)

Ich seh gerade, dass ein Button fehlt.  Wahrscheinlich passt der einfach nicht mehr auf den Bildschirm...


----------



## Holger (13. Feb 2012)

Also zu dem untereinander darstellen löse ich das indem ich zwei linealayouts schachtel, in etwa so
[XML]
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    androidrientation="horizontal">
                            <LinearLayout
                                xmlns:android="http://schemas.android.com/apk/res/android"
                                android:layout_height="match_parent"
                                android:layout_width="match_parent"
                                androidrientation="vertical">
                             </LinearLayout>

</LinearLayout>
[/XML]

Dann packst die View's die untereinander angezeigt werden sollen in den zweiten LinearLayout.

Wenn du in Eclipse porgrammierst kannst du dir die Layouts im Graphical Layout anschauen. Dort siehst du wie diese in etwas dargestellt werden. 

Falls es wirklich auf Grund des Platzes nicht passt, könntest du versuchen die einzelnen Elemente von der Größe etwas anzupassen das das list item alle Elemente darstellen kann


----------



## Holger (13. Feb 2012)

Weiße allen Elementen einfach mal das Attribut, aber nicht dem LinearLayout
[XML]android:layout_weight="0.2"[/XML] zu dann teilen sich alle 5 Elemente den Bereich. Je nach dem wie du diesen wert bei den einzelnen Elementen veränderst ändert sich die Größe der Views.
Desto größer der Wert bei einem Element ist desto mehr Platz nnimmt dieser View ein. Die Werte sollen in der Addition immer 1 ergeben


----------



## Warrior7777 (13. Feb 2012)

Ich habe jetzt ein anderes Problem: Wie bringt man eine ListView dazu, sich neu zu zeichnen? Ich hab mal onContentChanged überschrieben. Die Liste wird nicht mehr angezeigt, aber die aktualisierte Liste erscheint nicht...
Hier der Code zum auslösenden Button:

```
public void onClick(View v){
					//delete this image
					Log.d(TAG, "delete image");
		
					WallpaperSelection removed=data.remove(this.position);
					listactivity.save(data);
					listactivity.onContentChanged();
					Log.d(TAG, removed+" deleted.");
				}
			});
```
Und hier onContentChanged:

```
public void onContentChanged(){
    	super.onContentChanged();
    	Log.d(TAG, "onContentChanged");
    	
    	data=load();
    	if(data!=null){
    		data=defaultData();
        	save(data);
    	}
    	lv=getListView();
    }
```


----------



## Warrior7777 (13. Feb 2012)

Hier noch die Logausgabe:

```
02-13 15:19:07.221: D/WallpaperChangerActivity(274): onCreate()
02-13 15:19:07.221: D/WallpaperChangerActivity(274): load()
02-13 15:19:07.272: D/WallpaperChangerActivity(274): Fehler im ObjectInputStream.
02-13 15:19:07.272: D/WallpaperChangerActivity(274): java.io.EOFException
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at java.io.DataInputStream.readShort(DataInputStream.java:375)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:2388)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at java.io.ObjectInputStream.<init>(ObjectInputStream.java:445)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at renato.bellotti.wallpaperchanger.WallpaperChangerActivity.load(WallpaperChangerActivity.java:69)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at renato.bellotti.wallpaperchanger.WallpaperChangerActivity.onCreate(WallpaperChangerActivity.java:31)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at android.app.ActivityThread.access$2300(ActivityThread.java:125)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at android.os.Handler.dispatchMessage(Handler.java:99)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at android.os.Looper.loop(Looper.java:123)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at android.app.ActivityThread.main(ActivityThread.java:4627)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at java.lang.reflect.Method.invokeNative(Native Method)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at java.lang.reflect.Method.invoke(Method.java:521)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
02-13 15:19:07.272: D/WallpaperChangerActivity(274): 	at dalvik.system.NativeStart.main(Native Method)
02-13 15:19:07.292: D/WallpaperChangerActivity(274): defaultData()
02-13 15:19:07.292: D/WallpaperChangerActivity(274): save()
02-13 15:19:07.372: D/Adapter(274): WallpaperChangerAdapter()
02-13 15:19:07.442: D/WallpaperChangerActivity(274): onContentChanged
02-13 15:19:07.453: D/WallpaperChangerActivity(274): load()
02-13 15:19:07.471: D/WallpaperChangerActivity(274): defaultData()
02-13 15:19:07.471: D/WallpaperChangerActivity(274): save()
02-13 15:19:07.492: D/Adapter(274): getCount()
02-13 15:19:07.492: D/Adapter(274): getCount()
02-13 15:19:07.492: D/Adapter(274): getCount()
02-13 15:19:07.492: D/Adapter(274): getItemId(0)
02-13 15:19:07.512: D/Adapter(274): getItemId(0)
02-13 15:19:07.571: D/Adapter(274): getCount()
02-13 15:19:07.661: D/Adapter(274): getCount()
02-13 15:19:07.692: D/Adapter(274): getItemId(0)
02-13 15:19:07.692: D/Adapter(274): getCount()
02-13 15:19:07.692: D/Adapter(274): getItemId(0)
02-13 15:19:07.692: D/Adapter(274): getView(0, null, android.widget.ListView@44f00380)
02-13 15:19:07.741: D/Adapter(274): data!=null
02-13 15:19:07.753: D/Adapter(274): textview.setText()
02-13 15:19:07.761: D/Adapter(274): getItem(0)
02-13 15:19:07.761: D/Adapter(274): imageview.setImageResource(R.drawable.ic_launcher)
02-13 15:19:07.761: D/Adapter(274): Change Button
02-13 15:19:07.771: D/Adapter(274): Delete Button
02-13 15:19:07.771: D/Adapter(274): New Button
02-13 15:19:07.771: D/Adapter(274): return convertView
02-13 15:19:07.791: D/Adapter(274): getItemId(0)
02-13 15:19:07.791: D/Adapter(274): getCount()
02-13 15:19:07.791: D/Adapter(274): getCount()
02-13 15:19:07.791: D/Adapter(274): getItemId(0)
02-13 15:19:07.801: D/Adapter(274): getItemId(0)
02-13 15:19:07.951: I/ActivityManager(59): Displayed activity renato.bellotti.wallpaperchanger/.WallpaperChangerActivity: 1636 ms (total 24163 ms)
02-13 15:19:07.951: I/ActivityManager(59): Displayed activity com.android.launcher/com.android.launcher2.Launcher: 24164 ms (total 24164 ms)
02-13 15:19:08.371: D/MediaScanner(212):  prescan time: 560ms
02-13 15:19:08.371: D/MediaScanner(212):     scan time: 1ms
02-13 15:19:08.382: D/MediaScanner(212): postscan time: 2621ms
02-13 15:19:08.382: D/MediaScanner(212):    total time: 3182ms
02-13 15:19:08.421: D/MediaScannerService(212): done scanning volume external
02-13 15:19:13.251: D/KeyguardViewMediator(59): pokeWakelock(5000)
02-13 15:19:13.701: D/KeyguardViewMediator(59): pokeWakelock(5000)
02-13 15:19:13.842: D/Adapter(274): getCount()
02-13 15:19:14.121: I/ARMAssembler(59): generated scanline__00000077:03545404_00000004_00000000 [ 47 ipp] (67 ins) at [0x3010b8:0x3011c4] in 1100048 ns
02-13 15:19:14.211: I/ARMAssembler(59): generated scanline__00000177:03515104_00001001_00000000 [ 91 ipp] (114 ins) at [0x3011c8:0x301390] in 764982 ns
02-13 15:19:49.342: D/Adapter(274): delete image
02-13 15:19:49.342: D/WallpaperChangerActivity(274): save()
02-13 15:19:49.361: D/Adapter(274): getCount()
02-13 15:19:49.361: D/Adapter(274): getCount()
02-13 15:19:49.361: D/WallpaperChangerActivity(274): onContentChanged
02-13 15:19:49.361: D/WallpaperChangerActivity(274): load()
02-13 15:19:49.371: D/WallpaperChangerActivity(274): defaultData()
02-13 15:19:49.371: D/WallpaperChangerActivity(274): save()
02-13 15:19:49.382: D/Adapter(274): renato.bellotti.wallpaperchanger.WallpaperSelection@44eed138 deleted.
02-13 15:19:49.392: D/Adapter(274): getCount()
```


----------



## schlingel (13. Feb 2012)

Wie sieht denn aktuell dein Layout-XML-File aus? Wenn du noch immer der ersten View die komplette Breite deines Fensters gibst und horizontal Layout ausgewählt hast, ist es klar, dass man nichts sieht da die ganze Breite dann dem ersten Element gehört.

Zeichne doch einmal wie du dir das Layout vorstellst und wir posten wie man das am besten umsetzt.


----------



## Warrior7777 (13. Feb 2012)

So sollte ein Element der ListView aussehen.


----------



## schlingel (15. Feb 2012)

Hm, das ist wahnsinnig gedrängt für ein Element einer Listview. Zum einen würde hier besser ein Gridview passen, wenn du tatsächlich nur Bilder anzeigst und zum anderen würde ich die Nummerierung als Overlay oben rechts in die Ecke des Bildes packen und die Optionen bei einem Click auf's Bild anzeigen.

Die Anzeige sollte man dann entweder mit einem Dialog oder mit einer QuickAction lösen. Dann wäre dein Layout auch nicht so gedrängt. Ich wollte sowieso in den nächsten Tagen ein kleines ImageGallery-Projekt auf Github veröffentlichen (man findet nämlich kaum brauchbare Lösungen!), wenn du möchtest bau ich dir so eine Ansicht ein.

Falls du trotzdem ein Layout verwenden möchtest, schreib ich dir am Abend hier rein wie man das am besten löst.


----------



## Holger (15. Feb 2012)

Hey Schlingel,

das mit der Veröffentlichung finde ich super. Wärst du so nett und würdest den Link dann später hier posten oder eben per PN schicken. 

Gruß
Holger


----------



## Warrior7777 (16. Feb 2012)

Vielen Dank für die Mühe! Ich hab die Darstellung untereinander hingekriegt. (Der Fehler war, dass ich in <LinearLayout> layout_orientation="horizontal" ansatt "vertical" gesetzt habe.) Leider habe ich noch ein kleines Problem: Wie befüllt man die Parameter einer String-Ressource?


----------



## schlingel (16. Feb 2012)

Was meinst du?

Du packst deine Parameter, sofern es Sinn macht, in dein string.xml und verlinkst es dann im File mittels:

[XML]
  <TextView
      <!-- fill in layout zeugs -->
      android:text="@string/deineResource" />
[/XML]

Aber du willst ja ein Listen- bzw. Grid-Element befüllen, also musst du dir einen Adapter schreiben der in der getView-Methode die entsprechende View auf den Wert setzt.


----------



## Warrior7777 (16. Feb 2012)

Das ist mir schon klar, ich meinte aber sowas: %1d
Wie befühlt man diese Parameter im String selbst?


----------



## schlingel (17. Feb 2012)

Innerhalb des Adapters:


```
deineTextView.setText(String.format(getContext().getResources().getString(R.string.deinFormatString), deinInt));
```

oder was genau meinst du jetzt?


----------



## Warrior7777 (17. Feb 2012)

Genau das hab ich gemeint! Also, nur damit ich das richtig verstanden habe: man benutzt die statische Methode format(). Der erste Parameter ist die String-Ressource, die folgenden die zu befüllenden "Lücken". Vielen Dank!


----------

