Erstellen eines TabHost in Android

Bei meinen eigenen Projekten geht es auch vor ran, wenn ich denn mal Zeit habe neben Arbeit und Uni. Bei dem besagten Projekte wollte ich nun einen TabHost einfügen was sich als doch ein wenig knifflig herausgestellt hat. Denn wie ich gemerkt habe gibt es nur ein Beispiel was auf einem älterem Beispiel aufbaut.
Darum habe ich mich entschlossen ein Beispiel zu geben für die Aktuelle Version (Android 1.5 SDK, Release 1).

Hier gehts zum Beispiel.

Da wollen wir hinkommen

Da wollen wir hinkommen

So oder so ähnlich soll er dann aussehen wenn wir fertig sind. Also frisch ans Werk.

Zuerst müssen wir die Grundlagen in einer XML Datei festlegen (z.B. main.xml):

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@android:id/tabhost"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">

	<TabWidget android:id="@android:id/tabs"
		android:layout_width="fill_parent"
		android:layout_height="fill_parent"/>

	<FrameLayout
	android:id="@android:id/tabcontent"
	android:layout_height="wrap_content"
	android:paddingTop="70px"
	android:layout_width="fill_parent"/>
</TabHost>

In zeile 3, 7 und 12 müssen von Android vorgegebene id’s verwendet werden. Denn ein TabHost muss auf den Android eigenen TabHost verweisen. Außerdem:

  • muss er ein TabWidget haben
  • das TabWidget muss den Host ausfüllen
  • muss er ein FrameLayout haben

In Zeile 14 ist ein ziemlich großes Padding zu sehen. Diese muss gesetzt werden ansonsten rutscht der Inhalt des Tabs auf den TabHost und man kann keine anderen Tabs mehr auswählen.

Nun wird es aber spannend und wir gehen in den Source code und schauen uns an wie die einzelnen Tabs angelegt werden und mit Inhalt gefüllt werden.

Zur Vereinfachung habe ich mir eine TabActivity angelegt dadurch kommt man schneller an den TabHost. ran.


private LinkedList<String> tabNames = new LinkedList<String>();

private void initializeTabHost(){

	setContentView(R.layout.main);
	TabHost tabHost = getTabHost();
	MyTabContentFactory tabContentfactory = new MyTabContentFactory(this, tabNames);

	tabHost.setup();

	for(String names : tabNames){
		TabHost.TabSpec days = tabHost.newTabSpec(names);
		days.setIndicator(names);
		days.setContent(tabContentFactory);

		tabHost.addTab(days);
	}
	tabHost.setCurrentTab(0);
}

static{

	Calendar date = new GregorianCalendar();
    	
    tabNames.add("Today");
    	
    for(int i=0; i<3; i++){
    	date.roll(GregorianCalendar.DAY_OF_WEEK, true);
    	switch(date.get(GregorianCalendar.DAY_OF_WEEK)){
    		case GregorianCalendar.MONDAY:
    		tabNames.add("Montag");
    		break;
    	case GregorianCalendar.TUESDAY:
    		tabNames.add("Dienstag");
    		break;
    	case GregorianCalendar.WEDNESDAY:
    		tabNames.add("Mittwoch");
    		break;
    	case GregorianCalendar.THURSDAY:
    		tabNames.add("Donnerstag");
    		break;
    	case GregorianCalendar.FRIDAY:
    		tabNames.add("Freitag");
    		break;
    	default: i--;
    	}
    }
}

In Zeile 12 wird ein Tab angelegt. Es ist eine Innere Klasse vom TabHost.

  • Ein Tab verlangt Tag welchen wir nach belieben vergeben können.
  • Der eigentlich Name des Tabs wird in Zeile 13 festgelegt.
  • In Zeile 14 wird festgelegt wie der Inhalt aussieht (s.u.)

Nun haben wir uns 4 Tabs erzeugt:

  • Today
  • und die 3 darauf folgenden Tage
  • das Wochende wird ausgelassen da gibt es kein essen!

Nun schauen wir uns noch an wie der Inhalt des Tabs gefüllt wird:

public class MyTabContentFactory implements TabContentFactory {

	private Context mCtx;
	private RequestHandler rH;
	private LayoutInflater inflater;
	private HashMap<String, Integer> tabs;
	private DatabaseHelper databaseHelper;
	
	public MyTabContentFactory(Context ctx, LinkedList<String> tabNames){
		
		mCtx = ctx;
		databaseHelper = new DatabaseHelper(ctx);
		rH = new RequestHandler(mCtx);
        inflater = (LayoutInflater)mCtx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        
        tabs = new HashMap<String, Integer>();
        
        int i = 0;
        for(String names : tabNames){
        	tabs.put(names, i);
        	i++;
        }
}
	
	public View createTabContent(String tag) {
		
		rH.start();
		
		MyHashMapAdapter hashMapAdapter;
		View root;
		ListView listView;
		
		switch(tabs.get(tag)){
		
		case RequestHandler.TODAY:
			hashMapAdapter = new MyHashMapAdapter(mCtx, databaseHelper.getDay(Gerichte.TODAY));
			root = inflater.inflate(R.layout.list, null);
			listView = (ListView)root.findViewById(R.id.listview);
			listView.setAdapter(hashMapAdapter);
			return listView;
			
		case RequestHandler.TOMORROW:
			hashMapAdapter = new MyHashMapAdapter(mCtx, databaseHelper.getDay(Gerichte.TOMORROW));
			root = inflater.inflate(R.layout.list, null);
			listView = (ListView)root.findViewById(R.id.listview);
			listView.setAdapter(hashMapAdapter);
	        return listView;
	        
		case RequestHandler.THEDAYAFTERTOMORROW:
			hashMapAdapter = new MyHashMapAdapter(mCtx, databaseHelper.getDay(Gerichte.THEDAYAFTERTOMORROW));
			root = inflater.inflate(R.layout.list, null);
			listView = (ListView)root.findViewById(R.id.listview);
			listView.setAdapter(hashMapAdapter);
	        return listView;
			
		case RequestHandler.OVERTHEDAYAFTERTOMORROW:
			hashMapAdapter = new MyHashMapAdapter(mCtx, databaseHelper.getDay(Gerichte.OVERTHEDAYAFTERTOMORROW));
			root = inflater.inflate(R.layout.list, null);
			listView = (ListView)root.findViewById(R.id.listview);
			listView.setAdapter(hashMapAdapter);
	        return listView;
	        
	    default: return null;
		}
	}
}

Das sieht viel aus ist aber in kürze erklärt denn wir implementieren hier ja nur ein Interface (TabContentFactory) und die Methoden sind vorgegeben nur wir wie sie füllen wird uns überlassen.

Denn der TabHost wird die Methode createTabContent() aufrufen und den View der ihm zurück gegeben wird, wird eingebettet als Inhalt des Tabs. In diesem Fall fülle ich die Tabs mit einem ListView (vielleicht mache ich dazu später auch ein beispiel).

Ja und das war es auch schon. Der TabHost ist fertig und sollte genau so aussehen wie auf der Abbildung nur das kein Inhalt zu sehen sein dürfte da keine Daten vorhanden sind.

Anmerkungen:

  • DatabaseHelper ist von mir implementiert als Hilfsklasse
  • MyHashMapAdapter ist auch von mir implementiert
  • Folgen vielleicht in einem anderen beispiel
About these ads

Schlagwörter: , , , , , , , , ,

2 Antworten to “Erstellen eines TabHost in Android”

  1. Wiederverwendung von layouts - Android-Hilfe.de Says:

    [...] [...]

  2. SR Says:

    Danke für Dein Beispiel. Ich kann es aber nicht zum laufen bringen, da einfach zu viele Klassen fehlen. Wenn ich die Referenzen auf die fehlenden Klassen auskommentiere, bricht der Start mit einer Fehlermeldung im Emulator ab.

    Deshalb meine Bitte: könntest Du das Projekt als Ganzes zur Verfügung stellen – vielleicht gezippt?

    Vielen Dank

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ photo

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s


Follow

Erhalte jeden neuen Beitrag in deinen Posteingang.

%d Bloggern gefällt das: