I created a project long ago using the TabActivity and ActivityGroup (deprecated now).
The question is may be simple but first I want to clarify the flow. I have 4 tabs in my Tabhost. I have used the following code to keep track of activity back stack.
MyActivityGroup.java
public class MyActivityGroup extends ActivityGroup {
public static Stack<String> stack;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (stack == null) {
stack = new Stack<String>();
}
push("1stStackActivity", new Intent(this, Home.class));
}
@Override
public void finishFromChild(Activity child) {
pop();
}
@Override
public void onBackPressed() {
pop();
}
public void push(String id, Intent intent) {
Window window = getLocalActivityManager().startActivity(id,
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
if (window != null) {
stack.push(id);
setContentView(window.getDecorView());
}
}
public void pop() {
if (stack.size() == 1) {
finish();
}
LocalActivityManager manager = getLocalActivityManager();
manager.destroyActivity(stack.pop(), true);
if (stack.size() > 0) {
Intent lastIntent = manager.getActivity(stack.peek()).getIntent()
.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Window newWindow = manager.startActivity(stack.peek(), lastIntent);
setContentView(newWindow.getDecorView());
}
}
}
Note here:
push("1stStackActivity", new Intent(this, Home.class));
Home.class is my first activity to be loaded in my HOME TAB
.
Here is a image which shows my flow and question also.
From Activity A
when I click on a button (browse by see fig Activity A). I start new activity like this
Intent intent = new Intent();
intent.setClass(getParent(), BookOverView.class);
MyActivityGroup activityStack = (MyActivityGroup) getParent();
activityStack.push("2ndStackActivity", intent);
This loads my Activity B
on the current HOME TAB
also also pushes the activity into the stack.
From Activity B when I click the any list item I'm starting a new activity in the same tab with the same code as above (3rdStackActivity)
. It start my Activity c
; when I press back KEY it works fine (i.e From "Activity C" --> "ACTIVITY B" --> ACTIViTY A ).
QUESTION
While standing on activity C
When I click the Home TAB
(See in fig Activity C) it should come back to my 1st activity (i.e Activity A).
Here is my HOME TAB
click event
getTabWidget().getChildAt(0).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (getTabHost().getCurrentTab() == 0) {
\\ Check If stack has at least more then one activity loaded.
if (MyActivityGroup.stack.size() > 1) {
//My code to clear the stack and load the 1st Activity goes here
// I tried Here to clear my stack
// But not sccessfull
}
} else {
getTabHost().setCurrentTab(0);
}
}
});
I am having problems while trying to clear my Stack and start the first home class.
Here is my MainActivity.java which extends the TabActivity
public class MainActivity extends TabActivity {
Context context = MainActivity.this;
TabHost tabHost;
TabSpec spec;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabHost = getTabHost();
// Android tab
tabHost.addTab(tabHost
.newTabSpec("Home")
.setIndicator("Home",
getResources().getDrawable(R.drawable.home))
.setContent(
new Intent(this, MyActivityGroup.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));
tabHost.addTab(tabHost
.newTabSpec("Now Reading")
.setIndicator("Now Reading",
getResources().getDrawable(R.drawable.now_reading))
.setContent(
new Intent(this, NowReadingActivityGroup.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));
tabHost.addTab(tabHost
.newTabSpec("Favorites")
.setIndicator("Favorites",
getResources().getDrawable(R.drawable.favorites))
.setContent(
new Intent(this, FavoriteActivityGroup.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));
tabHost.addTab(tabHost
.newTabSpec("Profile")
.setIndicator("Profile",
getResources().getDrawable(R.drawable.profile))
.setContent(
new Intent(this, ProfileActivityGroup.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));
tabHost.setCurrentTabByTag("Home");
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
@Override
public void onTabChanged(String tabId) {
Toast.makeText(context, "Changed", Toast.LENGTH_SHORT).show();
}
});
}
@Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
getTabWidget().getChildAt(0).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (getTabHost().getCurrentTab() == 0) {
if (MyActivityGroup.stack.size() > 1) {
}
} else {
getTabHost().setCurrentTab(0);
}
}
});
}
}
EDIT 2
I have done like this in my onTabClick event
if (MyActivityGroup.stack.size() > 1) {
while (!MyActivityGroup.stack.isEmpty()) {
MyActivityGroup.stack.pop();
}
Intent homeIntent = new Intent();
homeIntent.setClass(MainActivity.this, Home.class);
MyActivityGroup activityStack = (MyActivityGroup) getCurrentActivity();
activityStack.push("HomeActivity", homeIntent);
}
} else {
getTabHost().setCurrentTab(0);
}
This loads my 1st activity and also clears my activity stack. But the problem is that now whenever change my tab to any other tab and come back to the home tab and press back button it crashes. Here is the log cat.
05-31 14:15:42.769: E/AndroidRuntime(550): FATAL EXCEPTION: main
05-31 14:15:42.769: E/AndroidRuntime(550): java.lang.NullPointerException
05-31 14:15:42.769: E/AndroidRuntime(550): at my.islamic.books.lib.app.MyActivityGroup.pop(MyActivityGroup.java:120)
05-31 14:15:42.769: E/AndroidRuntime(550): at my.islamic.books.lib.app.MyActivityGroup.finishFromChild(MyActivityGroup.java:30)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.app.Activity.finish(Activity.java:3259)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.app.Activity.onBackPressed(Activity.java:1920)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.app.Activity.onKeyUp(Activity.java:1898)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.view.KeyEvent.dispatch(KeyEvent.java:1280)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.app.Activity.dispatchKeyEvent(Activity.java:2078)
05-31 14:15:42.769: E/AndroidRuntime(550): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1663)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
05-31 14:15:42.769: E/AndroidRuntime(550): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1687)
05-31 14:15:42.769: E/AndroidRuntime(550): at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1120)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.app.Activity.dispatchKeyEvent(Activity.java:2073)
05-31 14:15:42.769: E/AndroidRuntime(550): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1663)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.widget.TabHost.dispatchKeyEvent(TabHost.java:278)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
05-31 14:15:42.769: E/AndroidRuntime(550): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1687)
05-31 14:15:42.769: E/AndroidRuntime(550): at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1120)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.app.Activity.dispatchKeyEvent(Activity.java:2073)
05-31 14:15:42.769: E/AndroidRuntime(550): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1663)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2560)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2535)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.view.ViewRoot.handleMessage(ViewRoot.java:1867)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.os.Handler.dispatchMessage(Handler.java:99)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.os.Looper.loop(Looper.java:123)
05-31 14:15:42.769: E/AndroidRuntime(550): at android.app.ActivityThread.main(ActivityThread.java:3683)
05-31 14:15:42.769: E/AndroidRuntime(550): at java.lang.reflect.Method.invokeNative(Native Method)
05-31 14:15:42.769: E/AndroidRuntime(550): at java.lang.reflect.Method.invoke(Method.java:507)
05-31 14:15:42.769: E/AndroidRuntime(550): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
05-31 14:15:42.769: E/AndroidRuntime(550): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
05-31 14:15:42.769: E/AndroidRuntime(550): at dalvik.system.NativeStart.main(Native Method)
I have done like this in my HomeTab click event
getTabWidget().getChildAt(0).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (getTabHost().getCurrentTab() == 0) {
Log.i("not Null", "Not null");
if (MyActivityGroup.stack.size() > 1) {
while (!MyActivityGroup.stack.isEmpty()) {
MyActivityGroup.stack.pop();
}
Intent homeIntent = new Intent();
homeIntent.setClass(MainActivity.this, Home.class);
MyActivityGroup activityStack = (MyActivityGroup) getCurrentActivity();
activityStack.push("HomeActivity", homeIntent);
}
} else {
getTabHost().setCurrentTab(0);
}
}
});
Also on tabchange listner I have to clear my activityGroup stack also. so i done I like this
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
@Override
public void onTabChanged(String tabId) {
Toast.makeText(context, "Changed", Toast.LENGTH_SHORT).show();
while (!MyActivityGroup.stack.isEmpty()) {
if (MyActivityGroup.stack.size()==1) {
break;
}
MyActivityGroup.stack.pop();
}
}
});
Huh finally I found my head ach pill :)