Here is the scenario:
I have an activity with 4 tabs, each tab with a different intent, each intent with a different activity.
Works perfectly.
What I need is, to somehow change the intent on one of the tabs.
It would be as simple as adding extra parameters to the Intent that is used on the TabSpec.setContent(intent), but I have not found a way to retrieve that intent to change it.
The specific action I'm trying to do is: from another activity (that is inside the content of another tab) I call it's parent (the TabActivity) to open a different tab AND add some custom data to that tab's activity.
I can change the tab without a problem, but I haven't found a way to pass the extra parameters from one activity to the other, since the original intent used to create the TabSpec had no extra parameters.
Am I approaching this in the wrong way?
Is there a way to replace the TabSpec content's intent?
Thanks !
If you are just trying to find a way to pass values between activities you can override the Application class.
Way to use app context.
Extend the application class and add your values as its attributes. In any activity, if you call the below code, it will return a singleton.
MyApplication appContext = (MyApplication) getApplicationContext();
To make this work you need to add this to the application tag of the manifest file
android:name=".MyApplication"
This method is used to pass values around the app when sending through intent is not possible.
To remove the tab, you will need to use the clearAllTabs() method and add the tabs again. The above code should be better.
In my case I'm storing a reference to an intent in the TabActivity
mGalleryTabIntent = new Intent(this, AnActivity.class);
spec = getTabHost().newTabSpec(TAB_GALLERY).setIndicator(res.getString(R.string.footer_gallery),res.getDrawable(R.drawable.gallery_icon_sel)).setContent(mGalleryTabIntent);
public Intent getStoredTabIntent(){
return mGalleryTabIntent;
}
Then, when from a child I want to navigate to another tab passing an Extra along with the Intent
MainTabActivity parent = (MainTabActivity)getParent();
parent.getStoredTabIntent().putExtra(AnActivity.START_VIEW, AnActivity.PAGE_TWO);
//Navigate to the tab
parent.getTabHost().setCurrentTabByTag(AnActivity.TAB_GALLERY);
Then, in AnActivity's onCreate
Bundle extras = getIntent().getExtras();
if(extras != null && extras.containsKey(START_VIEW)){
switch (extras.getInt(START_VIEW)) {
case PAGE_TWO:
doSomething();
break;
default:
break;
}
//Erase the Extra so that navigating to this Tab always displays the standard view unless specified otherwise
MainTabActivity parent = (MainTabActivity)getParent();
parent.getStoredTabIntent().putExtra(AnActivity.START_VIEW, "");
}else{
doStandardStuff();
}
The Application solution is also good, but I don't think I'll be needing it for anything else, thus I'd rather stick with Activities.
TabSpec tabspec1;
private void createTabHost() {
// initialize tabHost
tabHost = (TabHost) this.findViewById(R.id.tabhost1);
tabHost.setup(this.getLocalActivityManager());
// create tab1
Intent intent = new Intent(this, AnotherActivity.class).addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("myData",
ObjData);
tabspec1 = tabHost.newTabSpec("tab1")
.setIndicator(Utilities
.prepareTabView(this, "Title"))
.setContent(intent);
tabHost.addTab(tabspec1 );
// create tab2
...
}
method that changes the content of that activity placed in your tab:
private void reloadTabSpec1() {
Intent i = new Intent(this, AnotherActivity.class).addFlags(
Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("myData", ObjData);
tabspec1.setContent(i);
// needed for refresh :(
tabHost.setCurrentTabByTag(tabspec2.getTag());
tabHost.setCurrentTabByTag(tabspec1.getTag());
}
Related
I want to know if there is a way that I start an activity instead of launching a fragment on tabhost tab select.
What I want to acomplish if to launch an activity where the user can write a post and then save, why I want this? because when I want to edit I launch an activity and I don't want to have 2 classes that do the same thing with a little difference, and also the tab on the bottom uses so much space that leave my form area tiny.
My code actually looks like
#Override
protected void onCreate(Bundle savedBundleState) {
mTabHost.setup(getBaseContext(), getSupportFragmentManager(), R.id.realtabcontent);
// This starts the HomeFragment
mTabHost.addTab(newTabSpec("tabHome", R.layout.tab_home), HomeFragment.class, null);
// This throws an error
mTabHost.addTab(newTabSpec("tabPost", R.layout.tab_post));
mTabHost.setOnTabChangedListener(this);
}
private TabSpec newTabSpec(String tag, int layout) {
View view = getLayoutInflater().inflate(layout, null);
return mTabHost.newTabSpec(tag).setIndicator(view);
}
#Override
public void onTabChanged(String tabId) {
if (tabId == "tabAddPublication") {
startActivity(new Intent(getBaseContext(), PostActivity.class));
}
}
I got this error
you must specify a way to create a tab content
Regards
From the Documents
public TabHost.TabSpec setContent (Intent intent)
Specify an intent to use to launch an activity as the tab content.
You need to set the content for TabSpec
Intent postActivityIntent = new Intent(this, PostActivity.class);
mTabHost.newTabSpec(tag).setContent(postActivityIntent);
Hope this helps.
I have two tabs A, B with corresponding TabActivityA and TabActivityB. I have a third ActivityA1 which is not on the tab but is an intermediate activity coming from ActivityA.
Here is the code in sequence
public class AndroidTabLayoutActivity extends TabActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabHost tabHost = getTabHost();
// Tab for Home
TabSpec homeSpec = tabHost.newTabSpec("Home");
homeSpec.setIndicator("Home", getResources().getDrawable(R.drawable.icon_home_tab));
Intent homeIntent = new Intent(this, TabActivityA.class);
homeSpec.setContent(homeIntent);
// Tab for my cases
TabSpec helppec = tabHost.newTabSpec("Help");
// setting Title and Icon for the Tab
helppec.setIndicator("Help", getResources().getDrawable(R.drawable.icon_cases_tab));
Intent helpIntent = new Intent(this, TabActivityB.class);
mycasesspec.setContent(helpIntent);
// Adding all TabSpec to TabHost
tabHost.addTab(homeSpec); // Adding home tab
tabHost.addTab(help); // Adding help tab
}
ActivityA1 extends Activity
{
}
TabActivityA extends ActivityGroup
{
.....
Intent nextScreen = new Intent(getApplicationContext(), ActivityA1.class);
View view = getLocalActivityManager().startActivity("ActivityA1", nextScreen.addFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)).getDecorView();
setContentView(view);
}
Note: I am doing this because I want to show the same tabs for ActivityA1
This does show the tab (Home and Help) on ActivityA1, however on clicking the Home tab I want the user to go to TabActivityA but right now it is staying on ActivityA1 only.
Any help will be greatly appreciated!!
Ok I think I understand what you are asking now, simply keep an arrayList of View, add to this list before you call SetContentView, then when you are ready to go back to the previous View do SetContentView(list[count - 1]), also make sure you remove the previous View and dispose of it or it will hang around in memory forever...
I have 4 tabs in a page view when i click first time on tab it executes it oncreate() method of corresponding tab and when i go to other tab on same page and again click on previous clicked tab then its oncreate() method not execute why?why it is not work as button click means each time i click its oncreate() method run.
my code for tab activity class is below
intent1 = new Intent().setClass(this, keywordxmlparsing.class);
spec1 = tabHost.newTabSpec("Activity2").setIndicator("keyword/ search...").setContent(intent1);
tabHost.addTab(spec1);
intent2 = new Intent().setClass(this, filter.class);
spec2 = tabHost.newTabSpec("Activity1").setIndicator("filter search").setContent(intent2);
tabHost.addTab(spec2);
intent3 = new Intent().setClass(this, OpeningToday.class);
spec3 = tabHost.newTabSpec("Activity3").setIndicator("opening today").setContent(intent3);
tabHost.addTab(spec3);
intent4 = new Intent(keywordresulttab.this,Map.class);
spec4 = tabHost.newTabSpec("Activity4").setIndicator("Map").setContent(intent4);
tabHost.addTab(spec4);
dear if i use
#Override
public void onTabChanged(String label) {
// TODO Auto-generated method stub
if(label == "Activity2") {
}
try{
if(label == "Activity4") {
Intent intent4;
intent4 = new Intent(keywordresulttab.this,Map.class);
startActivity(intent4);
Log.i("suiuawhd","maps class");
}
then can i go to other activity means using
intent4 = new Intent(keywordresulttab.this,Map.class);
startActivity(intent4);
we can load again activity on tab click??then what to written in place of
tabHost.addTab(spec3);
intent4 = new Intent(keywordresulttab.this,Map.class);
spec4 = tabHost.newTabSpec("Activity4").setIndicator("Map").setContent(intent4);
tabHost.addTab(spec4);
Tabs that contain activities are implemented by means of ActivityGroup. When someone changes a tab, corresponding activity is created only if necessary. When you move to any tab for the second time, the activity is already existing and only its window is shown.
You should use instead:
TabHost.setOnTabChangedListener(TabHost.OnTabChangeListener l)
TabActivity with separate activities as a content are a little bit tricky so maybe you should consider using Views instead. If not you can use the following code to access all activities from each other:
get instances of content activities from TabActivity:
TabActivity.getLocalActivityManager().getActivity(String name)
where name is given in newTabSpec() method.
get instance of TabActivity from content activities:
FirstTab.getParent()
Using these method you can create communication between all activities (using proper casting). For example:
public void onTabChanged(String label) {
if(label.equals("Activity2")) {
SecondActivity sa = (SecondActivity) getLocalActivityManager().getActivity(label);
sa.modifySomething();
}
}
If you want to change activities under tabs you should use:
tabHost.clearAllTabs ()
and create all TabSpecs once again.
In the android oncreate() lifecycle called once in life of the activity (like constructor), as you press again that time the activity is alive and in memory so it will not call onCreate again.
so you have to implement
TabHost.setOnTabChangedListener(TabHost.OnTabChangeListener l).
I am trying to make an application which have 4 tabs at the bottom of the screen.
All of them contain Activity (Intent).
And I want to navigate any of the Activity to another activity. But want to keep the TabWidget visible.
Let me know as quickly as possible if you know about it.
Shaiful
The problem of error occuring due to the replacement of activities can be solved in the following manner.
First Let us understand the flow:
We have in a Tab host , activity (say a list) from which we need to go to the next Activity (say details for the clicked item) under the same tab. For this we can use the concept of replacing the activity.Also setting the flags for the tab selected and other for knowing that details are being shown now
When we press back we should get the previous activity under the same tab.For this instead of again replacing the activity we can refresh the tab while using the particular flag for tab which was selected. Also if flag for show details is true we'll go the the list in the same tab or else we will go the activity before the tabwidget (normal use of onBackPressed)
The code can be as follows..
For going from list to details...
(This can be in the onClickListener)
private OnClickListener textListener = new OnClickListener() {
#Override
public void onClick(View v) {
Constants.SHOW_DETAILS = true;
Intent intent = new Intent(context, DetailsActivity.class);
replaceContentView("activity3", intent);
}
};
public void replaceContentView(String id, Intent newIntent) {
View view = ((ActivityGroup) context)
.getLocalActivityManager()
.startActivity(id,
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
.getDecorView();
((Activity) context).setContentView(view);
}
When back pressed is done we override on BackPressed in each of the Activity under the tab to go to the list again from the details screen
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
if (MathHelper.SHOW_DETAILS) {
Log.e("back", "pressed accepted");
Constants.LIST_ACTIVITY = 1;
Constants.SHOW_DETAILS = false;
Intent intent = new Intent(this, Tab_widget.class);
startActivity(intent);
finish();
}
}
The most important part here is
Constants.LIST_ACTIVITY = 1; it indicates which tab we are in. so the corresponding activities will have its value as 0,1,2...etc
Again to load the correct list (Activty) when the tab activity is refreshed we have to include this in the TabWidget onCreate after the creation of the tabs
tabHost.setCurrentTab(Constants.LIST_ACTIVITY);
This is implemented in Tabs with multiple activities in a single tab.
However when multiple times activities are called StackOverFlow error arises. Tried very hard but unable to solve it.. Please someone tell a method to solve this problem
Also need to Replace an activity in a tab, However from child activity. How is that to be done?
At any one moment there may only be one activity. Docs about this here
Following is the example of tabs with intent data.
While debugging i found that always when first tab we add in tab host in our case following tab
tabHost.addTab(tabHost.newTabSpec("tab1")
.setIndicator("list")
.setContent(new Intent(this, List1.class)));
oncreate method of "List1" intent get called regardless it is our current tab or not even if if i define tab2 as a current tab how to fix this ?
public class Tabs3 extends TabActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final TabHost tabHost = getTabHost();
tabHost.addTab(tabHost.newTabSpec("tab1")
.setIndicator("list")
.setContent(new Intent(this, List1.class)));
tabHost.addTab(tabHost.newTabSpec("tab2")
.setIndicator("photo list")
.setContent(new Intent(this, List8.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));
// This tab sets the intent flag so that it is recreated each time
// the tab is clicked.
tabHost.addTab(tabHost.newTabSpec("tab3")
.setIndicator("destroy")
.setContent(new Intent(this, Controls2.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));
}
}
setDefaultTab(1);
seems not to be working in TabActivity when separate Activities are used as Tab Content.
Use following instead of this method,
tabHost.setCurrentTab(1);
This will set "photo list" (i.e second tab) as the selected or default tab...
I have found this same behavior as well, and I do not have a specific fix. But I do know of a work-around.
Instead of attaching Activities to each tab, attach a View to each tab. You can then handle the data passing very easily as each view will be in the same Activity. This also eliminates the need to pass information using Intents. Furthermore, you can create (or inflate) your Views as you need them and with more control.
Good luck,
-scott