April 28th, 2011, 01:25 PM
-
Passing a bundled object from TabHost to a tabbed Activity
Note: This was posted earlier at Android Central, under the mistaken impression that it was primarily a development forum. If there are any relevant replies at that site, I will re-post them here.
I am developing an app which (at its current stage of development) consists of a login Activity, which leads to a TabActivity containing four tabs, each of which is instantiated as a separate Activity. I need to be able to pass the user information (or at least the user ID) to some but not all of the tabbed Activities. I am able to pass the data from the login screen to the TabActivity (this has been confirmed by stepping through the relevant section of code), but my attempts to use a similar approach to pass a Bundle to the sub-Activities does not actually pass the Bundle to the child Activities. The relevant code for the TabActivity and an example child Activity is as follows:
ParentTabActivity.java:
Code:
package com.allpropestservices.bugpromobile;
import android.app.TabActivity;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.util.Log;
import android.widget.TabHost;
public class ParentTabActivity extends TabActivity {
public static final String TAG = "ParentTabActivity";
public Long userId;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.parent);
Bundle b = getIntent().getExtras();
try {
userId = b.getLong("UserId");
}
catch (RuntimeException e) {
String err = e.toString() + " in " + TAG + ".onCreate()";
Log.v(TAG, err);
}
Resources res = getResources(); // Resource object to get Drawables
TabHost tabHost = getTabHost(); // The activity TabHost
TabHost.TabSpec spec; // Reusable TabSpec for each tab
Intent intent; // Reusable Intent for each tab
Bundle userData;
// Create an Intent to launch an Activity for the tab (to be reused)
intent = new Intent().setClass(this, AnnouncementActivity.class);
// prepare a Bundle to pass to each of the sub-activities
userData = new Bundle();
userData.putLong("UserID", userId);
intent.putExtras(userData);
// Initialize a TabSpec for each tab and add it to the TabHost
spec = tabHost.newTabSpec("Announcements").setIndicator("Announcements",
res.getDrawable(R.drawable.ic_menu_notifications))
.setContent(intent);
tabHost.addTab(spec);
intent = new Intent().setClass(this, AlertActivity.class);
userData = new Bundle();
userData.putLong("UserID", userId);
intent.putExtras(userData);
spec = tabHost.newTabSpec("Alerts").setIndicator("Alerts",
res.getDrawable(R.drawable.ic_menu_inbox))
.setContent(intent);
tabHost.addTab(spec);
intent = new Intent().setClass(this, TimeClockActivity.class);
userData = new Bundle();
userData.putLong("UserID", userId);
intent.putExtras(userData);
spec = tabHost.newTabSpec("TimeClock").setIndicator("Time Clock",
res.getDrawable(R.drawable.ic_menu_duration))
.setContent(intent);
tabHost.addTab(spec);
intent = new Intent().setClass(this, ScheduleActivity.class);
userData = new Bundle();
userData.putLong("UserID", userId);
intent.putExtras(userData);
spec = tabHost.newTabSpec("Schedule").setIndicator("Schedule",
res.getDrawable(R.drawable.ic_menu_agenda))
.setContent(intent);
tabHost.addTab(spec);
tabHost.setCurrentTab(0);
}
}
AlertActivity.java:
Code:
/**
*
*/
package com.allpropestservices.bugpromobile;
import java.util.ArrayList;
import java.util.Date;
import android.app.Activity;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.TextView;
/**
* @author J. Osako
*
*/
public class AlertActivity extends Activity {
// For logging and debugging
private static final String TAG = "AlertActivity";
private int position = 0;
private ArrayList<Message> messages;
private User user = null;
/**
*
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.motd);
Bundle b = getIntent().getExtras();
Long userId = b.getLong("UserId");
user = new User(this, userId);
messages = Message.getAlertMessages(this, new Date(), 10, user);
Message msg = messages.get(position);
TextView banner = (TextView) findViewById(R.id.AlertBanner);
EditText title = (EditText) findViewById(R.id.AlertTitle);
EditText body = (EditText) findViewById(R.id.AlertText);
banner.setText("Recent Alerts for " + user.getFullName());
title.setText(msg.getTitle());
body.setText(msg.getBody());
}
}
I am not applying any intent filters in the layout file for ParentTabActivity; the layout is:
parent.xml
Code:
<?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">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp" />
</LinearLayout>
</TabHost>
I realize that it may be possible to avoid this issue by re-designing the TabActivity so that it uses Views instead of Activities, but I would prefer to keep the different tabs separated if at all possible.
Is there any way to make this design work, and if so, where am I making my error? Do I need to add an intent filter to either the parent layout or the child layouts? Would switching to a View-based design negatively impact the modularity of the app?
April 28th, 2011, 01:59 PM
-
Problem solved; it turned out to be a typographical error ("UserID" rather than "UserId") in the ParentTabActivity. The fact that it was duplicated four times is particularly galling.
Last edited by Schol-R-LEA; April 28th, 2011 at 04:13 PM.