Reputation: 60869
I have a TabActivity that has a TabHost with two tabs. Each tab has its own intent. It seems like the intent's onResume() fires before I can detect if a tab was changed. How can I resolve this?
TabActivity code:
public class TabHostActivity extends TabActivity {
static final int SHOW_SHARE_ACTIVITY = 0;
static final int SHOW_LOGIN_ACTIVITY = 1;
private TabHost tabHost;
private ImageButton composeImageButton;
private SharedPreferences prefs;
private Bundle b;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.tabhostactivity);
prefs = getSharedPreferences(Constants.PREFS_NAME, 0);
//Setup the ActionBar
composeImageButton = (ImageButton) findViewById(R.id.composeImageButton);
composeImageButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(prefs.getBoolean("isLoggedIn", false))
{
showShareActivity();
}
else
{
Intent intent = new Intent(TabHostActivity.this, LoginActivity.class);
startActivityForResult(intent, SHOW_LOGIN_ACTIVITY);
}
}
});
b = new Bundle();
//Setup the Tabs
Resources res = getResources(); // Resource object to get Drawables
tabHost = getTabHost(); // The activity TabHost
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
@Override
public void onTabChanged(String arg0) {
if(tabHost.getCurrentTab() == 0) //Check if the Watchlist tab was clicked so we can prompt login
{
//Toast toast = Toast.makeText(getApplicationContext(), "TRENDING = YES", Toast.LENGTH_SHORT);
//toast.show();
b.putBoolean("isTrendingTab",true);
}
else
{
Toast toast = Toast.makeText(getApplicationContext(), "TRENDING = NO", Toast.LENGTH_SHORT);
toast.show();
b.putBoolean("isTrendingTab",false);
}
}
});
TabHost.TabSpec spec; // Resusable TabSpec for each tab
Intent intent; // Reusable Intent for each tab
// Create an Intent to launch an Activity for the tab (to be reused)
intent = new Intent().setClass(this, ARActivity.class);
intent.putExtras(b);
// Initialize a TabSpec for each tab and add it to the TabHost
spec = tabHost.newTabSpec("trending").setIndicator("Trending",res.getDrawable(R.drawable.icon)).setContent(intent);
tabHost.addTab(spec);
// Do the same for the other tabs
intent = new Intent().setClass(this, WatchlistActivity.class);
intent.putExtras(b);
spec = tabHost.newTabSpec("watchlist").setIndicator("Watchlist",res.getDrawable(R.drawable.icon)).setContent(intent);
tabHost.addTab(spec);
tabHost.setCurrentTab(0);
}
private void showShareActivity()
{
Intent intent = new Intent(TabHostActivity.this, ShareActivity.class);
startActivityForResult(intent, SHOW_SHARE_ACTIVITY);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == SHOW_LOGIN_ACTIVITY)
{
//Login was successful so lets show the compose box!
if (resultCode == RESULT_OK) {
showShareActivity();
}
}
}
}
Here is the onResume in the Intent for one of my Activities:
public void onResume()
{
super.onResume();
Bundle bundle = getIntent().getExtras();
if(bundle.getBoolean("isTrendingTab"))
{
Toast toast = Toast.makeText(getApplicationContext(), "TRENDING!", Toast.LENGTH_SHORT);
toast.show();
}
else
{
Toast toast = Toast.makeText(getApplicationContext(), "WATCHLIST!", Toast.LENGTH_SHORT);
toast.show();
}
}
Upvotes: 1
Views: 841
Reputation: 13007
There's no need to use onTabChanged().
Here's how I do it in my app (with some of your values pasted in). I add the boolean flag to the intent, not an extra bundle:
Intent intent = new Intent(action) // see notes below about "action"
.setClass(this, ARActivity.class)
.putExtra("isTrendingTab", true);
TabHost.TabSpec spec = tabHost.newTabSpec("trending")
.setIndicator("trending", getResources().getDrawable(drawableId))
.setContent(intent);
tabHost.addTab(spec);
Then in onResume():
if (getIntent().getBooleanExtra("isTrendingTab", false)) {...
I found that when using the same class for multiple tabs, I had to differentiate them with a different action string in each Intent constructor, as above. Otherwise it wouldn't create a new activity when switching between tabs of the same class. You don't appear to be doing this (yet), so you can continue to leave it out. I thought I'd mention it, since passing isTrendingTab suggests you might be heading down this route.
Upvotes: 0
Reputation: 3936
The oncreate of your class ARActivity.class will be called before your onresume method of your tab host.
So do whatever the processing you want in your ARActivity.
Also since your tabHost.setCurrentTab(0); your starting tab will always be ARActivity.
And if you want to activate code depending your tab change, figure out which tab you are on using using the main tabhost ontabchange and use the id and then send a request to a inner broadcast receiver.
if (tabHost.getCurrentTab() == 0) {
i.setAction(getString(R.string.br_refresh_home_tab));
sendBroadcast(i);
} else {
i.setAction(getString(R.string.br_refresh_sports_tab));
sendBroadcast(i);
}
In your ARActivity,
protected class RefreshList extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(
getString(R.string.br_refresh_home_tab))) {
}
}
}
Upvotes: 0
Reputation: 17613
If i understood correctly the problem is that you try to put
b.putBoolean("isTrendingTab",true);
(or false) on the intent you're going to launch by detecting change.
That's the wrong approach.
The change event will always occur after the activity is launched, you should do the logic different. You have to rethink it.
Upvotes: 1
Reputation: 5435
Have you looked at Activity life cycle? The resume is being called when the activity is being created too and the line bundle.getBoolean("isTrendingTab") does not have a default value in case it has not been set yet...
Can you set it first in the onCreate to a default value? I think that is your issue. The code is a little sloppy. You are trying to pass variables to each activity but they still both exists in the tab activity. Views would be a better method so they all see the same variables in the tab activity.
Upvotes: 0