I am coming from iOS and working to port an iOS app on android. In iOS there is the storyboard where you can connect different view (activities) and embed them into tab bars and navigation bars. I am having an issue to understand what is the best way to implement bottom navigation in android...
Let say I have 3 bottom navigation items with the following
tab1
page1.1
page1.2
tab2
page2.1
page2.2
page2.3
tab3
page3.1
page3.2
page3.3
As an example in tab1 I have page1.1. Then let say I have a button in page1.1 which bring me in page1.2. If I go back from page1.2 I want to go back to page1.1. Same story for page2.1, I can go to page 2.2 and from page2.2 I can go to page2.3. I also want to go from page3.2 to page 1.2
I have read fragments are the best way to do it (each page.x is to become a different fragment with a different layout) but it does not seem very easy. I have also read I can use activities but many suggest not to use it
What do you recommend that I focus on? Are there any other solution to consider on top of fragment and activities? Thanks
You should use Fragments with a Single Activity. If you don't, you will have to copy/include one bottom bar in multiple Activities. It might be useful in some cases however when Activity is switched, your bar will redraw which might turn out to be a bad user experience.
I have read fragments are the best way to do it (each page.x is to become a different fragment with a different layout) but it does not seem very easy
Using Fragments might actually make it easier than if you use Activities. If you use Fragments, you can have one Activity be in control of every fragment that is being displayed, meaning that you can control navigation based on which fragment is being shown. This way, you can handle some special scenarios that do not fall into usual navigation behavior.
Doing the same in Activities would be a little more difficult since you'd have to continuously pass around data in Intents and it would be difficult to control the behavior since your logic will be spread across Activities.
What do you recommend that I focus on? Are there any other solution to consider on top of fragment and activities?
These two are only recommended solutions. If some of your UI elements are same in all pages while some part of it is changed constantly, then its best to use Fragments with single Activity. For screens that are completely different or that are not part of your navigation flow, you add more Activities for them instead of Fragments.
For example, You can use Fragments in One Activity with Bottom Navigation Bar, but for settings screen or profile screen, you should make separate Activites.
I know that Activities are designed to represent a single screen of my application, while Fragments are designed to be reusable UI layouts with logic embedded inside of them.
Until not long ago, I developed an application as it said that they should be developed.
I created an Activity to represent a screen of my application and used Fragments for ViewPager or Google Maps. I rarely created a ListFragment or other UI that can be reused several times.
Recently I stumbled on a project that contains only 2 Activities one is a SettingsActivity and other one is the MainActivity. The layout of the MainActivity is populated with many hidden full screen UI fragments and only one is shown. In the Activity logic there are many FragmentTransitions between the different screens of the application.
What I like about this approach is that because the application uses an ActionBar, it stays intact and does not move with the screen switching animation, which is what happens with Activity switching. This give a more fluent feel to those screen transitions.
So I guess what I'm asking is to share your current development manner regarding this topic, I know it might look like an opinion based question at first look but I look at it as an Android design and architecture question... Not really an opinion based one.
UPDATE (01.05.2014): Following this presentation by Eric Burke from Square, (which I have to say is a great presentation with a lot of useful tools for android developers. And I am not related in any way to Square)
http://www.infoq.com/presentations/Android-Design/
From my personal experience over the past few months, I found that the best way to construct my applications is to create groups of fragments that come to represent a flow in the application and present all those fragments in one Activity. So basically you will have the same number of Activities in your application as the number of flows.
That way the action bar stays intact on all the flow's screens, but is being recreated on changing a flow which makes a lot of sense. As Eric Burke states and as I have come to realize as well, the philosophy of using as few Activities as possible is not applicable for all situations because it creates a mess in what he calls the "God" activity.
Experts will tell you: "When I see the UI, I will know whether to use an Activity or a Fragment". In the beginning this will not have any sense, but in time, you will actually be able to tell if you need Fragment or not.
There is a good practice I found very helpful for me. It occurred to me while I was trying to explain something to my daughter.
Namely, imagine a box which represents a screen. Can you load another screen in this box? If you use a new box, will you have to copy multiple items from the 1st box? If the answer is Yes, then you should use Fragments, because the root Activity can hold all duplicated elements to save you time in creating them, and you can simply replace parts of the box.
But don't forget that you always need a box container (Activity) or your parts will be dispersed. So one box with parts inside.
Take care not to misuse the box. Android UX experts advise (you can find them on YouTube) when we should explicitly load another Activity, instead to use a Fragment (like when we deal with the Navigation Drawer which has categories). Once you feel comfortable with Fragments, you can watch all their videos. Even more they are mandatory material.
Can you right now look at your UI and figure out if you need an Activity or a Fragment? Did you get a new perspective? I think you did.
My philosophy is this:
Create an activity only if it's absolutely absolutely required. With the back stack made available for committing bunch of fragment transactions, I try to create as few activities in my app as possible. Also, communicating between various fragments is much easier than sending data back and forth between activities.
Activity transitions are expensive, right? At least I believe so - since the old activity has to be destroyed/paused/stopped, pushed onto the stack, and then the new activity has to be created/started/resumed.
It's just my philosophy since fragments were introduced.
Well, according to Google's lectures (maybe here, I don't remember) , you should consider using Fragments whenever it's possible, as it makes your code easier to maintain and control.
However, I think that on some cases it can get too complex, as the activity that hosts the fragments need to navigate/communicate between them.
I think you should decide by yourself what's best for you. It's usually not that hard to convert an activity to a fragment and vice versa.
I've created a post about this dillema here, if you wish to read some further.
Since Jetpack, Single-Activity app is the preferred architecture. Usefull especially with the Navigation Architecture Component.
source
Why I prefer Fragment over Activity in ALL CASES.
Activity is expensive. In Fragment, views and property states are separated - whenever a fragment is in backstack, its views will be destroyed. So you can stack much more Fragments than Activity.
Backstack manipulation. With FragmentManager, it's easy to clear all the Fragments, insert more than on Fragments and etcs. But for Activity, it will be a nightmare to manipulate those stuff.
A much predictable lifecycle. As long as the host Activity is not recycled. the Fragments in the backstack will not be recycled. So it's possible to use FragmentManager::getFragments() to find specific Fragment (not encouraged).
In my opinion it's not really relevant. The key factor to consider is
how often are you gonna reuse parts of the UI (menus for example),
is the app also for tablets?
The main use of fragments is to build multipane activities, which makes it perfect for Tablet/Phone responsive apps.
Don't forget that an activity is application's block/component which can be shared and started through Intent! So each activity in your application should solve only one kind of task. If you have only one task in your application then I think you need only one activity and many fragments if needed. Of course you can reuse fragments in future activities which solve another tasks. This approach will be clear and logical separation of tasks. And you no need to maintain one activity with different intent filter parameters for different sets of fragments. You define tasks at the design stage of the development process based on requirements.
There's more to this than you realize, you have to remember than an activity that is launched does not implicitly destroy the calling activity. Sure, you can set it up such that your user clicks a button to go to a page, you start that page's activity and destroy the current one. This causes a lot of overhead. The best guide I can give you is:
** Start a new activity only if it makes sense to have the main activity and this one open at the same time (think of multiple windows).
A great example of when it makes sense to have multiple activities is Google Drive. The main activity provides a file explorer. When a file is opened, a new activity is launched to view that file. You can press the recent apps button which will allow you to go back to the browser without closing the opened document, then perhaps even open another document in parallel to the first.
Thing I did: Using less fragment when possible. Unfortunately, it's possible in almost case. So, I end up with a lot of fragments and a little of activities.
Some drawbacks I've realized:
ActionBar & Menu: When 2 fragment has different title, menu, that
will hard to handle. Ex: when adding new fragment, you can change action bar title, but when pop it from backstack there is no way to restore the old title. You may need an Toolbar in every fragment for this case, but let believe me, that will spend you more time.
When we need startForResult, activity has but fragment hasn't.
Don't have transition animation by default
My solution for this is using an Activity to wrap a fragment inside. So we have separate action bar, menu, startActivityForResult, animation,...
The one big advantage of a fragment over activity is that , the code which is used for fragment can be used for different activities. So, it provides re-usability of code in application development.
use one activity per application to provide base for fragment
use fragment for screen ,
fragments are lite weight as compared to activites
fragments are reusable
fragments are better suited for app which support both phone & tablet
You are free to use one of those.
Basically, you have to evaluate which is the best one to your app. Think about how you will manage the business flow and how to store/manage data preferences.
Think about, how Fragments store garbage data. When you implement the fragment, you have a activity root to fill with fragment(s). So, if your trying to implement a lot of activities with too much fragments, you have to consider performance on your app, coz you're manipulating (coarsely speaks) two context lifecycle, remember the complexity.
Remember: should I use fragments? Why shouldn't I?
regards.
I use Fragments for better user experience. For example if you have a Button and you want to run let's say a webservice when you click it, I attach a Fragment to the parent Activity.
if (id == R.id.forecast) {
ForecastFragment forecastFragment = new ForecastFragment();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.main_content, forecastFragment);
ft.addToBackStack("backstack");
forecastFragment.setArguments(b);
ft.commit();
}
In that way the user won't have to move in another activity.
And secondly I prefer Fragments because you can handle them easily during rotation.
It depends what you want to build really. For example the navigation drawer uses fragments. Tabs use fragments as well. Another good implementation,is where you have a listview. When you rotate the phone and click a row the activity is shown in the remaining half of the screen. Personally,I use fragments and fragment dialogs,as it is more professional. Plus they are handled easier in rotation.
Almost always use fragments. If you know that the app you are building will remain very small, the extra effort of using fragments may not be worth it, so they can be left out. For larger apps, the complexity introduced is offset by the flexibility fragments provide, making it easier to justify having them in the project.
Some people are very opposed to the additional complexity involved with fragments and their lifecycles, so they never use them in their projects. An issue with this approach is that there are several APIs in Android that rely on fragments, such as ViewPager and the Jetpack Navigation library. If you need to use these options in your app, then you must use fragments to get their benefits.
Excerpt From: Kristin Marsicano. “Android Programming: The Big Nerd Ranch Guide, 4th Edition.” Apple Books.
Some wrong ideas:
Always put an activity in your app and handle different screens with fragments.
Write the UI code directly in the activity.
Handle navigating between screens (I don't mean tabs, I mean for example full-screen views) by fragments.
Activities can be replaced by fragments.
Here is the thing!
Fragments are designed to implement reusable parts of UI and use them in any part of the app that is needed. They are not designed for substituting activities.
When we must use each of them?
When we have an independent screen in which there are some different UI parts (tabs, expandable screens, partial screens, etc...) we should use an activity with some fragments to implement and handle different UI parts separately in the same screen.
Each independent part of the application is actually a component that is conceptually different from other parts and it needs to have an independent activity. For example, the login part may contain some different scenarios like using username-password or using fingerprint. Each scenario can be implemented by a fragment and all login-related fragments should be handled by LoginActivity. But for example, the part of the orders in the application doesn't have a conceptual relationship with login, so it must have a different activity and of course, it may contain some fragments like OrdersFragment, SubmitNewOrderFragment, and etc that all of them must be managed by OrdersActivity.
Do not implement a UI directly in an activity. Always implement UI in fragments and add those fragments in the activity even if there is only one fragment in that activity. It helps you to have more reusable code and change UIs easier.
Never use fragments to navigate infinitely in the application even if you force the user to have a limited number of fragments in the back stack. The fact is that when you add a new fragment into the back stack and remove it, it will not be removed from the memory unless the parent activity gets destroyed and it is only not visible. So when you are using fragment manager back stack, by navigating multiple times between fragments in the same activity (especially in the case of you create a new fragment on each navigation and put them into the back stack) you will get an OutOfMemoryException in the application.
I hope it to be helpful.
This question needs to be reevaluated since Jetpack Compose has reached stable.
Jetpack Compose is Android’s recommended modern toolkit for building
native UI.
from https://developer.android.com/jetpack/compose
The typical jetpack-compose architecture is:
Single Activity, multiple composables, and glued together by jetpack navigation.
Note there's no (need for) Fragments anymore.
See Now in Android for a sample.
There are few similar questions on stackoverlow, but I haven't find clear explanation at any of the answers how to implement Action Bar pattern for more complex/multiple activities apps.
As I understand, there are two options to do this:
1.) implement multiple activities and in each of them implement/include action bar
--> problem with this is that when ever you lunch new activity, although it has the same looking action bar, it has that transition, and jumps through the screen, so it's obvious it's a new "window",new separate screen, and it kills that feeling of single app navigation frame.
2.) Use single FragmentActivity, with action bar within, and with multiple fragments that inflate content frame.
--> this is pretty nice implementation of action bar pattern, but problem is that it goes against google's recommendation that one fragment should be in one activity in the case of phone. Or it doesn't? From the "look and feel" I would say that Gmail app is done mostly this way.
3.) TabActivity - which is deprecated.
For the second solution (single activity, multiple fragments) I'm concerned if there would be any performance issue in the future? How does android handle memory in that case? will it kill inactive fragments to free space just like it does with the activities? Or it will kill the whole app, or user phone will be overloaded?
Maybe I'm missing something there, but I found implementing android navigation patterns and usage of fragments very confusing :/
Is there any reason against having one activity with multiple fragments on the phone?
(there would be cca 5-6 fragments, with nested fragments in some of them)
First of all, you might think this question and this answer to be useful.
Though you are talking about the actionbar, the real question is about the pattern of ONE activity with multiple fragments or MULTIPLE activities. As the former link states, though the "oversimplified tutorial" suggests of starting another activity to display item's content in Phone situation, this will probably cause some duplicated logic or codes.
Finally, using "FragmentActivity with multiple fragments" is recommended. As it is against the the google's recommendation, Stephen Asherson says and I quote: " do not think of it as being forced to use many activities. Think of it as having the opportunity to split your code into many fragments, and saving memory when using them".
PS. just for your information, if you change the activity's actionbar in switching fragments, you might want to do something to correctly handle the UI change when "back" key is pressed and backstack is changed. Commonly, override the onbackstackchanged() function to handle the UI.
This is a bit of a desperation call for some good advice.
I began doing a project which involves Navigation drawer as the main menu for the application. After looking at the Android tutorial I followed the example and start developing on top of that. That example is a single activity that replaces the fragments depending on the selected option in the drawer. In part, I followed this design because if I launched Activities the drawer was lost and the Activity would appear with the launching transition and didn't look nice at all.
Now, my project is not a small one. During development I faced several issues like:
onResume not being called on the Fragments (due to not being attached to several activities but one instead.
All the data between Fragments should pass through the single Activity
Managing the Options Menus in the ActionBar became a real pain.
And many others I don't recall now
Now I am facing a new issue. In one of the fragments I need to have a Spinner that will switch fragments inside this one. And of course, the fragment will need to change the navigation mode in the action bar. This was a major headache to develop, but now I am facing a bigger problem with some fragments inside losing the activity context (like if they were detached).
After so many problems I just decided to switch back the whole app to Activities (this is a custom app that will run in just 1 tablet model, so no worries about fragmentation). So, in short I am looking for advice on the less painful way to do this.
I am on a extremely tight deadline that lead me to start implementing without designing (like a complete noob). Now I am being hit with so many issues that, if I didn't need the money, I would cancel this project at once.
Please help!
I can give a little advice, but sadly your situation can't really be solved by any one answer here.
First off, switching from a Fragment design to an Activity design is a lot easier than switching the opposite way. You can actually use all of the fragments you had before, and just have each activity loading only 1 of the fragments (or multiple if you prefer).
Also, when handling Intents (starting new activity), after the startActivity() call you can call overridePendingTransition() to make the launching transition whatever you want (or remove it completely).
I have seen a few questions raised on this topic (for e.g.: https://github.com/jfeinstein10/SlidingMenu/issues/5) but I am still unclear. I hope somebody can clarify this.
Context:
See https://github.com/jfeinstein10/SlidingMenu
I have an android app that organizes screens by activities and fragments (i.e.) each screen is an activity containing one or more fragments.
The new requirement is to add a sliding menu (similar to what this library provides).
Issue:
It appears from the examples and discussion that the right model would be to have just 1 MAIN ACTIVITY that will then switch in/out fragments belonging to the different screens. In fact the author mentions in the above thread: "If you were to launch Activities based upon the list selection, then you would not have the behavior where you swap the views that you're talking about. " and also "You can't put an Activity into the above view. That doesn't really make sense when you think about what an Activity is. ".
Why doesn't it make sense? Obviously, I am missing the point here.
Question:
Given that my project already contains multiple activities (one corresponding to each screen), is my only option then to re-organize the project to have JUST 1 MAIN ACTIVITY, in order to use this library? Or alternatively, is there any way to launch a new activity when a list item in the sliding menu is clicked, and still observe the sliding menu behavior, [EDIT- added the last part to be more clear] or in other words, on how exactly to use this library within my existing app design.
Thanks in advance
First, you can't have an Activity inside another and activities are completely different from views as stated in the docs:
An activity is a single, focused thing that the user can do.
Now, to answer your question, it all depends on how you want your app to behave. You could have your activities with the sliding menu implement the onClosedListener and switch to the selected activity from there. This will give you the animation of closing the menu before switching activities. It will also give you a weird effect since every time you select something from your menu you'll see the animation of a new activity coming to the front.
I think the best approach would be to have a "common purpose" between all your sliding menu options. For example, in one of my projects I have to allow the users to select between lists of different types of data. When the user selects anything from the menu, I load a new list fragment into the right corner where he may choose the item he wants to view or edit. That's the app entry point and also the only place were I have a sliding menu in my app. It is pretty much the same for every app that implements this UI design pattern. Look at google+, currents and youtube where the side menu lets you choose which feed or content to show. Once a user makes a selection, just open a new activity for the selected item (a g+ post, a video, a news article, a tweet or whatever it is).
Your app doesn't have to have lists of different data or anything like that to use the sliding menu, but keep in mind that the activity with the sliding menu should have a clear, focused goal with respect to its functionality and purpose. Having a sliding menu because many other apps have one is a bad choice, you should use it with a specific objective. Also keep in mind that applying the sliding menu everywhere would interfere with the platform's navigation pattern and lead to an overall bad user experience since it wouldn't behave as the other apps.
It doesn't make sense to place an Activity into the above view because the Activity is the main controller for the view of each screen. The Activity also shows views and keeps track of Fragments (which in turn are mini controllers, with or without their own views). So placing an Activity in the above view would mean that you would place an Activity in an Activity... Wich is impossible.
From what I can derive from your text I think it would be wise to read through the Android developer guide on Activities and Fragment again (http://developer.android.com/guide/components/activities.html) to get a better understanding of how the concept of Android works.
Now to your question:
I am not clear on what you are trying to achieve but if you want your app, with menu to behave like, say, the Google+ app then one way of doing it is to implement a base class that extends the Activity class (or what ever base Activity used in your project) and let the base set the SlidingMenu. Then you would simple extend your base Activity in each of the Activities that are supposed to have a menu.
You could also do it the way you describe it, but then you would end up with a classic example of a God object (http://en.wikipedia.org/wiki/God_object). It's a neat way to practice your Fragment juggling skills and switching between Fragments instead of starting new Activities does have it's use cases, but I still wouldn't recommend it for a project with more then a few views.
Here is the answer that came closest to the issue I had - http://www.verious.com/article/polishing-the-sliding-app-menu/. Scroll down to the bottom of the page to see the last section titled "Using the fly-in app menu between Activities". This is one option if you have a lot of activities in your existing app and want to avoid extensive re-factoring. I haven't tried this out yet but its worth being aware of.