How Many Activities Vs Fragments

Why fragments, and when to use fragments instead of activities?

#1 & #2 what are the purposes of using a fragment & what are the
advantages and disadvantages of using fragments compared to using
activities/views/layouts?

Fragments are Android's solution to creating reusable user interfaces. You can achieve some of the same things using activities and layouts (for example by using includes). However; fragments are wired in to the Android API, from HoneyComb, and up. Let me elaborate;

  • The ActionBar. If you want tabs up there to navigate your app, you quickly see that ActionBar.TabListener interface gives you a FragmentTransaction as an input argument to the onTabSelected method. You could probably ignore this, and do something else and clever, but you'd be working against the API, not with it.

  • The FragmentManager handles «back» for you in a very clever way. Back does not mean back to the last activity, like for regular activities. It means back to the previous fragment state.

  • You can use the cool ViewPager with a FragmentPagerAdapter to create swipe interfaces. The FragmentPagerAdapter code is much cleaner than a regular adapter, and it controls instantiations of the individual fragments.

  • Your life will be a lot easier if you use Fragments when you try to create applications for both phones and tablets. Since the fragments are so tied in with the Honeycomb+ APIs, you will want to use them on phones as well to reuse code. That's where the compatibility library comes in handy.

  • You even could and should use fragments for apps meant for phones only. If you have portability in mind. I use ActionBarSherlock and the compatibility libraries to create "ICS looking" apps, that look the same all the way back to version 1.6. You get the latest features like the ActionBar, with tabs, overflow, split action bar, viewpager etc.

Bonus 2

The best way to communicate between fragments are intents. When you press something in a Fragment you would typically call StartActivity() with data on it. The intent is passed on to all fragments of the activity you launch.

How many Activities vs Fragments?

I agree that the tutorials are very simplified. They just introduce Fragments but I do not agree with the pattern as suggested.

I also agree that it is not a good idea to duplicate your app's logic across many Activities (see DRY Principle on wikipedia).


I prefer the pattern used by the ActionBarSherlock Fragments Demo app (download here and source code here). The demo that most closely matches the tutorial mentioned in the question is the one called "Layout" in the app; or FragmentLayoutSupport in the source code.

In this demo, the logic has been moved out of the Activity and into the Fragment. The TitlesFragment actually contains the logic for changing Fragments. In this way, each Activity is very simple. To duplicate many very simple Activities, where none of the logic is inside the Activities, makes it very simple.

By putting the logic into the Fragments, there is no need to write the code more than once; it is available no matter which Activity the Fragment is placed into. This makes it a more powerful pattern than the one suggested by the basic tutorial.

    /**
* Helper function to show the details of a selected item, either by
* displaying a fragment in-place in the current UI, or starting a
* whole new activity in which it is displayed.
*/
void showDetails(int index)
{
mCurCheckPosition = index;

if (mDualPane)
{
// We can display everything in-place with fragments, so update
// the list to highlight the selected item and show the data.
getListView().setItemChecked(index, true);

// Check what fragment is currently shown, replace if needed.
DetailsFragment details = (DetailsFragment) getFragmentManager()
.findFragmentById(R.id.details);
if (details == null || details.getShownIndex() != index)
{
// Make new fragment to show this selection.
details = DetailsFragment.newInstance(index);

// Execute a transaction, replacing any existing fragment
// with this one inside the frame.
FragmentTransaction ft = getFragmentManager()
.beginTransaction();
ft.replace(R.id.details, details);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}

}
else
{
// Otherwise we need to launch a new activity to display
// the dialog fragment with selected text.
Intent intent = new Intent();
intent.setClass(getActivity(), DetailsActivity.class);
intent.putExtra("index", index);
startActivity(intent);
}
}

Another advantage of the ABS pattern is that you do not end up with a Tablet Activity containing lots of logic, and that means that you save memory. The tutorial pattern can lead to a very big main activity in a more complex app; since it needs to handle the logic of all the fragments that get placed in it at any time.

Overall, 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.

Activities vs Fragments for apps

Theoretically, you could have your entire application run on a single Activity and use Fragments for all of the pages.

Each fragment has its own lifecycle within the activity.

MainActivity can look like this

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
loadFragment(2)
}

public fun loadFragment(page: Int){
if(page == 1){
// load login
val manager = supportFragmentManager.beginTransaction()
manager.replace(R.id.fragment_holder, LoginFragment()).commit()
}else{
// load register
val manager = supportFragmentManager.beginTransaction()
manager.replace(R.id.fragment_holder, LoginFragment()).commit()
}
}
}

LoginFragment can look like this

class LoginFragment : Fragment() {

lateinit var myButton: Button

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_login, container, false)
myButton = view.findViewById(R.id.my_button)

myButton.apply {
setOnClickListener { toRegister() }
}
return view;
}

fun toRegister(){
// replace the fragment in main activity with register fragment
(requireActivity() as MainActivity).loadFragment(1)
}
}

RegisterFragment can look like this

class RegisterFragment : Fragment() {

lateinit var mButton: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_register, container, false)
mButton = view.findViewById(R.id.my_button)
mButton.apply {
setOnClickListener { toLogin() }
}
return view;
}

fun toLogin(){
// replacing the fragment in the main activity with the login fragment
(requireActivity() as MainActivity).loadFragment(1)
}
}

Basically, we replace the fragment displayed in the activity by calling loadfragment.
This logic can be applied to as many fragments as is necessary.

Should I use fragments or activities for my app?

For me, all decisions about Activity or Fragment are related to (1) UX (2) Manageability (3) Communication cost across components, etc.

Let me introduce some decisions by examples.

  1. Is the screen required to launch from outside (Share intent)?

    • Activity is better as it can be opened directly from what AndroidManifest gives.
  2. Does the screen require page-by-page views (recipe pages)?

    • Fragment is better as Fragment+ViewPager give flexible paging fuctionality. Moreover, some Android devices or theme editors override Activity opening effects so page-turning animation does not run as expected if we implements it in Activity-by-Activity manner.
  3. Does the screen execute Camera or Photo intent with StartActivity?

    • Activity is better as OnActivityResult is hard to manage inner fragments when the app restores back from the Camera apps. For this reason, "writing a post" screen could be a good example to be a single Activity.
  4. Does the screen have to run regardless of screen on/off (Timers)?

    • Activity is better as it can show up faster and lighter without Activity-Fragment dancing.
  5. Does the screen have a kind of master-detail hierarchy?

    • Fragment is better because we could prepare tablet layout.
  6. Does the screen consume memory a lot?

    • Activity is better because we can focus on the activity solely not inner fragments memory usage.
  7. Does the screen has nested fragments more than 3-depth?

    • Fragment, reluctantly. Communication between fragment is unstable and Activity-Fragment bridging/dancing is always headache 1 2. We can make complexity lower but Activity-inside-Fragment-inside-ViewPager-inside-fragment-... is hard to acheive manageability.

Using multiple Fragment with single Activity is recommended by professional Android developers but we could decide to create more Activities for easier management and faster understanding.

In your case, I would like to implement components as below.

  • MainActivity with Fragments: Ingredients, Categories, Recipe.
  • ResultActivity with Fragments: Search and its Results are a kind of master-detail view.
  • TimerActivity: It should be good to run in single Activity.
  • RecipeActivity: If each recipe has its own id and can be shared as permalink, your app could open directly the recipe page by RecipeActivity. And, it could be better to show recipe even if your app is restored from turned-off or switched back from another app situation.

Which one is the better design approach in Android - Multiple Activities/Fragments

It's an eternal question that was asked a lot of times. You'll probably won't find a definite answer. So you need to read about philosophy and decide for yourself what approach is better in your situation.

One activity - many fragments OR many activities - many fragments?

From my experience I would recommend rather having multiple activities with many fragments. If you use a single activity you are going to find it harder and harder to manage fragments with the activity lifecycle.

For example if the activity is destroyed (e.g. if phone is low on memory and user receives a phone call or you call an intent to open the camera), when the intent is recreated you will need to handle recreating the fragments and their states.

With a single activity this can quickly become a nightmare to manage if not done carefully. With multiple activities it's easier to manage and helps seperate portions of the app - making it easier to debug as well.

An example of how something simple can become complex with a single activity would be something such as the back button.

If you need to handle it different for different fragments that means your activity is going to need to cater for which fragment is currently visible, as the activity overrides the backbutton, not the fragment. This also would likely mean you need to add interfaces to notify the fragments of a back button press.

Stating all of this however, there are some apps that benefit from a single activity. For example if you have a viewpager for swiping fragments (e.g. pages of a book) or fragments that do little interaction, then a single activity can be beneficial.

Are Fragments and Fragment Activities inherently faster than Activities?

I became a believer in Fragments in my last application. Whether or not they are computationally faster, they feel faster because you can swap them in and out basically instantaneously, including full support for the back stack if you do it right (call addToBackStack() on the transaction, or something very similar).

I now use Fragments / Fragment activity for all navigation I want to feel very quick, like clicking on a row to get more details. I only launch new activities for when I want to do a fundamentally different thing and have a clean slate to work with. For instance, I usually have a LoginActivity that deals exclusively with logins/registrations, and at least one more that is the core of the app.

But the fundamental benefit of Fragments still remains their flexibility. I can show fragments on top of other fragments, re-arrange them on different screen sizes, etc. But there are loads of other benefits. It just takes a while to feel natural (just like Activities did at first).

One caveat, I always regret embedding fragments in my layouts. I can't give exact reasons here off the top of my head, but essentially you just lose some flexibility. Instead, I build a normal layout for each fragment, and add a placeholder view in the activity layout, create the fragment programmatically, and use transaction.replace() to add it to the layout. Perhaps because this is the main way I swap fragments in and out of that placeholder view, and prefer to just have a single way of doing things where possible.



Related Topics



Leave a reply



Submit