2009-10-19 9 views
10

Wir schreiben gerade eine App mit 4 Tabs: Karte, Personen, Orte, Ereignisse. Die Personen, Orte und Ereignisse in der App werden als Symbole auf der Karte angezeigt. Standardmäßig zeigen die Registerkarten "Personen", "Orte" und "Ereignisse" jeweils eine Listenansicht an, die benutzerdefiniert dargestellt wird und alle Personen, Orte und Ereignisse anzeigt.Android - Tabs, MapView, Aktivitäten innerhalb der Registerkarten

alt text http://web6.twitpic.com/img/37202700-f92052dc474b74e1760edda1c47f6940.4adcb134-scaled.png

jetzt, gerade jetzt jede der Laschen hat als Inhalt eine Absicht Satz die entsprechende Aktivität zu starten. Zum Beispiel gibt es eine MapTabActivity, die MapActivity erweitert, eine ShowPeopleListActivity, die die Personen anzeigt, und so weiter.

Ich sehe eine lotofStackOverflowquestions/Antworten sagen, dass aufgrund verschiedener Einschränkungen in der Art und Weise der TabHost Setup ist, dann ist es am besten nicht Aktivitäten wie der Inhalt von Tabs zu verwenden. Zum Beispiel ist es unmöglich, eine neue Aktivität zu starten und sie an die Stelle der bestehenden Aktivität auf einer Registerkarte setzen zu lassen, während es möglich ist, eine Ansicht mit einer anderen Ansicht zu wechseln.

Jetzt bin ich an einer Kreuzung. Wir haben (im Guten wie im Schlechten) eine Menge Zeit darauf verwendet, diese App so zu gestalten, wie sie derzeit strukturiert ist, mit den Aktivitäten als Inhalt der Registerkarten. Wenn auf ein Symbol geklickt wird, das einer Person, einem Ort oder einem Ereignis entspricht, wird eine VIEW-Absicht für einen diesem Objekt entsprechenden URI ausgelöst. Dies wird von einer Aktivität übernommen, die dann das Objekt anzeigt. Derselbe Mechanismus ist sowohl in der Karte als auch in den einzelnen Listen wirksam. Wir mögen die lockere Verbindung, die uns das bietet; Wir geben einfach einen VIEW-Befehl und den URI an die Person/den Ort/das Ereignis und es bringt uns automatisch zur richtigen Aktivität. Zugegeben, die gestartete Aktivität verdeckt die Tab-Ansicht, anstatt darin zu erscheinen, aber wir waren bereit, damit zu leben.

Hier ist ein Problem: Von der Show-Aktivität wollen wir zurück zur Karte gehen können, zentriert auf diese Person, Ort oder Ereignis. Wir können eine neue Aktivität starten, um die Karte erneut anzuzeigen, aber jetzt haben wir die Kartenaktivität als Inhalt der Registerkarte, plus die Showaktivität sowie die neue Kartenaktivität im Aktivitätsstapel; Angesichts der ressourcenintensiven Kartenaktivitäten ist das nicht der ideale Weg.

Ich denke, meine Frage ist, gibt es ein gutes Tutorial irgendwo genau zeigen, wie komplexe Aufgaben mit einem TabHost zu tun? Ich habe HelloTabWidget gesehen; Ich suche etwas, das viel ausgeklügelter ist als das. Ich bin besorgt, dass, wenn wir auf die View-basierte Art und Weise der Dinge gehen, müssen wir eine Menge Haushalt zu tun, um alle zurück Ereignisse abfangen, versuchen, die Ansichten usw., etc., sowie stark unser Programm auf eine Weise koppeln, die wir nicht wollen.

Alle Vorschläge für einen Weg nach vorne würden sehr geschätzt werden. Wir sind neu in Android, daher versuchen wir, den etablierten Best Practices zu folgen, aber es ist schwierig, wenn die wenigen Beispiele, die wir gesehen haben, für unseren Anwendungsfall zu einfach sind.

Antwort

7

Ich sehe eine Menge von Stackoverflow Fragen/Antworten zu sagen, dass aufgrund verschiedene Einschränkungen in der Art und Weise der TabHost Setup ist, dann ist es am besten nicht Aktivitäten wie der Inhalt von Tabs zu verwenden.

Als selbst ernannter Präsident der Anti-Activity-Tab-Allianz (AATA), das ist sicherlich meine Position.

Wenn ein Symbol einer Person, Ort oder Ereignis entsprechende geklickt wird, es feuert eine VIEW Intent auf einem URI auf dieses Objekt entspricht; Dies wird von einer Aktivität abgeholt, die dann das Objekt zeigt.

Beachten Sie, dass dies nichts mit Aktivitäten als Inhalt von Registerkarten zu tun hat.

Wir können eine neue Aktivität starten die Karte wieder zeigen, aber jetzt haben wir die Karte Aktivität als den Inhalt des Registerkarte plus die Show-Aktivität sowie die neue Karte Aktivität im Aktivitätsstapel ; gegeben, wie ressourcenintensiv die Karte Aktivität ist, ich denke, das ist nicht der ideale Weg zu gehen.

Ich würde es vermeiden, wenn möglich.

Ich mache mir Sorgen, dass, wenn wir auf die View basiert Art und Weise, Dinge zu tun wechseln, werden wir haben eine Menge Housekeeping abfangen alle zurück Ereignissen zu tun, versuchen Sie, Schalter aus den Ansichten usw., usw., als auch stark unser Programm in einer Weise koppeln, die wir nicht wollen.

Dies folgt nicht von dem, was Sie zuvor geschrieben haben. Ihre "Zurück-Ereignisse" werden keinen Unterschied zwischen der Verwendung von Ansichten als Inhalt von Registerkarten und der Verwendung von Aktivitäten als Inhalt von Registerkarten ändern. Darüber hinaus hat dies nichts mit dem von Ihnen beschriebenen "losen Kopplungsmuster" zu tun. Das Klicken auf ein Symbol in einer Liste in einer Ansicht in einer Registerkarte ist nicht anders als das Klicken auf ein Symbol in einer Liste in einer Ansicht in einer Aktivität in eine Registerkarte.

Haben Sie einfach Ihre Show Aktivität sagen Sie, äh, Hauptaktivität, um einen bestimmten Ort anzuzeigen, dann kann die Show Aktivität finish(). Der einfachste Weg, dies zu tun, ohne eine harte JVM-Kopplung zwischen den Aktivitäten einzuführen, besteht darin, eine Intent zu senden und eine BroadcastReceiver in der Hauptaktivität zu registrieren. Nach Erhalt dieses Intent würde die Hauptaktivität die Karte aktualisieren und als aktuelle Registerkarte festlegen. Dieser Ansatz ist natürlich einfacher, wenn Sie in der Hauptaktivität Ansichten für den Tab-Inhalt verwenden.

Jetzt, wenn Sie versuchen, Ihre Anwendung zu überholen, so dass das Navigieren in einer Registerkarte nicht eine andere Aktivität startet, sondern die Dinge in einem eigenen Tab hält ... das ist ein ganz 'verrückter Kessel Fisch.

+0

OK, ich sehe Ihren Punkt, dass, wenn wir alle Intents auf die gleiche Weise eingerichtet haben und die Show-Aktivität gestartet wird, die Back-Events genau gleich behandelt werden. Also ich denke, die wahre Komplexität (und die Back-Event-Schmerz) wäre, wenn wir den Inhalt der Registerkarten anstelle der gestarteten Absichten programmatisch auswechselten. Z.B. Die Registerkarte Personen, auf der normalerweise eine Personenliste angezeigt wird, wird aufgefordert, zu einer Personenansicht zu wechseln, wenn auf eine bestimmte Person geklickt wird. In diesem Fall müssten wir uns selbst mit dem Stapel von Ansichten befassen. – I82Much

+0

Wie kann man auch eine Karte innerhalb einer Registerkarte haben, ohne eine Aktivität als Inhalt einer Registerkarte zu haben? Ist das möglich? – I82Much

+0

w/r/t Ihren ersten Kommentar, ja, Sie müssten Ihr eigenes Stack-Management tun. w/r/t deinen zweiten Kommentar, ja du kannst AFAIK. Machen Sie Ihre Hauptaktivität zu einer MapActivity und nicht zu einer TabActivity. Das einzige, was TabActivity für Sie erledigt, ist der Aufruf von setup() automatisch auf Ihrem TabHost, was Sie dann selbst tun müssen, bevor Sie TabSpecs hinzufügen. Dann gibt MapActivity Ihnen, was Sie brauchen, um die Karte in einen Tab zu setzen. Es ist möglich, dass es hier Probleme gibt, aber aus dem Stegreif denke ich sollte es OK funktionieren. – CommonsWare

8

Es ist eine gute Übung, eine Aktivität und mehrere Ansichten für Ihre Tabs zu haben. Doch das bedeutet Sie müssen vorsichtig sein zu handhaben, welche Registerkarte ausgewählt ist, verschiedene Menüs und Kontextmenüs für jede Registerkarte Ansicht usw.

Ich denke, meine Frage ist, gibt es ein gutes Tutorial irgendwo zeigt genau wie komplexe Aufgaben mit einem TabHost zu tun? Ich habe HelloTabWidget gesehen. Ich bin auf der Suche nach etwas viel mehr anspruchsvoll als das.

Ich schrieb ein etwas besseres Tutorial in meinem Blog, das eine interagierende ListView und MapView als Tabs demonstriert. Hier ist der Link: Android Tabs with interacting map and list views

Die Grundlagen ist ein Layout ähnlich dem in der HelloTabWidget Tutorial haben, machen Sie Ihre Aktivität von MapActivity erweitern, extrahieren Sie die TabHost aus dem XML und stellen Sie sicher, rufen Sie Setup() auf der TabHost. Danach sind das Hinzufügen von Ansichten als Inhalt von Tabs, Tab-Listenern usw. gleich.

Hier ein kurzer Ausgangspunkt für die Klasse ist:

public class TabbedListMapActivity extends MapActivity { 

private ListView listView; 
private MapView mapView; 

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

    tabHost = (TabHost) findViewById(android.R.id.tabhost); 

    // setup must be called if not a TabActivity 
    tabHost.setup(); 

    // setup list view 
    listView = (ListView) findViewById(R.id.list); 

    // setup map view 
    mapView = (MapView) findViewById(R.id.mapview); 

    // add views to tab host 
    tabHost.addTab(tabHost.newTabSpec("List").setIndicator("List").setContent(new TabContentFactory() { 
     public View createTabContent(String arg0) { 
      return listView; 
     } 
    })); 
    tabHost.addTab(tabHost.newTabSpec("Map").setIndicator("Map").setContent(new TabContentFactory() { 
     public View createTabContent(String arg0) { 
      return mapView; 
     } 
    })); 
} 

...

+0

Jetzt ist dies eine gute Antwort! Danke Josh, du hast meinen Tag gerettet. –

1

Zum Beispiel ist es eine neue Aktivität zu Start unmöglich und hat es an die Stelle des bestehenden nehmen Aktivität innerhalb einer Registerkarte, während es möglich ist, eine Ansicht mit einer anderen Ansicht zu wechseln.

Ich glaube nicht, dass es unmöglich ist. Ich experimentierte mit dieser Idee und schrieb einen Blog article, der erklärte, was ich tat. Ich füge ein Beispielcode-Projekt am Ende des Artikels ein, der einige der interessanten Dinge zeigt, die ich gelernt habe.

Verwandte Themen