I have tried searching across to find a solution for it, but none of them seemed to work.
My use case is: I have a FragmentActivity which contains a ViewPager to manager couple of fragments whose that if coming from different data sources - thus things like Service,Content Proviers,Loaders etc are involved.
While the onCreateView of my Fragments is only called once, but when I try to exit the application by pressing the back key, the view pager first removes the fragment set and display the blank activity, and the consequent press on the back actually exits the application.
I have tried couple of things like:
calling finish() in onKey... onBackPressed within the activity
calling getActivity().finish() from withing the Fragment and its
main layout view
but none of them worked.
**closing application by using its PID - thats something I dont want to try.
Its surely not the standard behaviour becuase I have seen people on SO asking the opposite of my query with their apps getting exited.
So, I would really like the activity to be closed on the first press of the back button.
Related
I recently started refactoring my Android application by replacing "all" activities with fragments. In the state it is right now, it behaves a lot worse than before...
My problems are in the area of "up navigation", backstack behaviour and general "repainting" of fragments when they are brought to front.
So I have created a logical hierarcy of fragments in my ui and when the user is in the main menu, the "up" button shouldn't be displayed. When the user is in any of the other fragments the up button should take the user back to the main menu.
When I started implementing this, I just put a
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
In my fragment's onResume method. This works as expected until the main menu is brought to front from the back stack (or the home navigation). Then the onResume() method isn't called.
Wanting to "repaint" the fragment when the user have been somewhere else in the app seems like the kind of thing that a large share of developers want to do. I have read some solutions to this that basically include listening to backstack changes and then calling onResume() for the fragment that is about to come back. This solution feels like a ugly hack that you shouldn't have in a real application. So how do developers of large applications handle this? What is the best practice? Or have I missed some principle saying how to not code myself into this corner at all?
I must say that I think the Android dev page for fragments is almost lying about the lifecycle:
"Managing the lifecycle of a fragment is a lot like managing the lifecycle of an activity"
"Resumed: The fragment is visible in the running activity."
This information implies that onResume() should be called when the fragment goes from invisible to visible.
Also, my solution to providing up navigation is obviously not correct, any tips on how to get proper behaviour?
Thanks for you help!
OK it was very unclear the actual problem so i will try and break it down.
Problem
Home Screen's onResume Method is not being called.
In Looking at the activity lifecycle and fragment lifecycle:
It highlights "The fragments onResume() or onPause() will be called only when the Activities onResume() or onPause() is called."
Go here: 2nd paragraph
This should give you a big idea as to why your onResume() method in the home Screen isnt being called. I wouldnt implement this myself but for sake of giving a solution i would clear the backstack (for memory sake) and instantiate a new homeScreen Activity when the user tries to get to the main screen/homescreen or my own solution would be to rewrite part of your application again you do not need to use fragments for the sake of it.
Programming practices
Be careful when using many fragments use of a fragment unless your highly skilled and knowledgeable of the android API should be used for showing mutiple views in one screen. Use cases include larger screens (tables,extra information etc.
Many white screen issues have been reported from bombarding an app with fragments and popping to the back stack so be weary.
I'm working to clone an iOS app that uses a UITabBarViewController as the "main/outer/root" UIViewController. Each of its tabs has a UINavigationController as the root to manage a navigation stack of UIViewController instances.
I am trying very hard to do 2 things:
Replicate the functionality of the iOS app.
Do so in true "Android" fashion (i.e., not forcing an iOS paradigm in a non-iOS world).
I've searched around a good bit, but this topic seems to have been changed a lot over the past few years. I tried a solution that had a single Activity that managed everything, but that required maintaining separate back stacks, and seemed to get a thumbs down from most users around here.
Currently, I have a solution that is "sort of" working. As I understand it, my current setup is:
A single, BaseActivity class that extends ActionBarActivity.
All activities in my app (only 2 thus far, but slated for 5) extend this class.
This base activity loads a drawer.xml layout, which has an android:support.v4.widget.DrawerLayout as its outermost item.
Inside of this is:
A FrameLayout, which is the container for my fragments.
A ListView, which is the drawer itself.
Based on my testing of the app, this setup gets me most of what I want.
When I "navigate" (using the drawer) to a different activity, the correct activity is loaded.
When I "navigate" to a "deeper" fragment (via on-screen controls), the correct new fragment is pushed and I've overridden onBackPressed() in BaseActivity to correctly pop the back stack if appropriate.
The problem I'm encountering is this:
The app is launched and "Activity 1:Fragment 1" is displayed. I click on an item to move to "Activity 1:Fragment 2" (which works well).
I use the drawer to launch Activity 2, and "Activity 2:Fragment 1" is shown. So far, so good.
I use the drawer to go return to (at least that's my intention) to the existing Activity 1, and "Activity 1:Fragment 1" is displayed.
I've looked into Activity/Intent launch flags, but I'm not sure I really get what's going on. So far, my reading has led me to try the following steps:
When switching Activites, setting its flag like this:
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
In my AndroidManifest.xml, setting Activity launchMode like this:
android:launchMode="singleInstance", or like this
android:launchMode="singleTop"
An odd, additional problem I'm facing is that launching a new Activity doesn't seem to create the Activity back stack like I expect. When I move from Activity 1 to Activity 2 (ignoring the lack of fragment back stack maintenance for a moment), pressing the back button from Activity 2 closes the app, which confuses me.
Is there a single, current best practice for this type of app structure/navigation?
the good approach is to have 1 activity and handle the back stacks manually as Android has only 1 stack. I've done this several times and finally I created a library called Tab Stacker that does the job: a fragment history for each tab.
It is open source and fully documented, and can be included easily with gradle. You can find the library on github: https://github.com/smart-fun/TabStacker
You can also download the sample app to see that the behaviour corresponds to your needs:
https://play.google.com/apps/testing/fr.arnaudguyon.tabstackerapp
If you have any question don't hesitate to drop a mail.
I have a sherlock activity(A) that contains a fragment(B) which again contains a tab and FragmentViewPager(C) which contains a Fragment (D).
I have a weird issue here.
Initially everything shows up fine.
If I close the app by pressing the home button, then come back immediately to the app, then everything is fine (A containing B containing C containing D)
However, if I close the app by pressing the home button, then work on other apps for a long time, then come back to my app, then I see A containing B containing C containing an empty screen.
Here are two questions.
1. Why doesn't the fragment D show up?
2. It seems like something is wrong with onResume() or something in D? Or is it related to process issue? Lifecycle? How can I fix that?
3. In order to recreate the issue, I have to close the app, then spend a lot of time playing other apps. Is there a way to recreate this issue quickly without having to waste time?
Thanks a lot...
A fairly common model for iOS apps seems to have a single UITabBarController, where each tab essentially holds a UINavigationController, i.e. a stack of controllers, and pressing a tab switches to the top of the corresponding stack. Can I get the same behavior on Android without a lot of custom code? (Note: I am using menus instead of tabs on Android).
After reading http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html the closest I can see is to have multiple tasks, each one representing a stack (akin to UINavigationController), and to use FLAG_ACTIVITY_NEW_TASK to switch to another task/stack. When I switch, is there a way to go straight to the top of the stack, or do I need to keep that piece of state myself?
One problem with keeping that state myself: I've noticed that if my app launches an Intent that starts a new process, sometimes my original app's process is killed (I think), and all of my global state is destroyed.
The only other solution I can imagine is to have a dummy Activity per stack, to push DummyActivityN essentially right before I switch away from the Nth stack, and, when switching to the Mth stack, to start activity DummyActivityM with FLAG_ACTIVITY_NEW_TASK, and then have DummyActivityM immediately finish() itself.
One last problem: as I navigate to the bottom of one of the stacks, with the back button, I would like to hit the back button once more and NOT go to another stack/task. But this seems easy to overcome by launching an Intent to go to the home screen; is there anything better?
If I understood your problem correctly, if you add this parameter to your Activity declarations in AndroidManifest.xml, the Activities that are launched by your custom menu will be only created once - keeping their state while you move around the tabs.
android:launchMode="singleTask"
I hope this helps,
Best,
-sekran
This question actually has two parts.
The first part:
I've been developing my first app for a couple of weeks now. I have 5 screens and everything seems well. However, I'm considering changing the app's navigation to a TabView.
I haven't delved much into it, but I'm hoping someone can save me a little bit of time. It seems that people don't generally place Activities inside each tab. They simply point the tab content to a View. This is where my major setbacks are. 1) I already have Activity classes full of code and 2) I can't quickly guess how the structure of an app using TabView looks. For example, where do I put the handler code for clicking a button on a View? Does it all just get dumped into the TabView Activity somehow?
What I would like is if you could please give me a quick synopsis of what I'm looking at doing, answers to any questions you think I may have, and point me toward some resources for creating TabView applications. A quick Google search really just shows me how to create a TabView Activity and add a couple tabs to it. The code doesn't go any deeper. For example, say I have a layout xml to show in one of my tab's content pane, where does the code go for clicking a button I have in that layout?
The second part:
I've added a TabActivity to wrap the Activities I currently have in. At the moment I have Activities populating the content of my tabs (though ultimately I'd like to do this in the most efficient fashion, which doesn't seem to be having Activities be tab content). I've noticed something rather annoying. My MAIN Activity is an Activity I wrote for my user to log in to their account. After logging in, they are taken to my Tab Activity. Here is what happens:
When I am on my Tab Activity and I "minimize" the app by clicking the Home button and then launch it again, I don't get taken back to the Tab Activity. I get taken to my log in Activity. Why? I don't have the launchMode of my Tab Activity set to singleInstance... or is it singleInstance by default? How can I make the app re-launch showing the Tab Activity (ideally by setting some parameter, assuming I'm doing something wrong, and not having to save this data off somewhere and reading it and programmatically telling it what to go to)?
Thank you for all your time and help
I don't have a comment on the advisability avoiding the use of sub-activities in TabActivity. As for handlers -- if you aren't going to embed views instead of activities, then all the android:onclick type handler settings in your layout XML will call methods on the TabActivity. This is because they go to methods on the views' Context, which is the generally the nearest containing Activity. If you want to split your code up further without using Activities, I believe you'll have to use findViewById calls on the tab content views after you've set them up, and bind the handlers manually from there in your code.