I'm using TabActivity to implement tabs in my project and I want to communicate with activities of tabs and invoke some methods from tabActivity and I use method below:
CoachActivity activity=(CoachActivity) getLocalActivityManager().getActivity(mTabHost.getCurrentTabTag());
but activity is null. CoachActivity is Tab1 activity.
My code is a bit long so I don't post it here. I double checked everything and I'm sure the problem isn't about the setup of my tabs. I set the current tab and I checked that CoachActivity is created.
Related
I am trying to switch between tabs (ActionBarActivity) from within a fragment that is attached to one of the tabs.
I found this solution:
TabHost host = (TabHost) getActivity().findViewById(android.R.id.tabhost);
host.setCurrentTab(2);
but the app crashes when executed, with a NullPointerException at the second line. If I try and get any information about host, it all comes back null.
I don't have much Android experience, and so am unsure how to properly get a reference to the parent activity that holds the fragment.
EDIT
I'm not sure if this makes a difference, but I've moved the default SectionsPagerAdapter to a class of its own.
getActivity().getTabHost().setCurrentTab(2)
I'm writing a simple Fragment Activity with a FragmentPagerAdapter and two Fragments, where I need to show certain data in tab2 related to my selection in tab1. But the data in tab2 is never updated. Is there any common procedure for this?
You'll need a common holder for data, Activity object is most suitable, since it is parent of both fragments. All fragments can use getActivity() in onCreate(). You can call a method of Activity object to get selected data. The other fragment can similarly, call a method of Activity object to set selected data.
Solved. I just created one instance of each Tab and added an update() method on tab 2 which I called from Tab 1. I couldn't find a built in solution so I did it my way.
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 have a tabhost with three tabs. Each is an activity. I would like to have a button which is in the action bar, the bar along the top with common buttons, call functions of the tab which is active.
For example, an add function which could add something different to each tab depending on what tab was present when you clicked the button.
So, I am aksing how to call a function in Activity A from the tabHost.
And if that wont work, perhaps I can update the database from the tabhost and then refresh the tab content. Would that be easier?
Thank you all for you time and support.
I used the following code within my TabActivity class to switch tab then call a public method defined in the activity of the tab:
getTabHost().setCurrentTab(0);
Activity MyActivity = this.getCurrentActivity();
MyActivity.myMethod();
Hopefully helpful to someone looking for the answer to this question.
Hi Just stumbled across this, not sure if you already found a solution?
I solved this myself recently. I was previously getting around the problem by raising a intent broadcast from the tabhost activity and receiving the broadcast within the sub tab activity. This worked for me but i was sure there is a "better" way.
A cleaner way is to achieve it with something like this:
might have something like this:
parentActivity - my "container"
activity which holds the TabHost
childActivity - my tab activity
which holds tab content and the
public method i want to call from
parentActivity
within parentActivity:
// a method used for onclick callback or whatever you need. within parentActivity (tabhost)
// this will get call huzzah() in the first tab - getChildAt(0)
onClick () {
childActivity childAct = (childActivity) getTabHost().getChildAt(0).getContext();
childAct.huzzah();
}
within childActivity:
// a public method for the parent activity to access
public void huzzah() {
Log.d("stuff", "huzzah() called");
}
Note: Another alternative i believe is to redesign to use views instead of activities in your tabs. This is a better overall alternative because IIRC memory wise you are only storing 1 activity on the stack rather than (n * tabs) number of activities
Hope that helps
Edited as per Peter O request:
I am on API 10, and this problem gave me a huge headache. I have 3 tabs, I want all of them to be aware of changes on the other. The problem I had was that once the activity for a tab is started, there seemed to be no call back so the activity understood the user switched to a different tab, and thus needed to do work to be sure its state was correct.
I found lots of answers to this problem, but none seemed to work.
The one that I finally got to work was the solution offered as #3 for this thread --but it too is confusing. I found that the getTabHost().setCurrentTab(0); does nothing; I implemented OnTabChangeListener() to call a function that used getTabHost().setCurrentTab(0); however, I found the getTabHost().setCurrentTab(0); caused the app to crash for any tab other than 0--e.g, If I chose tab B (index=1) then called getTabHost().setCurrentTab(1); the app crashed.
Using the Debugger, I found the call this.getCurrentActivity(); always returns the activity associated with the tab which the user clicked on--calling getTabHost().setCurrentTab(); did not change that fact, and caused the app to crash.
So I got rid of it and I can now call this.getCurrentActivity(), then call a method in the Actvitity class returned by that call --this lets the activity know it has to update it's state--in my case it does this using the application object.
The above way of calling the method will not work,
Here is the quick answer for the above problem:
getTabHost().setCurrentTab(0);
Activity myActivity=getCurrentActivity();
String name=((Tab1) myActivity).et1.getText().toString();
Here the above code is given in the onclick() method of the activity which has TahHost
where Tab1 is the secondactivity and et1 is the identity of the edittext in the Tab1 activity so you can get all the value of the different fields like this individually.
I have an Android application which has four tabs (I use a main TabActivity with TabHost and TabSpecs).
In one of my sub activity (activity opened in a tab), i need to open a tab not by clicking on the tab title and i don't know how to do this.
For example, i have a button in my activity and when i click on it, it opens a different tab.
For the moment, it is what i do:
Intent intent = new Intent(myActivity.this, myTabActivity.class);
intent.putExtra("ComeFrom", true);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Then in the TabActivity, if i get true reading the "ComeFrom" extra i open the wished tab but the problem is that it kills all the other activies. So, if someone knows a better (cleaner) way to do that trick, please tell me...
Found an easier (I think) answer:
on the TabActivity declare a public, static and self variable and populate it on the onCreate method. F.e.:
public class TheActivity extends TabActivity {
public static TheActivity self;
...
#Override
public void onCreate(Bundle savedInstanceState) {
self=this;
on any Activity running in a tab, when you want to change the one shown on your app. you can do this:
TabHost tabHost = TheActivity.self.getTabHost();
tabHost.setCurrentTab(0);
Worked ok for me, hope serves someone else!
You have to use TabHost's "setCurrentTab(...)" for that. In one of my projects, I created a static method in the main Activity (the one with the TabHost), named "swtichToTab(int tab)". In my subactivites (those inside the tabs) could then just call "MainActivity.switchToTab()" to trigger switching.
It may not be the cleanest method, I'm sure you can achieve this using broadcast intents too.
You can create a BroadcastReceiver and send a broadcast with the index of the tab as extra
You can use views instead of activities for the content of the tabs. This way, the code is simpler and doesn't use as much memory. Plus, you then can use the setCurrentTab(tabIndex) method to easily switch between views.
I have a simple tutorial here. It has a tab activity with a list and map view. When you you click on an item in the list, the activity dynamically goes to the map view (using the setCurrentTab(tabIndex) method). You can easily modify this to have a button switch views.