I'm just getting to know Fragments in Android.
When you create a new blank project, by default a Fragment is included as well, although it's not really used. My impression is that Google wants you to use Fragments all the time no matter how simple the app is. Would that be a true assessment or can you think of any reasons not to use Fragments?
What I also find strange is that the documentation indicates that Fragments can also be used for stuff that is not UI related. Can you give me an example of an app that would use a Fragment but doesn't provide any UI?
Google introduced fragments when they lunched Honeycomb (3.0).
As you may know, Honeycomb was the first Android version to support tablets out-of-the-box and they use fragments to better arrange UI layouts on the screen.
With Fragments you can utilize screen property way better then with activities. One activity can run and "command" many different fragments that share same screen real-estate and the fragments can be swapped on the fly.
So yes, Google WANTS you to use fragments and it is the right way to write most scale-able applications.
As for the second question:
Fragments can persist across configuration changes - like screen orientation changes for instance. Activities gets killed and recreated when you change screen orientation and any work they might do will have to be recreated again.
If you use fragments right, then when you change screen orientation the activity might get killed but the fragment can persist its state and then re-attach itself to the newly created activity and continue where it left.
Basically, if you have an AsyncTask running from an activity and the activity gets killed because of orientation change (for example), you AsyncTask is useless now. But if you hold the AsyncTask through a fragment then it will continue because the fragment isn't destroyed.
Hope this helps
It all depends on what you're developing and how. I don't think EVERY app needs to have fragments, but they are in many cases easier to work with as they can be swapped on the fly, managed by a single activity, etc.
For instance, imagine your app has some background task running, and you want it to keep running while the user is still "Free to roam" around the app. Running that task in the activity and having the UI in fragments would be a very simple way to do this. The activity can also manage and send messages and data to its "children" fragments at any point, including communication between the fragments themselves.
As for fragments with no UI at all, I don't recall coming across something like this, but you can definitely implement background tasks and other methods that are not directly related to the UI in a fragment. Again, it all depends what you're developing and how. There's really no "right or wrong" here...
Related
I am developing a forum reader, which I expect that it will be run on phone only, not tablet.
The application originally have 3 views, and each is assigned with an Activity.
For example, if the user select a board on "Board selection screen", an Activity will start, and show the thread list of the selected board to the user.
Recently I have learned how to use fragment in an Android application. therefore I decided to convert my application from an Activity based apps to a Fragment based apps.
Although the apps works as fine as usual after the change, I encountered a problem in saving the state of the fragment. I failed to find the event to let me save the state of fragment (When I am switching from A fragment to B fragment). The most likely event is onSaveInstanceState(Bundle), but according to the API guide, it will only be called when an activity is about to be stopped, and it is not my case.
Actually I have tried to save the state in getArgument() in onDestroyView(). Nevertheless, according to the API guide, the values in getArgument() should only be used for instancing a fragment. Although everything work normal when I am saving the state in getArgument(), I believe that I am doing it wrong.
I have tried to do some googling about Fragment. I found that most of the artist suggest that Fragment is useful when an application is expected to run on both phone and tablet. And I don't find any artist that is talking about how to do screen switching between few Fragment within an Activity. I started to doubt that Fragment are only useful for supporting different device, but not for screen switching.
Sorry for the above junks. My questions are, does Fragment is not very useful when I am developing an application which for phone only? Should I change my application back to an Activity-based apps if I don't expect this to run on tablet?
One more thing Fragments are good at is they are good for Dialogs. Fragment-based dialogs have none of the problems you usually have with showDialog() when rotating the phone
No, you should stick with Fragments. They're incredibly versatile and will make your life easier down the road if you decide to rearrange things. As far as saving state, you just need to override onSaveInstanceState() in your Fragment (not the Activity). This will absolutely be called when switching between Fragments -- I use this all the time.
If we're talking about "just work" you can just go ahead and use fragments or just normal activities and layouts. However, what fragments provide, apart of scalability when developing for other devices like tablets, is that it's giving you more code separation, which is so, so great for the maintenance of the app.
For very long time, I think what is the reason of using fragment in Android if I just develop the application for Android Phone only but not 10.1.
Is it necessary to use fragment? Also, what is the usage of fragment,
I found that it may use for 'tab' and 'separate view'...
I really think it is very confusing. Can anyone explain briefly and give example?
From documentation
You can think of a fragment as a modular section of an activity, which
has its own lifecycle, receives its own input events, and which you
can add or remove while the activity is running (sort of like a "sub
activity" that you can reuse in different activities).
Some advantages are..
A particular UI part, once done in fragment, can be reused in
same/different activities.
You can separate different sections of UI, hence code will be neat,
and easy readable.
The ability of fragment to be able to reuse is very helpful when you are creating applications for different kind of android devices (phones, tablets). A well designed fragment can be just plugged into your UI hierarchy.
Fragments is a new concept introduced in 3.0 version.
The basic purpose of fragments is:
Fragments are designed to use the device UI space efficiently.
When you are writing an application in android, then some people can download it into phone, some into tablets. If you see the space in tablets it will be little bigger than phones. You should be able to use that space efficiently. But you can't keep writing different applications one targeting for phone, and other targeting for tablets. In order to do it efficiently, i.e writing only application that can fit well with all screen sizes, we use fragments concept.
fragments are designed as a reusable UI components between more than one activity.
Once you design a fragment, you can view it as a detachable independent unit, so that you can plug it into any activity where ever there is a space. That means you can reuse the code designed for a fragment.
Fragment you can think of it like a sub activity, which sits with in an activity and which contributes its own UI to the activity screen.
Fragments are always part of an activity. With out an activity, a fragment will not exist. So your fragment life cycle will always be affected by activity life cycle.
An activity can contain more than one fragment. Similarly a fragment can be re used in multiple activities.
If you use Fragment in your application, your apps will support all the device like small device, tablet and even google TV. In one .apk file, we will have different design for various devices.
This is the best Android tutorial that I've ever found. Section 21 covers fragments
Refer Here
Under some circumstances I need to be able to tear down all my activities that are in my application stack and recreate them all due to configuration changes. I have accomplished this by first calling finish for each activity and then recreating the stack.
To recreate, I relauch my root activity. And within its onStart I have it create my second activity. Within my second activities onStart I have it create my third Activity. This does work but the problem that I am having is that when watching the screen you see each of the three activities created and animate into the next activity. I want to have this rebuilding invisible to the user and hide these transitions. Does anyone know how to accomplish this?
Android already takes care of restarting activities when there is a configuration change.
If you are saying you want all of your activities to be restarted, even if they aren't currently visible (Android will do this lazily as the user returns them and they become visible, if the configuration is still different at that point), then no there is no simple way to do this. I can't imagine you coming up with anything that isn't going to be hideously ugly, because to get the platform to restart your activity you will need to make it visible, and then you are going to have flicker up the wazoo.
Things just aren't intended to work that way. This isn't how pretty much any other application you run on Android will operate, so if you deeply feel like it is something you need to do then it will be useful to explain why that is so we can tell you a better way to accomplish what you want. :) For example, if you have a bunch of activities whose state is fundamentally tied together to require this, consider using fragments instead (or cleaning that up).
On the other hand, if you just have some internal concept of a configuration and want to get your activity to be restarted (say for example to switch between themes), there is an API for this but it only was added in Android 3.0: http://developer.android.com/reference/android/app/Activity.html#recreate()
As Android documentation states: "An activity is a single, focused thing that the user can do."
However with Fragments we will be able to do many "things" within the same Activity as Reto Meier suggest. His suggestion is to replace a selection fragment by a content fragment within the same Activity (section "Within our code this produces a dilemma").
Lets say my application is a "bit" more complex, with many activities, with a complex navigation tree and designed with the "single, focused thing that the user can do" principle in mind.
Lets say now I have to adapt it to Fragments and large screens... and that I don't want to create a second application, neither have two completely different logics (one for phones other for tables) inside one application.
Should I have one Activity to manage all the application fragments and fragment transactions? Like Retro Meier suggest above. Is that the recommended path to follow? Thus breaking with the "single, focused thing that the user can do" principle for Activities?
Or am I missing something? I hope ;)
BTW, I think Fragments looks great, but from what I have seen till now, only if you are creating an application from the scratch. Because making applications to be compatible with phone and tablet looks like going to be a bit tedious. Hope to be wrong :)
Dianne Hackborn already has answered (thx for the link mgv):
you could put your entire application in one activity in which you change the fragment structure as its state changes
So then Activity becomes a sort of container where you will be able to plug Fragments. I like the approach, but... in my app there are about 30 different operations available, each one requires about 2 to 4 screens steps to be performed(forms and selection lists), all of them differ and there are also navigation restrictions. It works fine with Activities each one handling one screen/step behaviour.
So then to port to Fragments I should move each screen logic to Fragments and use Activities as containers for each operation. Thus leaving Activities as the ones managing the navigation between Fragments for every operation, right? Looks like going to be a pain to adapt long applications. :(
Current Activity definition should change a bit btw. :)
Should I have one Activity to manage all the application fragments and fragment transactions?
That is impossible to answer in the abstract. However, most applications will have multiple activities, even in a fragment-based world. Some of that will be to accommodate smaller screen sizes, where it will tend to be one fragment per activity. Some of that will be required by the framework (e.g., inheriting from PreferenceActivity). And, some of that will be by GUI design.
Thus breaking with the "single, focused thing that the user can do" principle for Activities?
That portion of the documentation was written in 2008, perhaps earlier. Had fragments existed back then, I imagine the documentation would state that a fragment is a "single, focused thing that the user can do", with activities serving as an orchestration layer, determining what fragments are visible in what circumstances.
The documentation will not in all places be updated to reflect fragments, and even if it does, it will take some time. For the balance of 2011, at minimum, you will need to perform your own translations of 2008-era instructions to convert them to 2011-era fragment-based UIs.
Lets say now I have to adapt it to Fragments and large screens... and that I don't want to create a second application, neither have two completely different logics (one for phones other for tables) inside one application.
I have no idea what you consider "completely different logics" to be. In a fragment-based app, most of your business logic will be in the fragments themselves. The activities, again, serve as an orchestration layer, determining what fragments should be visible and coordinating event handling. The latter will get a bit more complicated than it used to be, since sometimes clicking on an item in a list will bring up a new fragment and sometimes clicking on an item in a list will start a new activity, depending on screen size.
Or am I missing something?
To be honest, you are missing enough concreteness to your question to make it reasonably answerable.
I have developed some apps for Android, and this questions stays always:
How should I structure my UI? Should I launch activity after activity and leave the phone to make the "back" button, or should I choose more optimized, but more complex to implement, way with switching manually Views and then manually doing the "Back" button functionality?
What do you think (or know) is the better practice?
I would say that multiple Activities almost always makes more sense. I just don't think Android is designed for constantly switching its own views - you miss out on so much. You have to implement Back yourself, you don't get any inter-Activity transitions, you have to implement a lot of internal logic to resume an application in the correct state. If you don't partition your app into Activities, it makes it a lot more difficult later on to change the flow of your application. It also results in one mega-Activity that can be a lot harder to handle than a lot of smaller pieces of code.
I have trouble imagining that speed is really an issue; if it is then there's something wrong with the way you're initializing each Activity. For example, I used try to pass Serializable objects between Activities, and that proved to be incredibly slow; when I switched to a faster method of passing objects, the speed of launching Activities increased immensely.
Also, I think it's telling that the Android guidelines for Activity and Task Design don't mention switching Views at all; it's centered around an Activity-as-View design.
I'd like to point out some instances when a single activity might be better design for an Android application that has more than one full screen View:
If the application screens are tightly coupled and share a common Object that they are all operating on. In this case passing around the Object may require a Bundle and can be error prone since there will be copies of it. A good example might be a wizard. Yes you could use static's to access the common Object but static can be dangerous in Android (think configuration changes!)
If you want some really cool animations in between screens. Maybe you want a bird to take off in one screen and land in another screen. Try doing that when each screen is an activity!
On the other hand if one of your screens is designed to be shown by any number of other applications then that screen should be its own Activity.
UPDATE March 2014:
At this point the question should now include the choice of Fragments. I think that Views are probably the least likely choice of the 3: Activity, Fragment, View. If you want to implement screens that make use of the back button then it should be either Activties or Fragments because both handle the back button natively. Fragments will need to be added to the FragmentManager back stack for the back button to work. Managing fragments, dialogs and the back stack can be a bit of an annoyance though!
UPDATE Sept 2018:
Some devs at Google are recommending single activity apps using the new navigation architecture component.
Also keep in mind that implementing your app with multiple Activities will give the user a more coherent experience with the platform as a whole. Part of the experience will be shaped by using the built-in Google apps, so users will probably have an easier time using your application if it behaves similarly to the ones that are already installed on the phone.
Different from others I use a mixture of both, for example,
1. There is a main menu when the application starts
2. You click on search, takes you to search activity
3. Then there's a filter button, which just switches view and shows you filter options
4. There are two buttons at the end of the filter view, You hit "Search" or "Cancel" and you are back to the Search View again (without switching activity)
5. Now if the user hits the phone back button he's taken back to the main menu instead of the search filter options. Which I guess is the correct behavior.
Use it the way user will feel natural. And keeping everything in one activity will make it complex.
It all depends on application, what are you trying to achieve better performance, smoother UI. IMHO I prefer the second approach of controlling the Activities manually even that it is more complex as you have stated. This is a approach I have used in my android tabs project, also you might want to take a look at a class called ActivityGroup (not sure the package) it allows you to have multiple activities that you can switch between, good thing about this class is that your activities are not unloaded when you switch but a bad thing is it takes longer to load your main app.
Just my opinion.
The problem with switching views, that I stumbled upon, is also caused by garbage collector. Seems that GC is triggered when you leave activity and not the view. So, changing tabs with a fairly complex children views, for instance, will almost inevitably lead to stack overflow exception..
I've experienced so many problems with multiple activity layout that I strongly discourage it, unless there's good reason to pick it.
Disadvantage of multiple activities
Using multiple activities it is much hard to refactor code to return data from activity.
If you call a 'sub'-activity then the main activity may be killed. But you never experience that while debugging on a decent device, hence you need to handle always saving state and correctly recovering state. That is a pain. Imagine calling a method on a library (ie. another activity), and you would have to be ensure that when that method returns your app must be able to recreate its state completely with all fields on all objects in the VM (ie. activity.restoreIntance). Its insane.
Also the other way round, when you open a subactivity the VM might have been killed since the subactivity was first spawned, such as when app is minimized while subactivity is displayed.
Its so much cleaner to just have one place to store the relevant app-state, and in my case, most often if VM is killed, I want to return user to main-screen, and let them do their stuff again, because I don't spend 30-50 hours coding save/resume functionality that 0.1% of users will ever experience.
Alternative
Fragments or just manage you activity views yourself. Managing views manually, requires coding some view-switching alternative to activities/fragments with transitions if desired.
And no it does not mean one mega-activity, as suggested in the accepted answer, in any other way than its one mega-app. It just requires a bit more design of the codebase into fitting pieces, because there's slightly more work managing views, though much less work managing activity-state and other weirdness.
Possibly relevant: Reddit: It's official : Google officially recommends single activity app architecture