I'm trying to notify my activity when the relevant tab is selected.
Consider the follwoing situation:
MainActivity:
// Create an Intent to launch an Activity for the tab (to be reused)
intent = new Intent().setClass(this, HomeActivity.class);
// Initialize a TabSpec for each tab and add it to the TabHost
spec = tabHost.newTabSpec("home").setIndicator("Home",
res.getDrawable(R.drawable.ic_tab_home))
.setContent(intent);
tabHost.addTab(spec);
// Do the same for the other tabs
intent = new Intent().setClass(this, ProceduresActivity.class);
spec = tabHost.newTabSpec("procedures").setIndicator("Procedures",
res.getDrawable(R.drawable.ic_tab_checklist))
.setContent(intent);
tabHost.addTab(spec);
Now, the first time my second tab is selected, the onCreate method of ProceduresActivity is called.
What I want to be alble to do is, within ProceduresActivity, to be notified whenever tab 1 and tab 2 (mine) are selected.
I tryed overriding onPause and onResume within ProceduresActivity however those are only called when the MainActivity is pasued / resumed and not when I switch tabs...
So in other words I want ProceduresActivity to do something whenever the user selects second tab, and not only the first time.
Can someone help me please?
Thanks, Luca.
Hmmm. This seems like it might be a little difficult (I'm not even sure it's possible) to achieve. There are two ways I can see that you could achieve the same results.
The first way is by have the first tab refresh it's data/information when the user goes back to it. This can be done in the onResume() and by adding a flag to it. Pretty simple.
If you need your activity to do something that will take some time, you can make an ActivityGroup. It's basically a controller for multiple activities. It starts them all at the same time and just chooses which one is shown at once. This means that (in your case) both activities would be running, but only one would be shown. When you want the first tab to do something while the user is using the second tab, you go to the ActivityGroup (which is like a controller) and tell it to do whatever you want with the first tab.
The only problem I see with the ActivityGroup route is binding it to your tabs, but there are many workarounds for this.
Maybe this can help you, i use this to perform an action when the tabs change. But maybe you can alter it to do a specific action with every tab?
getTabHost().setOnTabChangedListener(new OnTabChangeListener() {
public void onTabChanged(String tabId) {
//TODO, action to be performed
}
}
});
Related
My android app has a tabhost with 5 tabs.
The problem is when I use setCurrentTab(2).Android start activity on the first tab then it start activity on the third tab. I find out that when I use method addTab of TabHost class,it also start activity in the first tab.
if (mCurrentTab == -1) {
setCurrentTab(0);
}
I read my thread in stackoverflow like:https://stackoverflow.com/questions/9978231/android-when-i-put-setcurrenttab-for-tabhost-it-loads-the-first-added-tab-ac
Cause My client requirement, I can't reorder tabs.When the TabActivity start,I only want start activity in the third tab ,How can I do that?
If you want to prevent loading of your fragment then put your in onVisible. Use this class UserVisibleHintFragment
It will help you to prevent advance loading.
use setCurrentTab(2) after addTab methods. Better use it at the last line of onCreate of your TabActivity
As you can see from the pic that I attached,when app android starts,it will launch activity from third tab and it read user's mail address in android device then post it to server.After that server will return user_id,I will save user_id in app memory.When user click on first tab which has an activity that contain a webview ,I will get this user_id from app memory then pass to url of webview.
If the activity in the first tab start first, the user_id will be blank.
Your question does not tell us how you are constructing your tabs. If you can post the bit of code on how you are building the tabs then we may be able to help you better.
Below is a simple way of building the tabs using TabHost. The tabHost.setCurrentTab(2); below just works fine...
TabHost tabHost = getTabHost();
// Tab for About
TabSpec aboutspec = tabHost.newTabSpec("About");
aboutspec.setIndicator("About", getResources().getDrawable(R.drawable.icon_about_tab));
aboutspec.setContent(new Intent(this, AboutActivity.class));
// Tab for Contacts
TabSpec contactsspec = tabHost.newTabSpec("Contacts");
contactsspec.setIndicator("Contacts", getResources().getDrawable(R.drawable.icon_contacts_tab));
contactsspec.setContent(new Intent(this, ContactsActivity.class));
// Tab for Resources
TabSpec resourcesspec = tabHost.newTabSpec("Resources");
resourcesspec.setIndicator("Resources", getResources().getDrawable(R.drawable.icon_resources_tab));
resourcesspec.setContent(new Intent(this, ResourcesActivity.class));
// Adding all TabSpec to TabHost
tabHost.addTab(aboutspec);
tabHost.addTab(contactsspec);
tabHost.addTab(resourcesspec);
// set the current tab to Resources
tabHost.setCurrentTab(2);
Hope this helps you resolve your problem.
I have an app that can create tabs dynamically. And when I create a tab I initiate an activity as an intent. Like so:
private void addTab(Context packageContext, Class<?> newClass, TabHost mTabHost, String tabId, String tabLabel){
// newClass is my Activity class that I want to start in the tab
Intent intent = new Intent().setClass(packageContext, newClass);
TabHost.TabSpec spec;
spec = mTabHost.newTabSpec(tabId).setIndicator(tabLabel)
.setContent(intent);
mTabHost.addTab(spec);
mTabHost.setCurrentTabByTag(tabId);
}
Pretty standard. And it works great. Now, suppose that I have a button (or menuitem, whatever) in the activity that I instantiated inside of my tab. When the user presses this button, I want the activity, and the tab it is inside of, to be removed and destroyed.
I can't seem to find a simple way to do this. I have found the TabHost.clearAllTabs() function, but this destroys all tabs and activities, I just want to remove one.
Someone suggested I save a list of all Tabs that I have opened, and then call clearAllTabs(), after which I recreate all of my other tabs except for the one I don't want.
Something like this:
public static ArrayList<TabHost.TabSpec> list = new ArrayList<TabHost.TabSpec>();
I add this line to my addTab() function so that every tab I create is remember in my ArrayList:
list.add(spec);
And then when I want to remove my tab I run this function:
public static void removeTab(){
list.remove(list.size()-1); // remove it from memory
mTabHost.clearAllTabs(); // clear all tabs from the tabhost
for(TabHost.TabSpec spec : list) // add all that you remember back
mTabHost.addTab(spec);
}
This removes my tab from my ArrayList, removes all tabs, then recreates all the tabs remaining using my ArrayList. In theory it should work, but I get the following error when I try call this function:
FATAL EXCEPTION: main
java.lang.NullPointerException
at android.widget.TabWidget.setCurrentTab(TabWidget.java:342)
at android.widget.TabWidget.focusCurrentTab(TabWidget.java:366)
at android.widget.TabHost.setCurrentTab(TabHost.java:323)
at android.widget.TabHost.addTab(TabHost.java:216)
at com.example.myapp.TabManager.removeTab(QuikBrowser.java:86)
at com.example.myapp.TabManager.TabWindow.onOptionsItemSelected(TabWindow.java:91)
at android.app.Activity.onMenuItemSelected(Activity.java:2205)
For some reason, when adding a tab, it attempts to set the current tab, and it hits a null pointer exception.
If you guys could suggest another way of achieving what I want to do, or a way to fix my current method, I would appreciate it.
Try changing current tab to 0.
Something like:
getTabHost().setCurrentTab(0);
getTabHost().clearAllTabs();
I was reading that calling clearAllTabs(); will throw a nullpointerexception if you don't set the tabhost to the first tab (.setCurrentTab(0)) before calling (.clearAllTabs())
Also this answer may help? (How to remove tab from TabHost)
I would suggest a different approach. You can use an ActivityGroup to build your own TabControl. As you are using normal Buttons (or similar controls just as you like) you can easyly arrange/create/remove them as needed.
I can't dump the whole code here but that is basically what I did when I had the same problem:
Create an Activity inherited from ActivityGroup
Place a ViewGroup in your layout where you want to show the sub-activities
Setup your buttons as needed (LinearLayout works fine with a variable count of buttons)
Start activites thru getLocalActivityManager().startActivity() as needed
You can now add/remove buttons as you like. The Activites follow the Android lifecycle so you don't have to delete them yourself.
You might have to implement onBackPressed on your ActivityGroup to properly handle the history but that depends on the project.
I stuck with one problem. actually my screen consists of two tabs. under each tab i have 4-4 activity. i m displaying each activity with the help of activity group in single tab.
Suppose i m in 1st tab which is active. Under this tab i m on 2nd activity(e.g first activity is list activity and second activity gives the result from the first activity)
I want when i click on 1st tab again it should show me the first activity again without using back button.?
I had that problem sometime ago... and that happens because people like to emulate the bottom bar of the iPhone. Android apps don't work that way and using Activity Group is always a signal of a poor UI design.
Anyway, this is what I did:
tabHost.setCurrentTabByTag(TAB_ID_MORE);
tabHost.getCurrentTabView().setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if( MoreGroupActivity.self != null ) {
MoreGroupActivity.self.reset();
}
tabHost.setCurrentTabByTag(TAB_ID_MORE);
}
});
tabHost.setCurrentTabByTag(TAB_ID_HOME);
The above code is not generic, but will give you an idea of the workaround I found. Let me explain:
tabHost.setCurrentTabByTag(TAB_ID_MORE); I use this to select a current tab (in my case, the main tab was another tab, so I had to to this and then change back with tabHost.setCurrentTabByTag(TAB_ID_HOME);). I mean, in my case, the only tab with that behavior was the "More" tab.
tabHost.getCurrentTabView().setOnClickListener this allows you to put a listener to the tab. As you may have already noticed, using OnChangeTabListener is not an option in this kind of situation.
MoreGroupActivity.self Inside my group activity, I had a static field referencing the group activity it self. This kind of hacks are common while using this crappy approach.
tabHost.setCurrentTabByTag(TAB_ID_MORE); this reset the tab so that it can change back to your first activity.
When you are adding a new TabHost.TabSpec to the TabHost
use
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_SINGLE_TOP);
to the respective Intent
To put it simply. From a context menu on a TabActivity how can I initiate executing the intent for the current tab? I am trying to force a refresh.
The tabs all initiate activities displaying a subset of people names. While in one list you call up an edit activity which allows you to associate the name to one of the other lists in the TabHost. Using the back button to get back to the tabhost (onResume fires) and the list has not updated. I would like to have a context menu item to refresh the current tab.
I know about using one activity for all the views in a tabhost but for many reasons I have not chosen that method.
You can also try adding a flag to the intent when you set up the tabs in the first place.
Intent i = new Intent().setClass(this, YourClass.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
TabHost.TabSpec spec = tabHost.newTabSpec("name")
.setIndicator("Class",res.getDrawable(R.drawable.ic_tab_something))
.setContent(intent);
Tabhost tabHost.addTab(spec);
I think due to the activity lifecycle, you will have some problems 'restarting' the activity (Activity lifecycle - startActivity()) - if you were to move any logic you have inside the onCreate method into another method, then call the method from onCreate and onResume, so it rebuilds the tab content for you.
Alternatively you could add a menu item to call this method, so onCreate calls the logic method on first run, and your user can call it from the menu to refresh the contents.
I have created two tabs, say TAB1 and TAB2. For TAB1, i have loaded one Activity, say ActivityOne, into TAB1 as
Intent intent = new Intent(this,ActivityOne.class);
TabHost.TabSpec spec = getTabHost().newTabSpec("ActivityOne")
.setIndicator("Activity One",getResources().getDrawable(R.drawable.artists)).setContent(intent);
getTabHost().addTab(spec);
This ActivityOne has extended the ActivityGroup and i added one button in this activity. By clicking on this button it will call another activity, say ActivityOne_One, as
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(ActivityOne.this,ActivityOne_One.class);
replaceContentView("ActivityOne_One",intent);
}
public void replaceContentView(String id, Intent intent){
View view = this.getLocalActivityManager().startActivity(id, intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();
this.setContentView(view);
}
When we click on that button ActivityOne_One will be launched under same TAB1. In this application i have two problems:
1) If i want to go back to ActivityOne under same TAB1 by using traditional BACK button on emulator it is not working..
2)ActivityOne_One is launching with no animation(like sliding from right to left) effect.
If anyone know about any one of these, give your advice..
Thanks,
venu
I have found the solution for my question. The following blog gave me a route for this
http://ericharlow.blogspot.com/2010/09/experience-multiple-android-activities.html
see this link which may help you out with this. http://blog.henriklarsentoft.com/2010/07/android-tabactivity-nested-activities/
i have implemented what is advised in the link i provided. it works OK, but it is quirky and does not always redirect you BACK like you would expect. i have found that you must implement your own custom tabs to really get this desired effect.