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
Related
I want to add back navigation to toolbar. I need to get from a fragment in an activity to a specific fragment in another activity.
It looks a little like this, where every orange line means navigating to a new activity or fragment:
How do I move from fragment B to fragment A from OtherActivity?
Consider these steps:
From Activity 1 holding Fragment A , you want to directly load Fragment B in Activity 2.
Now, I am thinking first, then you press a button in Fragment A, you can directly go to Activity B.
Then it means, you can simply load Fragment B as soon as you arrive in Activity 2.
Since you are dealing with back navigation (I believe you mean the upNavigation?), you can override the following:
But watch clearly, because if you need to load an exact fragment in Activity 2, you need to know somehow:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(this, Activity2.class);
intent.putExtra("frag", "fragmentB");
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
As you can see, when you click the back arrow on the toolbar, we pass a value through our intent to identity which fragment we want to load.
Next, in your Activity2, simply get the intent extra and do a switch or an if statement:
#Override
public void onResume(){
super.onResume();
Intent intent = getIntent();
String frag = intent.getExtras().getString("frag");
switch(frag){
case "fragmentB":
//here you can set Fragment B to your activity as usual;
fragmentManager.beginTransaction().replace(R.id.container_body, new FragmentB()).commit();
break;
}
}
From here, you should have your Fragment B showing in Activity 2.
Now you can handle the same thing while inside Activity 2 to decide where to go when a user clicks the back home arrow!
I hope this helps you get an idea.
Note: I thought about the interface approach and realized it is not necessary since this can be done easily with this approach!
To navigate from one Activity to another Activity's Fragment, with Kotlin version 1.4.0 and, for example, calling a click listener on a button it works so:
binding.yourButton.setOnClickListener {
supportFragmentManager.beginTransaction().replace(R.id.yourLayout, NameOfYourFragment()).commit()
}
Use this code to change your fragment
fragmentManager.beginTransaction().replace(R.id.container_body, new FragmentC()).commit();
and to show navigation on custom toolbar add
Toolbar toolbar = (Toolbar) rootView.findViewById(R.id.toolbar);
((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true)
((AppCompatActivity)getActivity()).getSupportActionBar().setHomeButtonEnabled(true);
I have six Tabs in MainActivity, the second tab have a listview, when user press on the listview item, its open a new Activity with Action bar, so, when user press on the back button of the second activity, I want to go to previous tab (second tab) of Main Activity, but its loading the First Tab (Home Tab).
How I can resolve this problem?
Using the Up navigation to return to the parent activity recreates the parent activity. When the parent activity is recreated you lose your selected tab. Rather than saving the selected tab, it is easier to just not recreate the parent activity. This can be done by adding the following line to the parent activity section of your AndroidManifest file.
android:launchMode="singleTop"
This will prevent the parent from being recreated and thus your previously selected tab will still be in the same state.
For example, if the MainActivity is the parent with the tabs, then the manifest would look something like this:
<activity android:name=".MainActivity"
android:launchMode="singleTop">
...
</activity>
See also:
ActionBar up navigation recreates parent activity instead of onResume
How can I return to a parent activity correctly?
We have three cases here. The actual back button (regardless it is hardware or software), the Action Bar's parent ("Up") button, and both buttons:
Back button case:
When you call the SecondActivity, use startActivityForResult() to keep MainActivity informed of the SecondActivity's lifecycle. When "back" is pressed, capture this event in MainActivity.onActivityResult() and switch to the second tab:
MainActivity: where you currently start your activity:
// Start SecondActivity that way. REQUEST_CODE_SECONDACTIVITY is a code you define to identify your request
startActivityForResult(new Intent(this, SecondActivity.class), REQUEST_CODE_SECONDACTIVITY);
MainActivity: onActivityResult():
// And this is how you handle its result
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == REQUEST_CODE_SECONDACTIVITY && resultCode == RESULT_CANCEL) {
switchToTab(2); // switch to tab2
}
// else... other cases
}
Action Bar's "Up" button case:
If this behaviour has to be connected to the Action Bar's "Up" button instead of the back button, you have to override getSupportParentActivityIntent() or getParentActivityIntent() depending on whether you are using the support library or not.
SecondActivity: get[Support]ParentActivityIntent():
#Override
public Intent getSupportParentActivityIntent() { // getParentActivityIntent() if you are not using the Support Library
final Bundle bundle = new Bundle();
final Intent intent = new Intent(this, MainActivity.class);
bundle.putString(SWITCH_TAB, TAB_SECOND); // Both constants are defined in your code
intent.putExtras(bundle);
return intent;
}
And then, you can handle this in MainActivity.onCreate().
MainActivity: onCreate():
#Override
protected void onCreate(Bundle savedInstanceState) {
...
final Intent intent = getIntent();
if (intent.hasExtra(SWITCH_TAB)) {
final int tab = intent.getExtras().getInt(SWITCH_TAB);
switchToTab(tab); // switch to tab2 in this example
}
...
Both buttons case:
Should you wish to handle both buttons the same way (regardless this is a good idea or not, I just don't know), both solutions above can be implemented concurrently with no problem.
Side note: to determine whether this is a good idea or not, this official guide may help. Especially the section "Navigating Up with the App Icon".
I have 3 tabs in my sample application with activity group. First tab contains search activity i.e.Home/Root activity and am displaying the results of search in another activity but under same tab i.e Tab1. When I press back button in result activity, it is going to search activity. Everything works fine till here. Now I want to go search activity by pressing tab1 instead of pressing back button. How can achieve this? I tried something like this
public class TabSample extends TabActivity {
public TabHost tabHost;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.tabHost = getTabHost();
tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator("OPT")
.setContent(new Intent(this, TabGroup1Activity.class)));
tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator("EDIT")
.setContent(new Intent(this, TabGroup2Activity.class)));
tabHost.setCurrentTab(1);
tabHost.setOnTabChangedListener(new OnTabChangeListener() {
public void onTabChanged(String arg0) {
if (tabHost.getCurrentTabTag().equals("tab1")) {
//What should I do to display search activity here
} else {
tabHost.setCurrentTab(1);
}
}
});
tabHost.setFocusable(true);
tabHost.requestFocus();
}
}
Can anyone please help let me know how to invoke search activity when tab is pressed? What will go into if part? Because if I use tabHost.setCurrentTab(index), it will display result activity but not search activity.
NOTE: I followed the tutorial given in this link.
I think what you want to do is this: when the 'tab1' tag is selected, go back to TabGroup1Activity if (and only if) the current activity is not that activity (basically you want to simulate a 'back' press).
If so, what you want is this:
if (getCurrentActivity().getClass() != TabGroup1Activity.class)
getCurrentActivity().finish()
I'm not 100% sure I understand you fully, but let's see :)
In your onTabChanged listener you can switch on which tab have been tabed, and then open the activity as normal inside an activitygroup:
public void onTabChanged(String tabId) {
if (tabId.contentEquals("tab1")) {
Intent intent = new Intent(tabHost.getContext(), TabGroup1Activity.class);
View view = StartGroup.group.getLocalActivityManager().startActivity("tab1", intent).getDecorView();
StartGroup.group.setContentView(view);
}
}
I just reviewed my code and think there's a bit more to explain here. The problem is that you don't stack activities as normal. Instead the workaround is to make a content stack and change these instead. So what I have done is to create a class StartGroup which extends
ButtonHandlerActivityGroup:
public class StartGroup extends ButtonHandlerActivityGroup {
// Keep this in a static variable to make it accessible for all the nested activities, lets them manipulate the view
public static StartGroup group;
// Need to keep track of the history if you want the back-button to work properly,
// don't use this if your activities requires a lot of memory.
private ArrayList<View> history;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.history = new ArrayList<View>();
group = this;
// Start the root activity within the group and get its view
View view = getLocalActivityManager().startActivity("UserList", new Intent(this, UserList.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();
replaceView(view);
}
public void back() {
if (history.size() > 0) {
// pop the last view
history.remove(history.size()-1);
setContentView(history.get(history.size()-1));
} else {
finish();
}
}
}
Then from the TabMaster class or what you call it you can use the StartGroup class to change the content view of an activity group.
This is something I wrote to work on devices from 2.2, so there might be an easier and more androidish way to accomplished it, but this works on almost all devices :)
Here is another thread where the use a similar approach:
Launching activities within a tab in Android
Let me know if I can help more.
There is an ArrayList in your ActivityGroup so override onPause() method in ActivityGroup and remove all the ids from ArrayList except the first one which must be your SearchActivity.
So when you go to other tab then comes back to SearchActivity( or on Tab1 ) Home will be displayed.
i have TabActivity in android project which contains some tabs. In each tab i can open various activities, and after open it in a tab i want go back to previous activity in same tab, but default android behavior close my root tab activity. How i can realise behavior that i need?
There are a few ways of doing this. The first involves creating a custom GroupActivity that will keep track of the stack from the LocalActivityManager and then extending that class for each of your tabs. For that, check out this tutorial:
http://ericharlow.blogspot.com/2010/09/experience-multiple-android-activities.html
A simpler approach is to keep an array of your tab's subviews within your initial ActivityGroup class and then override the back button. Here's some sample code:
public void replaceContentView(String id, Intent newIntent) {
View view = getLocalActivityManager()
.startActivity(id, newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
.getDecorView();
viewList.add(view); // Add id to keep track of stack.
this.setContentView(view);
}
public void previousView() {
if(viewList.size() > 0) {
viewList.remove(viewList.size()-1);
if (viewList.size() > 0)
setContentView(viewList.get(viewList.size()-1));
else
initView();
}else {
finish();
}
}
The initView() class holds all of the inflating of the original activity's view. This way, you can call this method to regenerate the original activity if there are no more views in the array.
I have used tabbar with activity group in my application. I have four tab like home, stock, citn, article. In my application first display home page from the home page user click in webview it will go to homepage1 activity. From home page1 activity user click stock tab it will go to stock activity. From the stock activity user click home tab it will go to homepage1 activity. I want to display home activity can any body tell how to do?
My question is switching between tab using activity group it will display last activity. I want to display first activity?
ok i will attach my code
spec = tabHost.newTabSpec("FirstGroup").setIndicator("FirstGroup",
getWallpaper()).setContent( new Intent(this,FirstGroup.class));
tabHost.addTab(spec);
View view =
getLocalActivityManager().startActivity("CitiesActivity",
new
Intent(this,CitiesActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
)).getDecorView();
// Replace the view of this ActivityGroup
replaceView(view);
}
public void replaceView(View v) {
// Adds the old one to history
history.add(v);
// Changes this Groups View to the new View.
setContentView(v);
run this example
http://united-coders.com/nico-heid/use-android-activitygroup-within-tabhost-to-show-different-activity
switching between activity and tab
I have posted in pastebin, my link is
http://pastebin.com/1zG0HJgv
Hi Did u tried the tabchanged event as shown below
tabHost.addTab(tabHost.newTabSpec("tab1").setContent(
R.id.content_movies).setIndicator("",
getResources().getDrawable(R.drawable.icon)));
tabHost.addTab(tabHost.newTabSpec("tab2").setContent(
new Intent(this, Sample.class)).setIndicator("",
getResources().getDrawable(R.drawable.menu_icon)));
tabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
#Override
public void onTabChanged(String arg0) {
if(arg0.equals("tab1"))
{
/*write the code here to show the view
Currentclass, the class where you have used ontabchanged function and
Newclass is the class where you want to navigate*/
Intent obj_intent = new Intent(CureentClass.this,Newclass.class);
startActivity(obj_intent);
}
else if (arg0.equals("tab2")) {
// write the code here to show the view
}
//similarly for other tabs
});