Firstly, Im new to android but have years of various other programming experience on unix, windows,but not with Java or android.
Im wanting to display a tab with 3 tabs, each having a different layout file (which works).
Im working on displaying a "blank" template and then the data is retrieved from an XML file once the user points a setting to one (i.e. via shared preferences).
My problem is that the function populateXMLCharacter is never called (using breakpoints). The tab activity always displays "", which is a strig the string.xml.
Actually putting a breakpoint in the oncreate function never gets called either. Ive tried using a call to populateXMLCharacter in onResume, but it too never gets called.
Im thinking its because of the call to the tab:
Resources res = getResources(); // Resource object to get Drawables
TabHost tabHost = getTabHost(); // The activity TabHost
TabHost.TabSpec spec; // Resusable TabSpec for each tab
// Do this and the same for all tabs
spec = tabHost.newTabSpec("Description").setIndicator("Description",
res.getDrawable(R.drawable.android)).setContent(R.layout.tab_harp_description);
tabHost.addTab(spec);
Should I be using an intent? I thought the layout was created in a seperate function (in this case harpCSDescription.java and then this allows that activity to be inserted into the tabhost?
other functions:
public class harpcsDescription extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView (R.layout.tab_harp_description);
}
//#Override
protected void onResume()
{
// NOW WE ADD DATA TO THE TEMPLATE
populateXMLCharacter();
}
public void populateXMLCharacter()
{
Ive tried using intents in the following manner but it simply crashes before any breakpoints are reached.
http://developer.android.com/resources/tutorials/views/hello-tabwidget.html
Can some one please guide me to what I should be doing to create an activity with data that is retrieved AFTER the tab is created?
I think you need an intent. To attach an activity to a tab, write the following in the tab host:
Intent intent = new Intent(this, MyActivity.class);
and then in the tab spec write:
tabSpec = tabHost.newTabSpec("name").setIndicator(this.getString(R.string.name)).setContent(intent)
Then in the MyActivity class, you can specify the layout and load the XML data to populate the tab in the onCreate() method. You can use a different activity for each tab.
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 a Tabbed Activity, which contains three tabs, which are initialized as follows:
TabHost tabHost = getTabHost();
TabSpec porabaspec = tabHost.newTabSpec("Tab1");
porabaspec.setIndicator("Tab 1", getResources().getDrawable(R.drawable.icon_tab1));
porabaIntent = new Intent(this, PorabaActivity.class);
porabaspec.setContent(porabaIntent);
...
tabHost.addTab(porabaspec);
...
This Tabbed activity has a button event that calls an Async Task which executes a second activity that returns some data back to the Tabbed Activity. At this point I would like to update the Tab 1 Activity (porabaIntent) with this new data that I received.
How do I do this? If I pass the bundled data when I initialize the tabs, the data won't update when it's changed, however if I try and send it in the onPostExecute() method of the Async Task I cannot seem to bind it to porabaIntent.
I found that the solution to this problem is to use static variables in the main tabbed activity, which can be accessed and modified by its child tabbed activites.
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.
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.
Currently I have a TabHost implemented with 3 tabs each containing a separate activity. My question is how do I switch between tabs from within one of the activities that is located inside the tab host. I've looked everywhere and have been unsuccessful in finding a real answer to this problem.
After a long time of battling with this problem I've been able to find a solution to switching tabs when using activity based tabs.
In the parent activity class where the tabhost is created I implemented a method like the one below:
public void switchTab(int tab){
tabHost.setCurrentTab(tab);
}
Inside of the tab that I would like to be able to switch internally to another tab I created the method below:
public void switchTabInActivity(int indexTabToSwitchTo){
MintTrack parentActivity;
parentActivity = (MintTrack) this.getParent();
parentActivity.switchTab(indexTabToSwitchTo);
}
If you would like a good example of this code, you can take a look at my MintTrack project here and here.
As a side note, please be very careful when deciding whether to use view or activity based TabHost.
Activity based tabs are great because they can be separated into there own XML file. Activities can also be organized into there own Java file instead of being cluttered into one. That being said some of the things you would think would be easy become complicated with activity based tabs. Its hard to pass information between tabs without creating overhead. Activity based tabs also use more memory/CPU time as they have the overhead of the Activity around each of them. Please consider this and the many more trade offs before diving into using an Activity based TabHost. I know now that I would personally go with a view based TabHost if I ever used them again.
I encountered the same problem. While a single activity for all tabs would be better, sometimes taking the easy way out is the rational choice.
To avoid creating a new tab activity when a tab wants to change to another tab, I put this in my AndroidManifest.xml:
<activity android:name=".MyTabsActivity"
android:label="Tabs!"
android:launchMode="singleTask">
Send an intent with the tab you want:
class OneTabContentActivity {
void switchTab() {
final Intent intent = new Intent(mContext, MyTabsActivity.class);
intent.setAction("Switch to tab 1, please");
mContext.startActivity(intent);
}
class MyTabsActivity {
#Override
protected void onNewIntent (Intent intent) {
super.onNewIntent(intent);
getTabHost().setCurrentTab(1);
}
}
This solution has drawbacks but I'm not clear over the details. Someone else might know enough to point them out.
First, I set a method to my main class, which extends TabActivity let's call it "MainActivity"
public TabHost getMyTabHost() { return tabHost; }
Then, I add my tab activity class;
MainActivity ta = (MainActivity) this.getParent();
TabHost th = ta.getMyTabHost();
th.setCurrentTab(0);
It worked for me.
Step #1: Replace the tabs-holding-activities with tabs-holding-views by using a better form of setContent() on TabSpec
Step #2: Call setCurrentTab() on your TabHost from within your single Activity
I have yet to see any benefit to having an Activity be the content of a tab rather than a simple View. Having an Activity as the content of the tab wastes CPU time and memory (and, hence, battery life) and makes things like you're trying to do much more difficult.
I had a slightly different problem and thought I'd add this for anyone else facing a similar situation. I have an activity-based tabbed application and one of the tab activities launches another activity which is not controlled by the tabHost. I needed to have a button on this activity finish() (ie: return back to the main Tab view) and switch to a different tab at the same time.
I decided to handle it with a BroadcastReceiver. In the class that sets up the TabHost, I added this class:
class ChangeTabReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "ChangeTabReceiver: received");
TabHost tabHost = getTabHost();
tabHost.setCurrentTab(1);
}
}
..then defined the vars:
ChangeTabReceiver changeTabReceiver;
IntentFilter changeTabFilter;
..then added to onCreate():
changeTabReceiver = new ChangeTabReceiver();
changeTabFilter = new IntentFilter(myApplication.CHANGE_TAB);
registerReceiver(changeTabReceiver, changeTabFilter);
Finally in the new activity when you want to close that activity and switch the tabs, do this:
Intent intent = new Intent(myApplication.CHANGE_TAB);
this.sendBroadcast(intent);
this.finish();
Of course you could make a method to switch to various tabs by passing the tab index -- but in my case this behavior only occurs in one activity so I decided to keep it simple...
public void switchTab(int index){
MintTrack ParentActivity;
ParentActivity = (MintTrack) this.getParent();
ParentActivity.getTabHost().setCurrentTab(index);
}
I just put a public static TabHost tabHost;
in my TabActivity.
Then from any other tab I can do a MyTabActivity.tabHost.setCurrentTab(tabNumber);
Works fine for me (but I wish I'd used Fragments from the start.. I was just following the Tab tutorial in the Android documentation and working from there)