There are two activities.
Activity A has a button that can switch to Activity B.
Activity B also has a button that can switch to Activity A.
here is my code,
#Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
Log.e("current", context.getClass().toString());
Log.e("changeto", tab.getTag().toString());
if(context.getClass()==tab.getTag())
return;
Intent intent = new Intent(new Intent(context,(Class<?>) tab.getTag()));
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
context.startActivity(intent);
}
I want to remove the animation when i switch the activities, but it doesn't work.
However if I remove
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
it works perfectly. Why?
Sorry for my bad English.
In the Activity that you're switching to, try using overridePendingTransition(0,0); either in onResume or in onCreate.
If you're calling startActivity in a tab switch, you're doing it wrong. Tabs are for switching views within the current activity, and switching tabs should never create navigation history. Consider switching a fragment or replacing your view hierarchy with the newly selected tab's content instead.
The more you pursue a path of switching activities for tab selection, the more you will find yourself playing whack-a-mole with subtle user experience bugs that make your app simply feel "wrong."
With your proposed implementation above, the Back button will return to the previously selected tab, breaking the, "never creates navigation history" rule. You may think that finish()ing the current Activity as you start the next can solve this, but you'll still have a host of other issues. Users expect subtle elements of state such as scroll position to persist across tabs. As of Android 4.0 there is an expectation that users should be able to swipe horizontally between tabs (http://developer.android.com/design/building-blocks/tabs.html) which you will not be able to accomplish if you are using separate activities for each tab's content.
This is only a small sample, the list just goes on. Tabs should not be used to switch between different Activities.
Related
I have implemented a TabHost. In one tab I have Activity1, which calls Activity2 after a button click, which calls Activity3 after a button click, which calls Activity1 after a button click, etc.. No backstack functionality is required, just 1 --> 2 --> 3 --> 1, etc. All three activities have a separate layout file.
Everything works fine, except that after the first transition from 1 --> 2 the activities grab the entire screen and the tabs are invisble forever.
Question: how can I keep these three activities within the confinement of de tab area and the tabs visible? The problem has been recognized here many times before; the solution used to be ActivityGroups, but these are deprecated and Fragments are advised instead. I have seen many examples here, but nothing that could help me.
Can I keep my three activites (Activity1 extends Activity, etc)?
Should I add fragment tags to the layout files?
Do I need to work with transactions?
Should I work with one fragment class or three?
Can you please give me a few hints how I should go about? I woud already be helped if you tell which classes I need to use and of what type they are.
Thanks in advance.
It took me more than half a day, but finally found a solution that works. Unfortunately I am still stuck with deprecated issues (Activity Group and getLocalActivityManager().startActivity(..)).
Again I have a single tab under a TabHost and several activities, all operating within that tab. Navigation from one activity to the next occurs with a buttonclick. Solution:
all Activities operating within the tab need to extend ActivityGroup
All Activity classes need to have a button handler that links to the next activity like this:
public void onBtnClicked(View view) {
Intent intent = new Intent(view.getContext(), NextActivity.class);
replaceContentView("NextActivity", intent);
}
public void replaceContentView(String id, Intent newIntent) {
View view = getLocalActivityManager().startActivity(id, newIntent.
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)).getDecorView();
this.setContentView(view);
}
By this the tabs remain visible all the time, as desired.
Hope this helps someone.
I need to refresh my activity. I have bunch of question regrading the same which advice me to finish current activity and restart the current activity. OR again provide value to each widget. To avoid transition I used this code
Intent intent = getIntent();
overridePendingTransition(0, 0);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
this.finish();
overridePendingTransition(0, 0);
startActivity(intent);
But in my case In my activity I have four tabs, and I need to refresh all four tabs.
There are few more problems regarding the same
1) With above code, if I am on other screen, I come back to this screen when above piece of code runs.
2) Activity sequence gets disturb.
3) Maintaining selected tab will also be a part of problem
Even if I try to refresh each tab seperatley, One of my tab have webview. how to refresh that as webview.loadData() can't be called unless there is view and since I am not on that tab there will no view.
What can be the ideal way to tackle this problem. Any help will be appreciated.
It depends a bit on your use case. You may setContentView() again to inflate the layout every time. If you are just displaying a list, then you may just call the adapter to display the list. You have to do this for every fragment in your TabActivity.
To reload a WebView I would just call loadUrl() again.
As to remembering the selected tab, you have to store it and then set the current tab in the TabHost.
Question was not much complicated but solution what I wanted got to be optimised. Finally I took the second way, ie refreshing each component. This approach overcomes the problem of disturbing the sequence of activity. For web view I am still using webView.loadData(...).
In total I have handeled each tab separately. If I include my entire code then it would become clumsy, but still trying to incorporate as many important feature.
In my activity class when I need to refresh my activity, I called this method.
private void onRefrash()
{
refreshCurrentActivity();
int selectedTab = getActionBar().getSelectedNavigationIndex();
switch (selectedTab)
{
case TAB1:
fragment1.update();
break;
case TAB2:
fragment2.update();
break;
case TAB3:
fragment3.update();
break;
}
Toast.makeText(this, getString(R.string.msg_case_updates_received), Toast.LENGTH_LONG).show();
}
}
Each fragment is earlier initialised, and update method is called for each tab in which I am updating the corresponding web view.
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
I've put a little app together that has three tabs to show three different web pages. It does work however I am bit worried I haven't got enough control over how this whole thing works. When I click a tab, I get a web page loaded (see code sample below), now when I click another tab another page loads in another view. When I go back to the first tab, the whole thing get initilized again and the page loads. Is there a way how I can control this and keep the underneeth tab's activity in its current state as long as I want (and say only "refresh" the page when it changes).
do I need to handle onPause()/onResume() methods for that or instead implement my tabs as views of a single activity (is this possible at all?)? How do I store the state of my activity to avoid re-initializing it every time?
this how activities are hooked to tabs:
intent = new Intent().setClass(this, tab_schedule.class);
spec = tabHost.newTabSpec("Schedule").setIndicator("Schedule",
res.getDrawable(R.drawable.tab_icon_schedule)).setContent(
intent);
tabHost.addTab(spec);
the tab_schedule.class does a simple web page load:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_people);
try {
WebView currentView = (WebView) findViewById(R.id.tab_people_WebView);
currentView.getSettings().setJavaScriptEnabled(true);
currentView.loadUrl("http://pda.lenta.ru");
} catch (Exception e) {
Log.v("webClientInit", e.getMessage());
}
}
If you don't want to create a new activity for each tab, you can use a TabWidget with a FrameLayout to toggle between views.
As to switching activities, see this question for a way to not recreate the activity each time.
Regardless, you should always implement onPause and onResume to restore the state of your app. You might want to read up on the Activity Lifecycle, but basically you cannot prevent your activity from being killed if goes into the background. Thus, you should store your state in onPause. The link above has some info on how to do so as well.
To bring the previous activity to the top of the stack use intent.addFlag(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
There are 4 Tabs in a TabHost, let them be A, B, C, and D. Now each one is just an index page and clicking on any of them shows a different activity.
The problem is that I need to start another activity when the user selects something from the content displayed in the tab. The other activity should also be displayed in the parent tab itself. Is it possible? Or will I have to try something else?
Try this, found this solution in android cookbook,
http://androidcookbook.com/Recipe.seam;jsessionid=5424397F3130CE7769FF47DD67742911?recipeId=1693&recipeFrom=ViewTOC
Can't you change the contentView of your tab instead of starting a new Activity ?
Maybe I'm wrong but I think also that starting an activity in a tab isn't possible because the TabView is hosted in a activity and not the opposite (Tabview don't host an activity per Tab).
I think the common consensus is that it is best not to use individual Activities as tab content due to these limitations. See these questions and answers for pointers to alternatives:
Android: Why shouldn't I use activities inside tabs?
Android - Tabs, MapView, activities within tabs
To summarize the link that Rukmal Dias provided. Here's what you do:
Change your current Activity (that's in a tab) to derive from ActivityGroup
Create a new intent for the Activity you want to switch to
Copy/Paste and call this function in your current activity where "id" is the "android:id" for the layout of the new activity you want to switch to
public void replaceContentView(String id, Intent newIntent){
View view = getLocalActivityManager().startActivity(id,newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)) .getDecorView();
this.setContentView(view);}
Here's an example of how I make the call to switch views from my current Tabbed Activity:
public void switchToNextActivity(View view)
{
Intent myIntent = new Intent(getApplicationContext(), MyNextActivity.class);
replaceContentView("next_activity", myIntent);
}
It looses the view hierarchy. When you press the back button, in my case, the app closes.