Adopting Fragments

Activities are fine, but they are fairly inflexible. Development is moving away from using activities as the core foundation of our UI. Activities will always exist, but many times we use an activity mostly as a simple container for other UI logic.

And, frequently, that UI logic is held in fragments.

The original vision for fragments was to make it easier to support early Android tablets, allowing you to assemble tablet-sized UIs by snapping together a bunch of phone-sized UIs that you use individually on phones.

Over time, fragments were used in more places and for more reasons. While fragments are not required, Google strongly encourages their use. Jetpack specifically advocates having an app be a single activity, with fragments for each “screen” of information.

This chapter will cover basic uses of fragments.

The Six Questions

In the world of journalism, the basics of any news story consist of six questions, the Five Ws and How. Here, we will apply those six questions to help frame what we are talking about with respect to fragments.

What?

Fragments are not activities, though they can be used by activities.

Fragments are not containers (i.e., subclasses of ViewGroup), though typically they create a ViewGroup.

Rather, you should think of fragments as being units of UI reuse. You define a fragment, much like you might define an activity, with layouts and lifecycle methods and so on.

However, at that point, you can use fragments in different ways, with two main patterns being:

Functionally, fragments are Java/Kotlin classes, extending from a base Fragment class.

Where??

Fragments will appear on the screen where you tell them to appear. There are two main approaches for this:

The first approach is for cases where the fragment will always be shown (“static fragments”) by the activity. The second approach is for cases where the fragment might be swapped out for another fragment, or whether the fragment might be conditionally shown based on user input, screen size, or other criteria (“dynamic fragments”).

Of the two, dynamic fragments are much more common.

Who?!?

Many fragments you will write yourself, just as you write your activities and other application code.

However, libraries can also contribute fragment implementations. We will see an example of this in the next chapter, with a Google-supplied Jetpack library offering a fragment that we use directly. Third party libraries might offer fragments as part of their API, for you to use or subclass as appropriate.

When?!!?

In modern, Jetpack-centric app development, often we define our fragments at the outset, as part of building our UI.

It is certainly possible to take an app that has several activities and rewite it such that it has one activity and several fragments. This is a bit tedious, but it might prove necessary at some point for legacy projects.

WHY?!?!?

Ah, this is the big question. If we have managed to make it this far through the book without fragments, and we do not necessarily need fragments to create Android applications, what is the point? Why would we bother?

There are many reasons for using fragments, some of which were hinted at above.

Break the Intent Barrier

Sharing data between activities is a problem. We can use extras on Intents, but they are limited in terms of size and data types. Other than that, we are limited to using singletons or other global objects, and those run the risk of memory leaks and related problems.

However, a single activity can have several fragments and switch between them at will. Plus, an activity can work directly with its fragments and share things, such as having a shared ViewModel. So, fragments give us ways of having different “screens” while still allowing everything to work using more-or-less normal Java/Kotlin object interactions.

To an extent, you can draw a parallel to Web development. Early Web development, and even a lot of modern development, has each “screen” be a separate Web page at a separate URL, fetched from the server. This works, but it has a similar problem to multiple activities in Android: one Web page cannot directly work with the DOM or JavaScript objects of another Web page. In the past decade, there has been a lot of movement towards “single-page applications”, where a single URL loading a single Web page has multiple screens’ worth of content, courtesy of lots of DOM rewriting. While this has its own set of problems, it gets past the separate-pages limitations, allowing multiple screens to share a common set of JavaScript objects.

Decomposition

Technically, one does not need fragments to allow for a single activity to represent multiple screens. We have used setContentView() to populate the activity’s UI, and you can call that as many times as needed. Each setContentView() call replaces whatever the previous “content view” was with a new one. Or, you can do other things with the activity’s view hierarchy to change the UI: hide and show widgets, add and remove widgets, etc.

However, if you go this route, you run the risk of having a single monster activity trying to manage all of this logic. For ease of maintenance and testing, having some decomposition is useful, so a set of Java/Kotlin classes can manage an individual screen, while the activity orchestrates which screen is seen at any point in time.

Fragments offer a foundation for this sort of decomposition. It is not the only option, and it may not be the absolute best option. However, it is Google’s best option, and Jetpack reflects a fragment-centric view of Android app development.

Screen Sizes

The original rationale for fragments was to make it easier to support multiple screen sizes.

Android started out supporting phones. Phones may vary in size, from tiny ones with less than 3” diagonal screen size, to monsters that are over 6”. However, those variations in screen size pale in comparison to the differences between phones and tablets, or phones and Chromebooks.

Some applications will simply expand to fill larger screen sizes. Many games will take this approach, simply providing the user with bigger interactive elements, bigger game boards, etc.

Part of the original vision for fragments was that one could assemble a tablet UI from a collection of phone screens, side by side.

Tablets vs. Handsets
Tablets vs. Handsets

(the above image is reproduced from work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License)

The user can access all of that functionality at once on a tablet, whereas they would have to flip back and forth between separate screens on a phone.

For applications that can fit this design pattern, fragments allow you to support phones and tablets from one code base. The fragments can be used by individual activities on a phone, or they can be stitched together by a single activity for a tablet.

OMGOMGOMG, HOW?!?!??

Well, answering that question is what the rest of this chapter is for!


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.