TabHost und ActivityGroup

  • Antworten:7
hollister
  • Forum-Beiträge: 5

25.11.2010, 00:18:23 via Website

Hi,

ich möchte gerne ein TabHost mit einem TabWidget einsetzen, dass im ersten Tab mehrere Activitys nacheinander darstellen kann.
Soweit ich weiß eignet sich hierzu die ActivityGroup sehr gut. Allerdings bin ich bisher zu keinem brauchbaren Ergebnis gekommen.

Im Grunde habe ich bereits mehrere Activitys mit je einer ListVIew erstellt, die im Kern wie folgt aussehen und funktionieren:
1public class firstactivity extends ListActivity{
2 public Order order = new Order();
3 private ProgressDialog m_ProgressDialog = null;
4 private ArrayList<Order> orders_book = null;
5 private OrderAdapter adapter_overview;
6 private Runnable viewOrders;
7
8 @Override
9 public void onCreate(Bundle savedInstanceState) {
10 super.onCreate(savedInstanceState);
11 setContentView(R.layout.main);
12
13 /** Create a new layout to display the view */
14 LinearLayout layout = new LinearLayout(this);
15 layout.setOrientation(1);
16 orders_book = new ArrayList<Order>();
17 this.adapter_overview = new OrderAdapter(this, R.layout.first, orders_book);
18
19 setListAdapter(this.adapter_overview);
20 viewOrders = new Runnable(){
21 @Override
22 public void run() {getBookTitle();}
23 };
24
25 Thread thread = new Thread(null, viewOrders, "MagentoBackground");
26 thread.start();
27 m_ProgressDialog = ProgressDialog.show(firstactivity.this,
28 "Please wait", "123", true);

main.xml (standard)
1<?xml version="1.0" encoding="utf-8"?>
2<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:orientation="vertical"
4 android:layout_width="fill_parent"
5 android:layout_height="fill_parent"
6 android:id="@layout/main">
7<ListView
8 android:id="@+id/android:list"
9 android:layout_width="fill_parent"
10 android:layout_height="fill_parent"
11 />
12<TextView
13 android:id="@+id/android:empty"
14 android:layout_width="fill_parent"
15 android:layout_height="fill_parent"
16 android:text="@string/main_loader_text"/>
17</LinearLayout>


first.xml
1<?xml version="1.0" encoding="utf-8"?>
2<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="fill_parent"
4 android:layout_height="?android:attr/listPreferredItemHeight"
5 android:id="@layout/first">
6
7 <ImageView
8 android:id="@+id/icon"
9 android:layout_width="wrap_content"
10 android:layout_height="fill_parent"
11 android:layout_marginRight="10dip"
12 android:src="@drawable/icon" />
13 <LinearLayout
14 android:orientation="vertical"
15 android:layout_width="0dip"
16 android:layout_weight="1"
17 android:layout_height="fill_parent">
18 <TextView
19 android:id="@+id/toptext"
20 android:layout_width="fill_parent"
21 android:layout_height="0dip"
22 android:layout_weight="1"
23 android:textColor="@color/white"
24 />
25 </LinearLayout>
26</LinearLayout>

Jetzt würde ich gerne diese mit um die TabHost erweitern.

Hier ein Ansatz, den ich gern als tablayout.xml nutzen würde:
1<TabHost android:layout_width="fill_parent"
2 android:layout_height="fill_parent"
3 android:id="@android:id/tabhost"
4 xmlns:android="http://schemas.android.com/apk/res/android"
5 >
6 <RelativeLayout
7 android:layout_width="fill_parent"
8 android:layout_height="fill_parent"
9 >
10 <TabWidget
11 android:layout_width="fill_parent"
12 android:layout_height="wrap_content"
13 android:id="@android:id/tabs"
14 android:layout_alignParentBottom="true"
15 />
16 <FrameLayout
17 android:layout_width="fill_parent"
18 android:layout_height="fill_parent"
19 android:id="@android:id/tabcontent"
20 >
21
22 </FrameLayout>
23 </RelativeLayout>
24 </TabHost>

Würde mich über einen brauchbaren Ansatz einer Javaklasse und Layoutfile freuen. Danke. -_-

Antworten
mybecks
  • Forum-Beiträge: 27

26.11.2010, 10:39:41 via Website

Hallo,

schau dir mal die beiden Links an, da findest du je ein super Beispiel zum Thema ActivityGroup und TabHost.

Link 1
Link 2

In den Kommentaren verstecken sich auch als nützliche Hinweise.

Viele Grüße,
mybecks

hollister

Antworten
hollister
  • Forum-Beiträge: 5

28.11.2010, 21:42:28 via Website

Hi,

aufbauend auf dem Tutorial deines ersten Links habe ich mein Programm umgeschrieben.
Wie in der Beschreibung soll zunächst eine TabActivity aufgerufen werden, die dann die FirstGroup als intent aufruft. Ab der Stelle FirstGroup läuft mein Programm problemlos. Allerdings beim Aufruf der TabActivity (hier "TabAct" genannt) erhalte ich folgenden Fehler im LogCat:
1...ERROR/AndroidRuntime(4812): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test/com.test.TabAct}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test/com.test.FirstGroup}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test/com.test.FirstGroupChild}: android.view.WindowManager$BadTokenException: Unable to add window -- token android.app.LocalActivityManager$LocalActivityRecord@46395dc8 is not valid; is your activity running?


Hier meine TabAct.xml:
1public class TabAct extends android.app.TabActivity{
2
3 public TabHost tabhost;
4
5 public void onCreate(Bundle savedInstanceState) {
6 super.onCreate(savedInstanceState);
7 setContentView(R.layout.main);
8
9 Resources res = getResources();
10 TabHost tabhost = getTabHost();
11 TabHost.TabSpec spec;
12 Intent intent;
13
14 intent = new Intent().setClass(this, FirstGroup.class);
15
16 spec = tabhost.newTabSpec("FirstGroup").setIndicator("FirstGroup",
17 getResources().getDrawable
18 (R.drawable.icon))
19 .setContent(intent);
20 tabhost.addTab(spec);
21
22 intent = new Intent().setClass(this, SecondGroup.class);
23
24 spec = tabhost.newTabSpec("SecondGroup").setIndicator("SecondGroup",
25 getResources().getDrawable
26 (R.drawable.icon))
27 .setContent(intent);
28 tabhost.addTab(spec);
29
30 tabhost.setCurrentTab(1);
31 }
32}


Die TabAct ist ebenfalls richtig in die AndroidMainfest.xml als eingebunden:
1<activity android:name=".TabAct"
2 android:label="@string/app_name">
3 <intent-filter>
4 <action android:name="android.intent.action.MAIN" />
5 <category android:name="android.intent.category.LAUNCHER" />
6 </intent-filter>
7 </activity>

main.xml:
1<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
2 android:id="@android:id/tabhost"
3 android:layout_width="fill_parent"
4 android:layout_height="fill_parent">
5 <LinearLayout
6 android:orientation="vertical"
7 android:layout_width="fill_parent"
8 android:layout_height="fill_parent"
9 android:padding="5dp">
10 <TabWidget
11 android:id="@android:id/tabs"
12 android:layout_width="fill_parent"
13 android:layout_height="wrap_content" />
14 <FrameLayout
15 android:id="@android:id/tabcontent"
16 android:layout_width="fill_parent"
17 android:layout_height="fill_parent"
18 android:padding="5dp">
19
20 <LinearLayout
21 android:orientation="vertical"
22 android:layout_width="fill_parent"
23 android:layout_height="fill_parent">
24 <ListView
25 android:id="@+id/android:list"
26 android:layout_width="fill_parent"
27 android:layout_height="fill_parent"/>
28 <TextView
29 android:id="@+id/android:empty"
30 android:layout_width="fill_parent"
31 android:layout_height="fill_parent"
32 android:text="@string/main_loader_text"/>
33 </LinearLayout>
34 </FrameLayout>
35 </LinearLayout>
36</TabHost>

— geändert am 28.11.2010, 21:57:00

Antworten
mybecks
  • Forum-Beiträge: 27

29.11.2010, 10:06:51 via Website

Hallo,

habe in einer meiner Apps folgenden Aufbau (bin auch nach den 2Tuts vorgegangen).
Vielleicht hilft es dir.

main.xml
1<?xml version="1.0" encoding="utf-8"?>
2<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
3 android:id="@android:id/tabhost"
4 android:layout_width="fill_parent"
5 android:layout_height="fill_parent">
6 <TabWidget
7 android:id="@android:id/tabs"
8 android:layout_width="fill_parent"
9 android:layout_height="wrap_content"
10 android:orientation="horizontal"
11 android:layout_gravity="bottom" />
12 <FrameLayout android:id="@android:id/tabcontent"
13 android:layout_width="fill_parent"
14 android:layout_height="fill_parent"
15 android:paddingBottom="65dp">
16</FrameLayout>
17</TabHost>

TabActivity.java
1public class TabMenu extends TabActivity{
2
3 private final String TAG = "TabMenu";
4
5 @Override
6 public void onCreate(Bundle savedInstanceState) {
7 super.onCreate(savedInstanceState);
8 setContentView(R.layout.main);
9 Resources res = getResources();
10
11 TabHost tabs = (TabHost) this.findViewById(android.R.id.tabhost);
12
13 TabSpec tspec1 = tabs.newTabSpec("TAB_01");
14 tspec1.setIndicator(getString(R.string.tab1), res.getDrawable(R.drawable.tab_home));
15 tspec1.setContent(new Intent(TabMenu.this, CockpitGroup.class));
16 tabs.addTab(tspec1);
17
18 TabSpec tspec2 = tabs.newTabSpec("TAB_02");
19 tspec2.setIndicator(getString(R.string.tab2), res.getDrawable(R.drawable.tab_contacts));
20 tspec2.setContent(new Intent(TabMenu.this, ContactsGroup.class));
21 tabs.addTab(tspec2);
22
23 TabSpec tspec3 = tabs.newTabSpec("TAB_03");
24 tspec3.setIndicator(getString(R.string.tab3), res.getDrawable(R.drawable.tab_calendar));
25 tspec3.setContent(new Intent(TabMenu.this, AppointmentDetails.class));
26 tabs.addTab(tspec3);
27
28 tabs.setCurrentTab(0);
29
30 }
31
32Du fügst so wie ich das gerade sehe, deine Tabs nicht hinzu, sondern definierst sie nur. Aber keine Ahnung ob dies den Fehler
33}

CockpitGroup.java (TAB1)
1public class CockpitGroup extends ActivityGroup{
2 private final String TAG = "CockpitGroup";
3 public static CockpitGroup group;
4 private ArrayList<View> history;
5
6 @Override
7 protected void onCreate(Bundle savedInstanceState) {
8 super.onCreate(savedInstanceState);
9 this.history = new ArrayList<View>();
10 group = this;
11
12 // Start the root activity withing the group and get its view
13 View view = getLocalActivityManager().startActivity(
14 "CockpitActivity",
15 new Intent(CockpitGroup.this, Cockpit.class)
16 .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
17 .getDecorView();
18
19 // Replace the view of this ActivityGroup
20 replaceView(view);
21 }
22
23 public void replaceView(View v) {
24 // Adds the old one to history
25 history.add(v);
26 // Changes this Groups View to the new View.
27 setContentView(v);
28 }
29
30 public void back() {
31 if (history.size() > 0) {
32 history.remove(history.size() - 1);
33 setContentView(history.get(history.size() - 1));
34 } else {
35 finish();
36 }
37 }
38
39
40 @Override
41 public boolean onKeyDown(int keyCode, KeyEvent event) {
42 Log.i(TAG, keyCode+"");
43 Log.i(TAG, KeyEvent.KEYCODE_BACK+"");
44 Log.i(TAG, event.KEYCODE_BACK+"");
45 if (keyCode == KeyEvent.KEYCODE_BACK) {
46 CockpitGroup.group.back();
47 return true;
48 }
49 return super.onKeyDown(keyCode, event);
50 }
51}

— geändert am 29.11.2010, 10:07:56

Antworten
hollister
  • Forum-Beiträge: 5

29.11.2010, 20:50:26 via Website

Unglaublich mybecks,

jetzt habe ich gänzlich deinen Code verwendet und bekomme den exakt gleichen Fehler "...Unable to start activity ComponentInfo{com.test/com.test.TabAct}...". 8o ???

Antworten
Ansgar M
  • Forum-Beiträge: 1.544

29.11.2010, 21:04:17 via App

Die Activity ist im Manifest eingetragen, oder?
Lg Ansgar

Antworten
hollister
  • Forum-Beiträge: 5

29.11.2010, 21:35:38 via Website

Ja ist Sie:
1....
2<activity android:name=".TabAct"
3 android:label="@string/app_name">
4 <intent-filter>
5 <action android:name="android.intent.action.MAIN" />
6 <category android:name="android.intent.category.LAUNCHER" />
7 </intent-filter>
8 </activity>
9
10 ....
11 </activity>

Ich habe jetzt ...this... mit getParent() ersetzt. Dadurch erhalte ich nur noch den folgenden Fehler:
111-29 21:32:44.689: ERROR/AndroidRuntime(6878): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test/com.test.TabAct}: java.lang.NullPointerException

Antworten
hollister
  • Forum-Beiträge: 5

30.11.2010, 09:43:53 via Website

Nach einigem Testen vermute ich, dass der Fehler sich in diesem Teil des Codes befindet.

1public class CockpitGroup extends ActivityGroup{
2private final String TAG = "CockpitGroup";
3public static CockpitGroup group;
4private ArrayList<View> history;
5
6@Override
7protected void onCreate(Bundle savedInstanceState) {
8super.onCreate(savedInstanceState);
9this.history = new ArrayList<View>();
10 group = this;
11
12 // Start the root activity withing the group and get its view
13 View view = getLocalActivityManager().startActivity(
14 "CockpitActivity",
15 new Intent(CockpitGroup.this, Cockpit.class)
16 .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
17 .getDecorView();
18
19 // Replace the view of this ActivityGroup
20 replaceView(view);
21}

Wieso ich das denke:
Bleiben wir bei dem Beispiel von mybecks. Wenn ich die ActivityGroup nicht verwende und direkt im TabMenu auf die CockpitActivity verweise, funktioniert alles wunderbar. Das Problem, dass ich dann aber habe, dass ich das TabMenu in den weiteren Activitys nicht sehe. Folglich brauche ich die ActivityGroup.

— geändert am 30.11.2010, 09:47:53

Antworten