Tutorial .xml Layouting für z.B ListView elemente

kaoZ

Top Contributor
Aloha, ich suche ein gutes Tutorial zum designen von Views unter verwendung von .xml Dateien mit android.

Gern auch mit einer detaillierten Einführung in .xml Dateien und deren Aufbau.

Prinzipiell geht es mir darum zu verstehen wie ich z.B ListView Einträge unter der Verwendung einer selber erstellten .xml Datei anpassen kann.

Wenn ich in einem neuen Android eine neue .xml Datei anlegen und ein Layout verwende ( z.B Lineares Layout) nimmt dieses ja immer den kompletten Screen ein .

Ich vermute ich muss auf einen LayoutInflater zurückgreifen , bin mir aber nicht sicher, wäre super wenn jemand ein guten Tutorial kennt und mir nen Link oder auch gern ein Buch darüber vorschlagen könnte :)

:rtfm:
 
Zuletzt bearbeitet:

dzim

Top Contributor
Wenn ich es richtig verstehe, ist der konkrete Use-Case ein ListView, oder? Hier wirst du im dazugehörigen Adapter nicht um den Inflater herumkommen. Klappt bei mir aber wunderbar (auch bei Listen von 10'000 Einträgen aus einer DB).
Ein einzelnes Tutorial, dass dir alles erklärt, wirst du (leider) nicht finden - ich habe Lars Vogels Tutorials genutzt, wobei die häufig nur der Einstiegspunkt waren. Konkrete Probleme habe ich dann meist mit Google-suche, oder - wenn möglich - StackOverflow geklärt.

Grundsätzlich muss ein (Basis-)Layout nicht immer die ganze Seite einer Activity oder eines Fragments, etc., einnehmen. Wie jedes andere hat es die Attribute für die layout_width und _height - wie gut das in der Praxis dann funktioniert, ist eine andere Sache und auch nach 1.5 Jahren Android ist mir noch nicht immer alles sofort klar und muss noch häufig suchen (vor allem, wenn man nicht ausschliesslich Android entwickelt).

Aber bitte erläutere doch einmal dein konkretes Problem etwas näher. Was genau bereitet dir im Moment noch Kopfzerbrechen?
 

kaoZ

Top Contributor
Danke erstmal ,

ich habe eine Listview , in welcher ich 4 Verschiedene Strings darstelle, dazu nutze ich zzt. das Layout Simple_List_item1,

ich würde gerne selber festlegen wie dieses Layout aussehen soll, ich habe bereits gelesen das dies über einen LayoutInflater in verbindung mit einer .xml Datei machbar ist und das Design bzw. der Aufbau des Layouts dazu eben wie für jedes andere layout in einer .xml datei festgelegt wird,

da ich bislang noch nicht wirklich mit xml dateien gearbeitet habe ( bis auf die "vollständigen" layouts für die einzelnen Activitys)

suche ich halt ein Tutorial oder ähnliches wo ich mir nochmal anschauen kann wie man die xml Datei richtig aufbaut (bzw. für solche fälle verwendet) , und diese dann anschließend in Android in über den Inflater o.ä als Layout für die Elemente nutzen kann.
 

dzim

Top Contributor
Ich zeige es dir am besten an dem konkreten Beispiel (Achtung, das ist 1:1 kopiert und vielleicht etwas komplexer...):
[XML]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:eek:rientation="vertical" >

<!-- musste kürzen -->

<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:cacheColorHint="#00000000"
android:choiceMode="singleChoice"
android:fadeScrollbars="false"
android:fastScrollEnabled="true"
android:listSelector="@drawable/result_list_selector"
android:scrollbarAlwaysDrawVerticalTrack="true" />

<!-- musste kürzen -->

</LinearLayout>
[/XML]
Wichtig ist das
Code:
android:id="@android:id/list"
- kennst du sicher schon: So kann man ein ListFragment verwenden und muss nicht mehr die Liste selbst aus dem View heraussuchen.

Die Children eines LinearLayout nehmen nicht notwendigerweise den vollen Platz ein (ich glaube,
Code:
match_parent
bei der Höhe der Liste, würde andere Widgets verdrängen). Daher wird hier die Variante von
Code:
0dp
Höhe und einem
Code:
layout_weight
von 1 gearbeitet.

Beim Fragment is jetzt wichtig, dass es ein ListFragment extended:
Java:
public class ResultFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {

[...]

	private TextView tvHeader;
	private ProgressBar progressStats;
	private TextView tvData;
	private TextView tvAvgRates;
	private TextView tvCount;
	private TextView tvFooterInfo;
	
	private View sep;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		
		View view = inflater.inflate(R.layout.fragment_history, container, false);
		
		[...]

		sep = view.findViewById(R.id.sep);
		tvHeader = (TextView) view.findViewById(R.id.fragment_header);
		
		progressStats = (ProgressBar) view.findViewById(R.id.progressBar_stats);
		tvCount = (TextView) view.findViewById(R.id.historyCount);
		tvAvgRates = (TextView) view.findViewById(R.id.historyAvg);
		tvData = (TextView) view.findViewById(R.id.historyData);
		tvFooterInfo = (TextView) view.findViewById(R.id.fragment_footer_info);
		
		[...]
		
		ImageButton ibSort = (ImageButton) view.findViewById(R.id.history_sort);
		ImageButton ibFilter = (ImageButton) view.findViewById(R.id.history_filter);
		
		if (ibSort != null) {
			ibSort.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					showSortDialog();
				}
			});
		}
		if (ibFilter != null) {
			ibFilter.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					showFilterDialog();
				}
			});
		}
		
		updateText();
		
		return view;
	}

[...]

private ResultCursorAdapter adapter;
	
	@SuppressWarnings("unchecked")
	@Override
	public Loader<Cursor> onCreateLoader(int id, Bundle args) {
		
		String[] projection = { ResultTable.Cols._ID, ResultTable.Cols.TIMESTAMP, ResultTable.Cols.SERIES_ID, ResultTable.Cols.TEST_ID,
				ResultTable.Cols.SPEED_DOWN, ResultTable.Cols.SPEED_UP, ResultTable.Cols.SPEED_UP_CLIENT, ResultTable.Cols.RTT, ResultTable.Cols.SERVER_NAME,
				ResultTable.Cols.LOCATION, ResultTable.Cols.CONNECTION, ResultTable.Cols.SUCCESS, ResultTable.Cols.ERROR_MESSAGE };
		
		Object[] filterOptions = SpeedTestDBAccess.createFilterOptions(filterEnums, filterSeries, errorFilter, filterServer);
		String sort = SpeedTestDBAccess.getSortString(currentSorting, sortOrder);
		
		CursorLoader cursorLoader = new CursorLoader(getActivity(), ResultTable.CONTENT_URI, projection, (filterOptions == null ? null
				: (String) filterOptions[0]), (filterOptions == null ? null : ((List<String>) filterOptions[1]).toArray(new String[] {})), sort);
		return cursorLoader;
	}
	
	@Override
	public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
		adapter.swapCursor(cursor);
	}
	
	@Override
	public void onLoaderReset(Loader<Cursor> loader) {
		adapter.swapCursor(null);
	}
	
	public void restartOrStopLoader(boolean stop) {
		if (stop)
			ResultFragment.this.getLoaderManager().destroyLoader(0x01);
		else
			ResultFragment.this.getLoaderManager().restartLoader(0x01, null, ResultFragment.this);
	}
	
	private void restartLoader() {
		ResultFragment.this.getLoaderManager().restartLoader(0x01, null, ResultFragment.this);
	}
	
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		
		super.onActivityCreated(savedInstanceState);
		
		final String[] uiBindFrom = new String[] { ResultTable.Cols.TIMESTAMP, ResultTable.Cols.SERIES_ID, ResultTable.Cols.TEST_ID,
				ResultTable.Cols.SPEED_DOWN, ResultTable.Cols.SPEED_UP, ResultTable.Cols.SPEED_UP_CLIENT, ResultTable.Cols.RTT, ResultTable.Cols.SERVER_NAME,
				ResultTable.Cols.LOCATION, ResultTable.Cols.CONNECTION };
		final int[] uiBindTo = new int[] { R.id.HC_Date, R.id.HC_Time, R.id.HC_Ids, R.id.HC_Icon, R.id.HC_Download, R.id.HC_Upload, R.id.HC_RTT,
				R.id.HC_Server, R.id.HC_Location, R.id.HC_Connection };
		
		ResultFragment.this.setListAdapter(null);
		// this.getListView().addHeaderView(headerView);
		
		if (ResultFragment.this.adapter == null) {
			ResultFragment.this.adapter = new ResultCursorAdapter(getActivity(), null, uiBindFrom, uiBindTo, 0);
		}
		
		ResultFragment.this.setListAdapter(adapter);
		ResultFragment.this.getLoaderManager().initLoader(0x01, null, ResultFragment.this);
		
		ResultFragment.this.getListView().setOnItemLongClickListener(new OnItemLongClickListener() {
			@Override
			public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
				if ((adapter == null) || (adapter.getCursor() == null)) {
					return false;
				}
				// do something
				return true;
			}
		});
	}
	
	private View currentSelectedView = null;
	
	@Override
	public void onListItemClick(ListView l, View v, int position, long id) {
		
		if ((adapter == null) || (adapter.getCursor() == null)) {
			return;
		}
		
		super.onListItemClick(l, v, position, id);
		
		if (currentSelectedView != null)
			currentSelectedView.setSelected(false);
		currentSelectedView = v;
		currentSelectedView.setSelected(true);
		
		if (SpeedTestConstants.PREF_DEFAULT_LONG == id) {
			return;
		}
		
		FragmentManager fm = getFragmentManager();
		DetailsDialogFragment detailsDialog = new DetailsDialogFragment();
		Bundle args = new Bundle();
		args.putLong(ResultTable.Cols._ID, id);
		detailsDialog.setArguments(args);
		detailsDialog.show(fm, null);
	}

}
Das ist ein Auszug aus dem Fragment-Code - ich habe versucht es soweit zu bereinigen, dass es wenigstens halbwegs übersichtlich bleibt... Nicht, dass das wirklich gelungen ist :-/

Als nächstes kommt das Layout der Listen-Items:
[XML]
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/result_row"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/result_list_selector"
android:stretchColumns="4,5" >

<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >

<TextView
android:id="@+id/HC_Ids"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="6dp"
android:layout_marginRight="5dp"
android:text="@string/historyIds"
android:textColor="@color/list_textcolor_selector"
android:textSize="13sp"
android:textStyle="bold" >
</TextView>

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="5dp"
android:contentDescription="@string/historyNull" />

<ImageView
android:id="@+id/HC_icon_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="5dp"
android:contentDescription="@string/historyDownload"
android:src="@drawable/arrow_down" />

<TextView
android:id="@+id/HC_Download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="5dp"
android:text="@string/historyDownload"
android:textColor="@color/list_textcolor_selector"
android:textSize="13sp" >
</TextView>

<TextView
android:id="@+id/HC_Server"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="6dp"
android:layout_weight="1"
android:gravity="right|center_vertical"
android:text="@string/historyServer"
android:textColor="@color/list_textcolor_selector"
android:textSize="13sp" >
</TextView>
</TableRow>

<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<TextView
android:id="@+id/HC_Date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="6dp"
android:layout_marginRight="5dp"
android:text="@string/historyDate"
android:textColor="@color/list_textcolor_selector"
android:textSize="13sp" >
</TextView>

<ImageView
android:id="@+id/HC_Icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="5dp"
android:contentDescription="@string/historyConnectionType" />

<ImageView
android:id="@+id/HC_icon_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="5dp"
android:contentDescription="@string/historyUpload"
android:src="@drawable/arrow_up" />

<TextView
android:id="@+id/HC_Upload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="5dp"
android:text="@string/historyUpload"
android:textColor="@color/list_textcolor_selector"
android:textSize="13sp" >
</TextView>

<TextView
android:id="@+id/HC_Location"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="6dp"
android:layout_weight="1"
android:gravity="right|center_vertical"
android:text="@string/historyLocation"
android:textColor="@color/list_textcolor_selector"
android:textSize="13sp" >
</TextView>
</TableRow>

<TableRow
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<TextView
android:id="@+id/HC_Time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="6dp"
android:layout_marginRight="5dp"
android:text="@string/historyTime"
android:textColor="@color/list_textcolor_selector"
android:textSize="13sp" >
</TextView>

<ImageView
android:id="@+id/HC_icon_upload_to_server_failed"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="5dp"
android:contentDescription="@string/historyNull" />

<ImageView
android:id="@+id/HC_icon_rtt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="5dp"
android:contentDescription="@string/historyRTT"
android:src="@drawable/arrow_up_down" />

<TextView
android:id="@+id/HC_RTT"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="5dp"
android:minWidth="80sp"
android:text="@string/historyRTT"
android:textColor="@color/list_textcolor_selector"
android:textSize="13sp" >
</TextView>

<TextView
android:id="@+id/HC_Connection"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginRight="6dp"
android:layout_weight="1"
android:gravity="right|center_vertical"
android:text="@string/historyConnection"
android:textColor="@color/list_textcolor_selector"
android:textSize="13sp" >
</TextView>
</TableRow>

</TableLayout>
[/XML]
Das ist recht Straight-Forward. Baue den genau so, also wolltest du eine ganze Seite damit füllen - am besten zentriere den Content und checke es immer wieder mal im Preview. Dieses XML hier ist recht alt (aus einer nicht von mir geschriebenen Vorgängerversion der Anwendung) und macht immer wieder Probleme, wenn es nur noch wenig Platz auf dem Bildschirm hat. Aber für alle normale Geräte (Tablets mit Tablet-UI und Phones mit Phone-UI) sieht es gut. Erst Tablet-UI auf Phone sieht wirklich bescheuert aus.

Jetzt das wichtigste: Der "ResultCursorAdapter", der oben im Code war. Hier kannst du den Inflater verwenden - musst du aber nicht zwingenderweise, wenn du im Konstruktor des Adapters dein XML angibst - dann inflated Android es für dich und du musst es "nur" noch updaten.

Java:
public class ResultCursorAdapter extends SimpleCursorAdapter {
	
	private int sortby = 0;
	
	public void setSortById(int id) {
		sortby = id;
	}
	
	private final Typeface bold;
	private final Typeface boldItalic;
	
	public ResultCursorAdapter(Context context, Cursor c, String[] from, int[] to, int flags) {
		
		super(context, R.layout.result_row, c, from, to, flags);
		
		bold = Typeface.create(Typeface.DEFAULT, Typeface.BOLD);
		boldItalic = Typeface.create(Typeface.DEFAULT, Typeface.BOLD_ITALIC);
	}

	private Set<Long> selection = null;
	
	public Set<Long> getSelection() {
		if (selection == null) {
			selection = new HashSet<Long>();
		}
		return selection;
	}
	
	public void setSelection(Set<Long> selection) {
		this.selection = selection;
	}
	
	public Set<Long> addSelection(Long selection) {
		if (this.selection == null) {
			this.selection = new HashSet<Long>();
		}
		if ((selection == null) || (selection < 1)) {
			return this.selection;
		}
		this.selection.add(selection);
		return this.selection;
	}
	
	// XXX Hack of the week...
	private static final int rid = Resources.getSystem().getIdentifier("btn_check_holo_dark", "drawable", "android");
	
	@SuppressWarnings(value = { "unused" })
	@Override
	public void bindView(View view, Context context, Cursor cursor) {
		
		TextView ids = (TextView) view.findViewById(R.id.HC_Ids);
		TextView date = (TextView) view.findViewById(R.id.HC_Date);
		TextView time = (TextView) view.findViewById(R.id.HC_Time);
		
		ImageView icon = (ImageView) view.findViewById(R.id.HC_Icon);
		ImageView iconDown = (ImageView) view.findViewById(R.id.HC_icon_down);
		ImageView iconUp = (ImageView) view.findViewById(R.id.HC_icon_up);
		ImageView iconRtt = (ImageView) view.findViewById(R.id.HC_icon_rtt);
		ImageView iconServer = (ImageView) view.findViewById(R.id.HC_icon_upload_to_server_failed);
		
		TextView download = (TextView) view.findViewById(R.id.HC_Download);
		TextView upload = (TextView) view.findViewById(R.id.HC_Upload);
		TextView rtt = (TextView) view.findViewById(R.id.HC_RTT);
		
		TextView server = (TextView) view.findViewById(R.id.HC_Server);
		TextView location = (TextView) view.findViewById(R.id.HC_Location);
		TextView conn = (TextView) view.findViewById(R.id.HC_Connection);
		
		ids.setTypeface(bold);
		download.setTypeface(Typeface.DEFAULT);
		upload.setTypeface(Typeface.DEFAULT);
		rtt.setTypeface(Typeface.DEFAULT);
		
		// First Column
		long timestamp = cursor.getLong(cursor.getColumnIndex(ResultTable.Cols.TIMESTAMP));
		Calendar cal = new GregorianCalendar();
		cal.setTimeInMillis(timestamp);
		date.setText(String.format("%tF", cal));
		time.setText(String.format("%tH:%tM", cal, cal));
		ids.setText(context.getString(R.string.test_format, cursor.getInt(cursor.getColumnIndex(ResultTable.Cols.SERIES_ID)),
				cursor.getInt(cursor.getColumnIndex(ResultTable.Cols.TEST_ID))));
		
		// Second Column
		long down = cursor.getLong(cursor.getColumnIndex(ResultTable.Cols.SPEED_DOWN));
		String downSpeed = SpeedFormatter.formatSpeed(context, down);
		if (SpeedFormatter.emptyString(context) != downSpeed) {
			download.setText(context.getString(R.string.average) + SpeedTestConstants.ONESPACE_STRING + downSpeed);
		} else {
			download.setText(downSpeed);
		}
		
		long up = cursor.getLong(cursor.getColumnIndex(ResultTable.Cols.SPEED_UP));
		long upClient = cursor.getLong(cursor.getColumnIndex(ResultTable.Cols.SPEED_UP_CLIENT));
		String upSpeed = SpeedFormatter.formatSpeed(context, (up > 0 ? up : upClient > 0 ? upClient : SpeedTestConstants.PREF_DEFAULT_INTEGER));
		if (SpeedFormatter.emptyString(context) != upSpeed) {
			upload.setText(context.getString(R.string.average) + SpeedTestConstants.ONESPACE_STRING + upSpeed);
		} else {
			upload.setText(upSpeed);
		}
		
		if (cursor.getInt(cursor.getColumnIndex(ResultTable.Cols.RTT)) > 0) {
			// TODO if we use nanoseconds use the formatTime method
			rtt.setText(context.getString(R.string.average) + SpeedTestConstants.ONESPACE_STRING
					+ TimeFormatter.formatTimeDeleteIt(context, cursor.getInt(cursor.getColumnIndex(ResultTable.Cols.RTT))));
		} else {
			rtt.setText(context.getString(R.string.notAvailable));
		}
		
		// Third Column
		server.setText(cursor.getString(cursor.getColumnIndex(ResultTable.Cols.SERVER_NAME)));
		LocationEnum loc = LocationEnum.findByKey(cursor.getString(cursor.getColumnIndex(ResultTable.Cols.LOCATION)));
		location.setText(loc != null ? loc.getLabel(context) : SpeedTestConstants.EMPTY_STRING);
		
		conn.setText(cursor.getString(cursor.getColumnIndex(ResultTable.Cols.CONNECTION)));
		
		int size = 32;
		
		// Icon
		icon.getLayoutParams().height = size;
		icon.getLayoutParams().width = size;

		if (cursor.getString(cursor.getColumnIndex(ResultTable.Cols.CONNECTION)).equalsIgnoreCase(SpeedTestConstants.CONNTYPE_WIFI)) {
			icon.setImageResource(R.drawable.wifi_dark);
		} else {
			icon.setImageResource(R.drawable.wwan_dark);
		}
		
		iconDown.getLayoutParams().height = size;
		iconDown.getLayoutParams().width = size;
		iconDown.setImageResource(R.drawable.arrow_down);
		iconUp.getLayoutParams().height = size;
		iconUp.getLayoutParams().width = size;
		iconUp.setImageResource(R.drawable.arrow_up);
		iconRtt.getLayoutParams().height = size;
		iconRtt.getLayoutParams().width = size;
		iconRtt.setImageResource(R.drawable.arrow_up_down);
		
		if (sortby == R.id.HC_Ids) {
			ids.setTypeface(boldItalic);
		} else if (sortby == R.id.HC_Download) {
			download.setTypeface(boldItalic);
		} else if (sortby == R.id.HC_Upload) {
			upload.setTypeface(boldItalic);
		} else if (sortby == R.id.HC_RTT) {
			rtt.setTypeface(boldItalic);
		} else {
			ids.setTypeface(boldItalic);
		}
	}
	
	@Override
	public View getView(int position, View parent, ViewGroup container) {
		
		boolean error = false;
		
		Object item = getItem(position);
		if (item instanceof CursorWrapper) {
			int index = ((CursorWrapper) item).getColumnIndex(ResultTable.Cols.SUCCESS);
			int success = 1;
			if (index != -1) {
				success = ((CursorWrapper) item).getInt(index);
			}
			if (success == 0) {
				error = true;
			}
		}
		
		View view = super.getView(position, parent, container);
		if (!error) {
			view.setBackgroundResource(((position % 2) != 0) ? R.drawable.result_list_selector_2 : R.drawable.result_list_selector);
		} else {
			view.setBackgroundResource(((position % 2) != 0) ? R.drawable.result_list_selector_2_error : R.drawable.result_list_selector_error);
		}
		return view;
	}
}
Wenn du doch einen Inflater verwenden möchtest, dann hole ihn dir im Konstruktor mit
Code:
LayoutInflater.from(context)
und verwende ihn in der
Code:
#getView(int, View, ViewGroup)
Methode.
Anstatt
Code:
View view = super.getView(position, parent, container);
verwendest du dann
Code:
View view = mInflater.inflate(R.layout.result_row, container, false);
.
Ich verwende die #getView-Methode nur, um jeden zweiten View mit einem alternativen Hintergrund zu belegen, damit man die Zeilen besser unterscheiden kann. Der Rest geschieht in der
Code:
#bindView(View, Context, Cursor)
-Methode.
Der Rest ist bla bla und keine Hexerei.

Schau mal durch, ob dir das als Gedankenstütze hilft. Wenn du fragen dazu hast, immer her damit.

Grüsse,
Daniel

PS: Wenn du es dir in Aktion ansehen möchtest, installier dir einmal die Anwendung und spiele damit herum. Playstore: cnlab SpeedTest
PPS: Und wenn du Feedback hast, immer her damit ;-)
 

kaoZ

Top Contributor
Ok, das muss ich mir in Ruhe anschauen ^^

doch relativ komplex das ganze.... dazu muss ich mich auch erstmal in die Fragments Doku einlesen denke ich , aber trotzdem schon mal danke,

ich stehe aber grad noch vor einem anderen Problem, vielleicht hast du sowas ähnliches ja schon mal realisieren müssen.

Und zwar wird mein ListView ( bzw. der Adapter) mit Elementen aus einer ArrayList gefüllt, diese sind von einem eigenen Typ, nun möchte ich bei Klick auf eines der Items eine Kopie dieses Elementes anfertigen können.

Die Idee war dieses Element in die Zwischenablage zu kopieren und und bei bedarf wieder in den ListView einfügen zu können , nun habe ich aber in der API Dokumentation zum ClipboardManager nichts gefunden was mir helfen würde , da ich eben keine Strings kopieren will sondern eigene Objekte .

mein erster Gedanke war eine Methode zu erstellen die mir eine Kopie meines Objektes returned

z.B

Java:
public myObject copyListViewItem(MyObject obj){

  if(!(obj == null)){
    MyObject copy = new MyObject();
    copy.addValue(/* Aufruf der Setter von MyObject zum setzen der Werte*/);
    return copy;
  } 
return new MyObject().setDefaultValues(); // Zum umgehen einer NPE

}

Einfügen in den Adapter kann ich ja dann einfach über add() realisieren, allerdings muss ich mein Objekt dazu ja irgendwo Zwischenspeichern :) ( sonst bliebe nur Serialisieren, und das wäre Overkill oder nicht ?)

Java:
adapter.add(/* Objekt aus der Zwischenablage */);

nun stellt sich mir aber die Frage wie und wo ich diese Kopie nun temporär zwischenspeichern kann ?

ich nutzen btw. den OnItemLongClickListener der dann die Methode zur Objektkopie aufrufen soll.
(ich habe hier erstmal bewusst nicht Cloneable implementiert da die Objektkopie auch so leicht zu realisieren ist).

Hast du vielleicht schon etwas ähnliches realisieren müssen ?
 
Zuletzt bearbeitet:

dzim

Top Contributor
Da ich heute schon einen zu langen Tag hatte: Ich schau es mir morgen noch mal an. Eine erste Idee wäre recht pragmatisch - speicher es in eine Liste, für die es einen Getter in deinem Adapter gibt. Ist vielleicht nicht schön, sollte aber gehen.
Aber wie gesagt, ist es schon zu spät für mich und ich habe deine Antwort nur überflogen: Morgen!

Grüsse
 

kaoZ

Top Contributor
Ok, die Idee mit der Liste ist vielleicht garnicht verkehrt, ich werde das mal teste und für meine zu Verarbeitende Klasse eine Methode schreiben welche mir ein Objekt zurückliefert welches identisch belegte werte hat, da es wie gesagt nicht um Objektgleichheit geht kann ich auch einfach ein neues mit selben werten erzeugen anstatt clone() zu implementieren.

ich probiere mich mal ein bisschen aus und geb dann mal rückmeldung ;)
 
Zuletzt bearbeitet:

dzim

Top Contributor
Ok, danke. Das ersparrt mir gerade über mehr als meine Zahnschmerzen nachzudenken (der Zahnarzt war zwar grüdnlich, aber dennoch...) ;-)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Textdatei in ListView einlesen Tutorial gesucht!? Android & Cross-Platform Mobile Apps 3
R GCM Tutorial Android & Cross-Platform Mobile Apps 0
A https tutorial Android & Cross-Platform Mobile Apps 11
A Midlet Tutorial Android & Cross-Platform Mobile Apps 1
T Layouting, nebeneinander Android & Cross-Platform Mobile Apps 2
Kazudemruzo Android API/Library für externe Entwickler zur Verfügung stellen Android & Cross-Platform Mobile Apps 7
C Consent für Admob mit ump / funding choices Android & Cross-Platform Mobile Apps 6
B Was fehlt mir hier für diese Klasse? ich habe es mit (>>> ... <<<) markiert. Android & Cross-Platform Mobile Apps 4
J SharedPreferences für User-Session Android & Cross-Platform Mobile Apps 2
M Barrierefreie Appentwicklung für Android - Suche Codebeispiele Android & Cross-Platform Mobile Apps 8
I App für Fire HD entwickeln Android & Cross-Platform Mobile Apps 3
T Bringen mir die Java-Basics irgendetwas für die Android-Programmierung Android & Cross-Platform Mobile Apps 4
L Textfeld für Dezimalzahl mit Vorzeichen Android & Cross-Platform Mobile Apps 2
J Android Datenbank Klasse nur für CRUD-Operation, oder auch mehr ? Android & Cross-Platform Mobile Apps 8
B Android Projekt für Android und IOS erstellen? Android & Cross-Platform Mobile Apps 5
J Impressumspflicht für App, wenn ich kein Unternehmer bin? Android & Cross-Platform Mobile Apps 13
T Android Equalizer für Android Android & Cross-Platform Mobile Apps 3
L Zeitstempel für Sensordaten bekommen Android & Cross-Platform Mobile Apps 3
L Android Texterkennung für Android? Android & Cross-Platform Mobile Apps 1
L Android Chart API für Android Android & Cross-Platform Mobile Apps 0
T Android Datenbankverbindung in Service für Push Notification Android & Cross-Platform Mobile Apps 0
R Android USB Treiber für Huawei Android & Cross-Platform Mobile Apps 1
M Hilfe bei App Programmierung für Android Android & Cross-Platform Mobile Apps 1
B Script für Android Android & Cross-Platform Mobile Apps 1
H Datenprotokoll für Graphview Android & Cross-Platform Mobile Apps 2
M Android Obfuscation für Strings Android & Cross-Platform Mobile Apps 8
S Bilder mit fester grösse für verschiedene Android Endgeräte Android & Cross-Platform Mobile Apps 2
D Android Layout für alle Geräte Android & Cross-Platform Mobile Apps 4
A String[] für Lisadapter Android & Cross-Platform Mobile Apps 4
D Lib für (Desktop-)Java und Android schreiben Android & Cross-Platform Mobile Apps 7
J MySQL Simulation für Android App Android & Cross-Platform Mobile Apps 2
W Java Editor für Android +Emulator Android & Cross-Platform Mobile Apps 7
M 20 Image Button für jede Auflösung positionieren Android & Cross-Platform Mobile Apps 3
L Android ActionBar mit unterschiedlichen Farben für Tabs Android & Cross-Platform Mobile Apps 3
S Voraussetzungen für Android-Apps Android & Cross-Platform Mobile Apps 7
R Sinnvoller Ablageort für Leveldaten Android & Cross-Platform Mobile Apps 8
B App bei Play-Store für bestimmte auflösungen anbieten? Android & Cross-Platform Mobile Apps 3
G extends Activity für Berechnungen? Android & Cross-Platform Mobile Apps 7
H Progrämmchen für Symbian Android & Cross-Platform Mobile Apps 4
G wiederkehrenden Wert für Design in XML ablegen Android & Cross-Platform Mobile Apps 2
L Android SearchBox für Custom Listview Android & Cross-Platform Mobile Apps 5
T Android KontrollApp für Nitrado Server Android & Cross-Platform Mobile Apps 2
L Android Eine Kleinigkeit für Profis Android & Cross-Platform Mobile Apps 2
G Android C++ Quellcode für Android Geräte compilieren Android & Cross-Platform Mobile Apps 2
T Zeit in zwei Zahlen für Widget zerlegen Android & Cross-Platform Mobile Apps 2
J Apps für Android programmieren - Android Handy notwendig oder reicht Simulator? Android & Cross-Platform Mobile Apps 3
A Android SimpleDateFormat gibt für Date unter android anderes Datum zurück als in Std. Java Android & Cross-Platform Mobile Apps 2
H Android Landscape Modus für App dektivieren Android & Cross-Platform Mobile Apps 3
M Frage zu Java Programm für Windows Mobile 6.5 Android & Cross-Platform Mobile Apps 2
H Welches JDK für Huawei G7002? Android & Cross-Platform Mobile Apps 6
C Panel/View für Android Android & Cross-Platform Mobile Apps 3
C Sanke für Android Android & Cross-Platform Mobile Apps 3
Kukulkan Welche Mindestanforderungen (JDK) für Android und BB? Android & Cross-Platform Mobile Apps 8
G Views für verschiedenen Bildschirmgroeßen Android & Cross-Platform Mobile Apps 2
thE_29 Widget für verpasste Anruf + SMS Android & Cross-Platform Mobile Apps 2
A Android Android Parameter für VM Android & Cross-Platform Mobile Apps 7
O Entwickler für Java Anwendungen auf Handy gesucht! Android & Cross-Platform Mobile Apps 3
S JButton in GUI für Handys? Android & Cross-Platform Mobile Apps 3
M Welche Datenbank für J2ME? Android & Cross-Platform Mobile Apps 5
D Event für Tastensperre? Android & Cross-Platform Mobile Apps 3
G WTK für Nokia Android & Cross-Platform Mobile Apps 2
P bestimmte API für XDA ORBIT2 Android & Cross-Platform Mobile Apps 3
S Idee gesucht für ein kleines Programm Android & Cross-Platform Mobile Apps 3
M ein image pixel für pixel aufbauen : setPixel() ? Android & Cross-Platform Mobile Apps 1
M Handyprogramm für U-Bahn-Fahrplan für Siemens SK65 Android & Cross-Platform Mobile Apps 2
J Empfehlungen für ME-Anfänger Android & Cross-Platform Mobile Apps 2
K Anwendung für Handy programmieren Android & Cross-Platform Mobile Apps 1
P Java für PDA DELL Axim 51 Android & Cross-Platform Mobile Apps 4
M Virtuelle Machiene für PDA Android & Cross-Platform Mobile Apps 8
B Programm für NokiaComunicator erstellen Android & Cross-Platform Mobile Apps 2
K Programme für Handy erstellen Android & Cross-Platform Mobile Apps 3
M Java-Programme für Handy auf Desktop-PC ausführen Android & Cross-Platform Mobile Apps 4
T Für Handy Game die Sprache umschreiben? Android & Cross-Platform Mobile Apps 24
M java game für handy mit grahi. oberfläche Android & Cross-Platform Mobile Apps 1
D java.security.MessageDigest (für ME?) Android & Cross-Platform Mobile Apps 1
N Unser Team such Coder für Spieleprojekte Android & Cross-Platform Mobile Apps 8
B WTK für Sony Ericsson? Android & Cross-Platform Mobile Apps 7
S JAVA für java-mobiltelefone Android & Cross-Platform Mobile Apps 14

Ähnliche Java Themen

Neue Themen


Oben