I am working on an Android app that has multiple screens the user will need to navigate between and I am curious what the best practices are when switching between those screens. I am torn between creating a new Activity for each screen and simply changing the view (setContentView(R.layout.whatever)). The screens all share at least some variable values so I'm leaning toward changing views and using class level variables, but I'm worried a single activity could become very large and confusing with logic for multiple screens in a single file. I'd like to keep the code clean and separated, but I also don't want to be passing several variables around between views if that isn't needed.
Being new to Android development, I'm hoping some more experienced members of the community could share their thoughts and let me know how best to handle it.
Thanks!
Note:
I wasn't planning on using a viewflipper. My thought was to use a button click event and then call setContentView() to a new view for the page I wanted to bring up next.
Example: My application starts up using R.layout.main as it's view. User clicks the Help button and it calls a method that runs setContentView(R.layout.help); to display the help screen as opposed to switching to a help activity.
You should use an activity per screen as this will make the best use of the framework and allow the OS to selectively kill off screens if things get tight.
If you have a single activity and resources get tight the OS has two choices; kill everything or kill nothing, and if the user is not using your app then it's most likely it'll kill everything.
If you use an Activity per screen the OS can kill off some of the screens the user hasn't visited for a while, whilst still allowing others to remain active which allows the user to go back to them quickly.
As for sharing variables and values, you could use the SQLite database or SharedPreferences stores for passing them around if they are widely shared, or use the putExtra methods in Intent if they're only of use from one screen to the next.
If you have variables that you will reuse make a base class for them, that you will extend.
This can be a your custom activity that extends Activity.
As far I can tell you have to create separate activities for each views, only a few situation can be handled by viewflippers.
Related
I have a large Android game in which there is an Activity for each logical screen.
(Splash screen, start screen, level chooser, game screen and Settings are distinct Activities).
Everything is working fine right now.
If I rewrite everything so that there is only one activity and the logical screens are Fragments, Will it reduce RAM or CPU consumption?
After years (two+) of saying "Fragments are the way to go", I would never replace activities with Fragments again.
Using fragments to rehuse certain components is fine. Using fragments for dialogs is also fine, but I have now realized how awful the Fragment implementation is, how awful the Fragment lifecycle is and how unpredictable (and buggy) FragmentManager tends to be under certain circumstances. Go ahead an spend some time googling around and you will find all the "edge but not so edge" cases where hacks have to be implemented to work around a "by design" buggy behavior.
Sometimes you have to extend or copy the source code of these classes from the Android Source Code to modify a private or protected field…
Don't get me wrong, Fragments work. But they are not the solution to all your problems (they are possibly the source of new ones in the mid-long term). If you already have Activities, enjoy that! In fact, the new Transition Frameworks with Shared Elements is a clear indication that Google wants you to use more activities ;)
This is my personal opinion after working in roughly six mid-large sized Android projects (some are popular and you've probably used them!) ;)
As far as I know, no, Fragments have (near to) no impact on RAM or CPU.
An Activity contains certain elements and performs some functionality. A Fragment is loaded onto an sort of base Activity, like an Activity with no more than an ActionBar. The rest is filled by the Fragment.
Also check out:
android - need some clarifications of fragments vs activities and views
Activity or Fragment which is better way to use for performance and reliable?
No, it will probably increase it (as you will have more classes) but only marginally.
The benefit of using fragments is to have reusable "blocks" that you can move around depending on your needs. For example for a specific activity you could have a layout where you have your main window on screen and clicking on an item creates an new activity with some details. With fragments, you could create a layout for tablets where the main window takes only half the screen and the rest is used for the details fragment, witout having to rewrite everything.
The main benefit of fragments to me is easy data sharing. Between two activities, data has to be passed in relatively primitive types...string, int, arrayList, etc.
However between fragment and activity, data can passed back and forth in complex classes.
This question already has answers here:
Dilemma: when to use Fragments vs Activities:
(17 answers)
Closed 4 years ago.
I often need the different parts of my applications to have their own special behavior and UI, and I don't know how fragments can help. In most cases, I think it is quicker to create 2 different activities (e.g., 1 for tablets and 1 for handsets), and to share the common behaviors and events in a third class.
So, keeping this in mind, why should I use fragments ?
Fragments are more of a UI benefit in my opinion. It's convenient for the user sometimes to see two different views of two different classes on the same screen. If, in your moment of creativity, you decide it would be nice to display your application with, say, a listView that takes up half the screen and a webView that takes up the other half - so that when you click on a list item in fragment A it passes an intent to the webView in fragment B, and suddenly you see what you just clicked without the app switching activities - then you could use a fragment. That's just an example I came up with off the top of my head.
Bottom line: Fragments are two or more activities on the screen at the same time.
The benefits I see when using fragments are:
Encapsulation of logic.
Better handle of the lifecycle of the fragment.
Reusable in other activities.
The drawbacks I see are:
More code(For example, instantiating a fragment manager, adding the fragment transaction, writing the callbacks of the fragment)
Communication between fragments and activities is harder. As #jonney said it, you would need to deal with a parcelable interface to serialize your objects you wish to pass.
So, when deciding to use a fragment, I would ask myself the following questions:
Is the lifecycle of the fragment different from the activity's lifecycle?
If the lifecycle is different, you get better handling of the lifecycle using a fragment. For example, if you want to destroy the fragment, but not the activity. Such is the case, when you have a pager adapter.
Is the fragment going to be used in several activities?
The user input events will be reusable if you use a fragment.
Is the amount of communication between the fragment and the activity small?
If you need to pass big objects to the fragment, you would need to deal with the code that serializes them. Also, if you need to communicate between fragment and activity, you would probably need to implement interfaces. This, in most cases, adds complexity to your codebase. It's not a difference maker, but a criteria to take into account.
Google advises you to ALWAYS use Fragments.
Why? It's simple:
In the simplest case, Fragments are used like containers of activities.
Why do you need this? Again, it's simple.
Android 4 (ICS) supports both Smartphones and Tablets. This means the SAME application will be running on a smartphone and a tablet and they are likely to be very different.
Tablets have big screens which will be empty or unused - unless you assign it properly.
That means- Putting two fragments on one activity like Contact List and Contact Info.
The smatphone will display contact List, and on a touch- display the contact's Info.
On a tablet, the user will still see the list and the info will be next to it.
2 fragments- on one screen....
Smart? yes... supposed to be back compatible down to Android 1.6......
#############################################################
O.K, Already Knew That? then - just try to understand the case solved:
A lot of things work that way- list & details, Menus and Sub-Menus, Info, Detailed Info and some more detailed info.
You want a way to keep it natural and smooth for a tablet which you expect to preform that way, but can't expect smartphone to display it all like the tablet did...
Get it?
for more Information, check out this.
I really think you just need to catch the concept....
Historically each screen in an Android app was implemented as a separate Activity. This creates a challenge in passing information between screens because the Android Intent mechanism does not allow passing a reference type (i.e. object) directly between Activities. Instead the object must be serialized or a globally accessible reference made available.
By making each screen a separate Fragment, this data passing headache is completely avoided. Fragments always exist within the context of a given Activity and can always access that Activity. By storing the information of interest within the Activity, the Fragment for each screen can simply access the object reference through the Activity.
https://softwareengineering.stackexchange.com/questions/244771/why-use-android-fragments
Fragment primary support more dynamic & Large UI Screen like Tablet.Because Tablet screen is much larger than normal Handset. There is more room to combine & Interchange UI Component.
Fragment allow such design without the need for such complex change in the View hierarchy.
By divide activity layout in fragment, we become able to modify activity's appearance at runtime
I just want to ask what is efficient way of use activity. Mean use one activity for multiple functionality or use multiple activity for every functionality.
In my application working some thing like Category->subcategory->Product listing. In which orientation change design and also need to consume previous functionality state for Back.
Thanks
Per the documentation for Activities, "An activity is a single, focused thing that the user can do". In other words, each different screen of your application should be an activity.
The only time you should have an Activity represent more than one screen is if it's a recursive action like a file browser; i.e. something that just changes the data that is displayed, but is displayed the same way.
It's quite common to create one Activity for every logical "screen" of your application, but to share the same Activity for multiple "states" (eg. dialog boxes, different modes) of that screen.
The back button will automatically go backwards through Activities (by default) and you can override the back button within an activity to revert to a previous state within the same activity (ie. hiding a panel)
Basically, Activity, in case of Android, is not a synonym for functionality. It is synonym for screen UI. Thus, how you implement your functionality is your choice. You just need to consider the following tips:
If you use the same activity for categories and subcategories (using
List elements), then you need time for deleting items for categories
(plus, GC also takes time), populating the list with the values for
subcategories. The weak points here that the user cannot return to
the previous Activity using back button (this violates the default
flow for user interactions), the screens are identical for
categories and subcategories (this can mess the user), it will takes
a long time for deleting unnecessary elements and populating with
new elements. Strong point: you will reduce memory consumption for
your application.
The second option is to use different activities. Weak points: it
also takes time to initialize new activity and to populate the list
with the values of subcategories, it will take more memory to store
two activities. Strong point: clear user understanding, more
responsibility to user's actions (you do not need to run GC to
delete unnecessary objects).
As for me the second approach is better unless you are not restricted with the memory.
I have a very simple 2 screen android app.
Is there any downside to simply switching out the layouts via setContentView or should i be using intents?Don't want to bugger up my app if something is wrong with this.
Another thing to consider is that activities form a stack. If you want to be able to go back to the previous activity via the 'back' button, then you need to use activity. But if it is something simple like a 'loading' screen when your app starts and you don't have to go back to it again, setting content view would be a much better idea.
Well as stated on Android Dev http://developer.android.com/reference/android/content/Intent.html
An Intent provides a facility for
performing late runtime binding
between the code in different
applications. Its most significant use
is in the launching of activities,
where it can be thought of as the glue
between activities. It is basically a
passive data structure holding an
abstract description of an action to
be performed.
Therefore if your two screens are 2 different applications I would say you want to simply use setContentView.
it will simplify your code when you want to pass info from one to the other views
There is nothing wrong with having two views in a single activity. This approach is more light-weight, as you don't need to go through the phase of stopping one activity and then starting another one. However, it will make your activity code bulkier. Consider now if you are going to need more functionality or more views in the future and if the answer is yes, then it would be better to create separate activities.
If the view is light-weight (a bunch of text boxes), then it should not matter. On the other hand, if the two screens are largely independent and heavy, you could use two different activities. The primary advantages with this approach are:
If there is an error in the second screen (an activity in this case), your application will fall back to the first screen whereas in the case of using the view, the whole application crashes
Better readability
Easier to add more functionality in the future
Which you think is the best way of doing a wizard like application (user can navigate between screens with a next and back button, and each screen has to save some state data) in Android platform.
I mainly can think in two approaches:
Having one activity+view for each screen and then i make the screen switch by calling each activity. What make this nice is that i can use the system back button as my back handler and i don't have to take care of that myself, aslo each activity will save it's own state.
Having one activity and many views, and what i switch views in each screen change, this helps me re-use more code, but makes saving states a mess.
What do you think? Which is the best way of doing this on Android?
This library is no longer being developed.
Use Android Navigation Component with combination of ViewModels to build a wizard flow.
I've developed a lightweight Android library, which is built on top of Android's ViewPager that can be used for creating wizard like activities. Check it out: WizarDroid.
I suggest going with 2 as it fits the goal of activities and views. Saving state in this case is easy - if you use the MVC pattern, you can simply have a model object that is passed along to the views. Each view will have portions of the model that it can read/write. No matter where you are, the model should always have the current state. If you get disposed, just save the model. Restore works automatically since you already read from the model when you show each page.
I've gone with the first approach as it seems more natural. Another app uses ViewFlipper for switching views but that's far from anything like wizard.
9 years ago this was obviously a very different kettle of fish - but I think the best way to do this now is with Fragments.
Have a Fragment for each 'page' in the wizard, letting it handle its own lifecycle and state.
Change page from within each Fragment with Fragment.getFragmentManager() - this returns the FragmentManager from the parent Activity, allowing the Fragment to replace itself.
I think 2 is better. Put each "page" in a view and then just alternate between showing and hiding them. Makes it trivial to do nice transitions. What state are you thinking of maintaining? The only one that doesn't work automatically would be focus and I think you probably want to reset that every time you switch pages. It is also trivial to catch back if you think that is the right behavior for your app.
With 1 you can reuse almost all of your code (just define your own WizardBase class) but I think activities are much slower to launch (and require more memory) than switching between views.