Android Fragments Tutorial: An Introduction with Kotlin
In this Android Fragments with Kotlin tutorial you will learn the fundamental concepts of fragments while creating an app that displays dogs breeds. By Aaqib Hussain.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Android Fragments Tutorial: An Introduction with Kotlin
30 mins
- Getting Started With Android Fragments
- Android Fragment Lifecycle
- The V4 Support Library
- Creating a Fragment
- Using a factory method
- Adding a Fragment
- Adding a Fragment Dynamically
- Data Binding
- Communicating With the Activity
- Fragment Arguments and Transactions
- Binding Adapters
- Navigating the Fragment Back Stack
- Where To Go From Here?
A fragment is an Android component that holds part of the behavior and/or UI of an activity. As the name would suggest, fragments are not independent entities, but are tied to a single activity. In many ways, they have functionality similar to activities.
Imagine for a moment that you’re a super villain. You have a lot to do, so you might employ a few minions to run around and do your laundry and taxes in exchange for lodging and food. That’s kind of like the relationship between activities and fragments.
In the same way that you don’t actually need an army of little helpers to do your bidding, you don’t have to use fragments. However, if you use them well, they can provide:
- Modularity: Dividing complex activity code across fragments for better organization and maintenance.
- Reusability: Placing behavior or UI parts into fragments that multiple activities can share.
- Adaptability: Representing sections of a UI as different fragments and utilizing different layouts depending on screen orientation and size.
In this tutorial, you’ll build a mini-encyclopedia of dogs which displays a list of dog breeds arranged in a grid. When the user selects a breed, the app displays information about it. Through building this app you’ll learn how to:
- Create and add fragments to an activity.
- Let your fragments send information to an activity.
- Add and replace fragments by using transactions.
Note: This tutorial assumes you’re comfortable the basics of Android programming and understand what the activity lifecycle means. If you’re brand new to Android, you should work through both the Android Tutorial for Beginners and the Introduction to Activities first.
This tutorial utilizes an Android RecyclerView
. If you’ve never used RecyclerView
or need a refresher, you should also look at the Android RecyclerView Tutorial.
Time to get started!
Getting Started With Android Fragments
Use the Download Materials button at the top or bottom of this tutorial to download and extract the Starter Project.
In the Welcome to Android Studio dialog, select Import project (Eclipse ADT, Gradle, etc.).
Check out the project El Dogo app. You’ll find some resource files: strings.xml, activity_main.xml, drawable and layout files. There are also some boilerplate layouts for your fragments, non-fragment code that you’ll need and a fragment class that you’ll use later to write your own.
The MainActivity
will host all of your wee fragments and DogListFragment
contains code to display a list of dog breeds content so that you can focus on fragments.
Build and run the project. You’ll see that it’s pretty quiet in there.
But don’t worry! You’ll fix that…soon!
Android Fragment Lifecycle
Like an activity, a fragment has a lifecycle with events that occur when the fragment’s status changes. For instance, an event happens when the fragment becomes visible and active, or when the fragment becomes unused and is removed. You can also add code and behaviors to callbacks for these events as you would for an activity.
Here’s a fragment lifecycle diagram from the official Android Developer documentation:
The following lifecycle events come into play when you add a fragment:
-
onAttach
: The fragment attaches to its host activity. -
onCreate
: A new fragment instance initializes, which always happens after it attaches to the host. Fragments are a bit like viruses. :] -
onCreateView
: A fragment creates its portion of the view hierarchy, which is added to its activity’s view hierarchy. -
onActivityCreated
: The fragment’s activity has finished its ownonCreate
event. -
onStart
: The fragment is visible. A fragment starts only after its activity starts and often starts immediately after its activity does. -
onResume
: The fragment is visible and interactable. A fragment resumes only after its activity resumes and often resumes immediately after the activity does.
But wait, the fragment isn’t done! These lifecycle events happen when you remove a fragment:
-
onPause
: The fragment is no longer interactable. This occurs when either the fragment is about to be removed or replaced or when the fragment’s activity pauses. -
onStop
: The fragment is no longer visible. This occurs either after the fragment is about to be removed or replaced or when the fragment’s activity stops. -
onDestroyView
: The view and related resources created inonCreateView
are removed from the activity’s view hierarchy and destroyed. -
onDestroy
: The fragment does its final clean up. -
onDetach
: The fragment is detached from its activity.
As you can see, the fragment’s lifecycle intertwines with the activity’s lifecycle. But it has extra events that are particular to the fragment’s view hierarchy, state and attachment to its activity.
The V4 Support Library
In Android, when using fragments, there are two alternative fragment implementations you can use.
One type is the fragment that is provided by the platform version. A platform version corresponds to the version of Android that a user is running. For example, a device running Android 6.0, SDK Version 23, would be running platform version 23 of the library.
The second type is a support library fragment. When you include a support library, it is added to your project in the same manner as any third-party library.
Using the support library has two benefits when developing applications for multiple versions of Android.
First, it ensures that you have consistency in your code and functionality across different devices and platform versions. This means that bugs and fixes will be more consistent across different versions of Android using these libraries.
Second, when they add new features to the latest version of Android, the Android team will often back-port these features via the support library in order for developers to use on older versions of Android.
So, which library should you use?
Android has deprecated platform fragments in Android 9.0, SDK Version 28. So you should always go with the v4 support library when using fragments.
Creating a Fragment
Eventually, El Dogo will show a list of dogs breeds on launch and tapping on any of the items will display details about that particular breed. To start, you’ll work backwards and first create the detail page.
Open the starter project in Android Studio and find fragment_dog_details.xml under app ▸ src ▸ main ▸ res ▸ layout. This XML file lays out the dog detail display. It also displays one of the drawable resources and the associated String
resources.
Locate the DogDetailsFragment.ky file in the project. This class will be responsible for displaying details for a selected breed.
In DogDetailsFragment.kt, the code now looks like this:
import android.os.Bundle
import android.support.v4.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
//1
class DogDetailsFragment : Fragment() {
//2
companion object {
fun newInstance(): DogDetailsFragment {
return DogDetailsFragment()
}
}
//3
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_dog_details, container, false)
}
}
This code:
- Declares
DogDetailsFragment
as a subclass ofFragment
. Notice theimport android.support.v4.app.Fragment
: This is from the v4 support library mentioned before. - Provides a method for creating new instances of the fragment, a factory method.
- Creates the view for the fragment.
Activities use setContentView()
to specify the XML file that defines their layouts, but fragments create their view hierarchy in onCreateView()
. Here you called LayoutInflater.inflate
to create the hierarchy of DogDetailsFragment
.
The third parameter of inflate
specifies whether the inflated fragment should be added to the container
. The container is the parent view that will hold the fragment’s view hierarchy. You should always set this to false
when inflating a view for a fragment: The FragmentManager
will take care of adding the fragment to the container.
Using a factory method
There’s a new kid in town here: FragmentManager. Each activity has a FragmentManager that manages its fragments. It also provides an interface for you to access, add and remove those fragments.
You’ll notice that while DogDetailsFragment
has a factory instance method, newInstance()
, it does not have any constructors.
Wait, why do you need a factory method but not a constructor?
First, because you did not define any constructors, the compiler automatically generates an empty, default constructor that takes no arguments. This is all that you should have for a fragment: no other constructors.
Second, you probably know that Android may destroy and later re-create an activity and all its associated fragments when the app goes into the background. When the activity comes back, its FragmentManager
starts re-creating fragments by using the empty default constructor. If it cannot find one, you get an exception.
For this reason, it is best practice to never specify any non-empty constructors. In fact, the easiest thing to do is to specify none as you did here.
What if you need to pass information or data to a Fragment? Hang on, you’ll get the answer to that later!
Adding a Fragment
Here’s where you get to add a fragment using the simplest approach — adding it to the activity’s XML layout. This is also sometimes called Adding a Fragment Statically.
To do this, open activity_main.xml, select the Text tab and add the following inside of the root FrameLayout:
<fragment
android:id="@+id/details_fragment"
class="com.raywenderlich.android.eldogo.DogDetailsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:name="com.raywenderlich.android.eldogo.DogDetailsFragment"
instead of class="com.raywenderlich.android.eldogo.DogDetailsFragment"
.
In this step, you’re placing a <fragment>
tag inside of the activity layout and specifying the type of fragment the class
attribute should inflate. FragmentManager
requires the view ID of the <fragment>
. By including this in the XML, the FragmentManager
knows to add this fragment to the activity automatically.
Build and run. You will see the fragment:
Adding a Fragment Dynamically
First, open activity_main.xml again and remove the <fragment>
you inserted. Embrace the Zen of deleting code! You’ll replace it with the list of dog breeds.
Open DogListFragment.kt, which has all the list code. You can see that the DogListFragment
has no explicit constructors and a newInstance()
.
The list code in DogListFragment
depends on some resources. You have to ensure that the fragment has a valid reference to a Context
for accessing those resources. That’s where onAttach()
comes into play.
In DogListFragment.kt and add these imports directly below the existing imports:
import android.os.Bundle
import android.support.v7.widget.GridLayoutManager
The GridLayoutManager
helps in positioning items in the breed list. The other import is for standard fragment overrides.
Inside of DogListFragment.kt, add the following method above the definition of the DogListAdapter
:
override fun onAttach(context: Context?) {
super.onAttach(context)
if (context != null) {
// Get dog names and descriptions.
val resources = context.resources
names = resources.getStringArray(R.array.names)
descriptions = resources.getStringArray(R.array.descriptions)
urls = resources.getStringArray(R.array.urls)
// Get dog images.
val typedArray = resources.obtainTypedArray(R.array.images)
val imageCount = names.size
imageResIds = IntArray(imageCount)
for (i in 0 until imageCount) {
imageResIds[i] = typedArray.getResourceId(i, 0)
}
typedArray.recycle()
}
}
onAttach()
contains code that accesses the resources such as breed names and descriptions you need via the Context
to which the fragment is attached. Because the code is in onAttach()
, you can rest assured that the fragment has a valid Context
.
Add this method right after the onAttach()
:
override fun onCreateView(inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view: View = inflater.inflate(R.layout.fragment_dog_list, container,
false)
val activity = activity as Context
val recyclerView = view.findViewById<RecyclerView>(R.id.recycler_view)
recyclerView.layoutManager = GridLayoutManager(activity, 2)
recyclerView.adapter = DogListAdapter(activity)
return view
}
In onCreateView()
, you inflate the view hierarchy of DogListFragment
, which contains a RecyclerView
, and perform some standard RecyclerView
setup.
If you have to inspect a fragment’s view, onCreateView()
is a good place to start because it generates the view.
Next open MainActivity.kt and add the following to the bottom of onCreate()
:
// 1
if (savedInstanceState == null) {
// 2
supportFragmentManager
// 3
.beginTransaction()
// 4
.add(R.id.root_layout, DogListFragment.newInstance(), "dogList")
// 5
.commit()
}
At this point, to get DogListFragment
into MainActivity
. You ask your new friend, FragmentManager
, to add it.
Here you:
- Check that the
savedInstanceState
isnull
. This is a way to see if it’s an initial open of the screen. - Grab the
FragmentManager
by referencingsupportFragmentManager
as opposed tofragmentManager
, since you are using support fragments. - Ask that
FragmentManager
to start a new transaction by callingbeginTransaction()
— you probably figured that out yourself. - Specify the add operation that you want by calling
add
and passing in:-
The view ID of a container for the fragment’s view hierarchy in the activity’s layout. If you take a look at
activity_main.xml
, you’ll find@+id/root_layout
. - The fragment instance you want to add.
-
A string that acts as a tag/identifier for the fragment instance. This allows the
FragmentManager
to later retrieve the fragment for you.
-
The view ID of a container for the fragment’s view hierarchy in the activity’s layout. If you take a look at
- Finally, ask the
FragmentManager
to execute the transaction by callingcommit()
.
In the code above, an if
block contains the code that displays the fragment and checks that the activity doesn’t have saved state. When an activity saves, all of its active fragments are also saved. If you don’t perform this check, this could happen:
And you may feel like this:
The lesson: Always keep in mind how the saved state affects your fragments.
And with that, you’ve added the fragment!
Build, run and you’ll see a dog list once the app launches:
FragmentManager
helped achieve this awesomeness through FragmentTransactions
, which are basically fragment operations such as add and remove.
Data Binding
While poking around the project you may have noticed a few things:
- A file called
DataBindingAdapters
. - A reference to
dataBinding
in the app modulebuild.gradle
:dataBinding { enabled = true }
- A data section in the
recycler_item_dog_model.xml
layout file.<layout xmlns:android="http://schemas.android.com/apk/res/android"> <data> <variable name="dogModel" type="com.raywenderlich.android.eldogo.DogModel"/> </data> ... </layout>
- A
DogModel
data class.
If you haven’t used data binding before you may be like…
Let’s take a quick walkthrough.
Normally, if you want to set the value of properties in your layout, you’d use something like the following in your fragments and activities:
programmer.name = "a purr programmer"
view.findViewById<TextView>(R.id.name).setText(programmer.name)
The problem with that is that if you change the value of name
for programmer
, you would need to do a subsequent setText
to the TextView
in order to update the item. Imagine having a tool where you could bind a variable from your fragments and activities to your view and allow for changes to the variable to automatically update in the View. That is what data binding does for you.
Looking at our El Dogo app, the enabled=true
in the build.gradle
enables data binding in the application. Your data class contains data that you want to use in your fragment and display in your view. The data field contains variables consisting of name and type options which specify the type and name of the variable being bound.
This data is used in the view using {@}
notation. For example, the following would set a text field to the value held by the name field of the dogModel variable. You can see this in the TextView
with the ID name
:
tools:text="@{dogModel.name}"
Now that you have your view set up, you need to access your view and bind the variables to it. This is where the data binding magic comes in!
Whenever a view has a data
field, the framework automatically generates a binding object. It creates the name of the object by converting the snake case name of the view into camel case and adding binding to the name. For example, a view called recycler_item_dog_model.xml
would have a corresponding binding called RecyclerItemDogModelBinding
. You can see this in DogListAdapter
in DogListFragment.kt:
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int):
ViewHolder {
val recyclerDogModelBinding =
RecyclerItemDogModelBinding.inflate(layoutInflater, viewGroup, false)
val dog = DogModel(imageResIds[position], names[position],
descriptions[position], urls[position])
recyclerDogModelBinding.dogModel = dog
You can then inflate the view via the inflater method on the binding object and set properties via standard property access mechanisms.
Data binding follows a Model-View-ViewModel (MVVM) pattern. MVVM consists of three components:
- View: The layout file.
- Model: The data class
- View Model/Binder: The auto-generated binding files.
For further reading on the MVVM, and other design patterns, refer to the tutorial Common Design Patterns for Android. You’ll see more on data biding later on.
Communicating With the Activity
Even though fragments attach to an activity, they don’t necessarily all talk to one another without some further encouragement from you.
For El Dogo, you’ll need DogListFragment
to let MainActivity
know when the user has made a selection so that DogDetailsFragment
can display the selection.
To start, open DogListFragment.kt and add the following Kotlin interface at the bottom of the class:
interface OnDogSelected {
fun onDogSelected(dogModel: DogModel)
}
This defines a listener interface for the activity to listen to the fragment. The activity will implement this interface and the fragment will invoke the onDogSelected()
when the user selects an item, passing the selection to the activity.
Add this new field below the existing ones in DogListFragment
:
private lateinit var listener: OnDogSelected
This field is a reference to the fragment’s listener, which will be the activity.
In onAttach()
, add the following directly below super.onAttach(context)
:
if (context is OnDogSelected) {
listener = context
} else {
throw ClassCastException(
context.toString() + " must implement OnDogSelected.")
}
This initializes the listener reference. Wait until onAttach()
to ensure that the fragment actually attached itself. Then verify that the activity implements the OnDogSelected
interface via is
.
If it doesn’t, it throws an exception since you can’t proceed. If it does, set the activity as the listener
for DogListFragment
.
if (context != null)
line in onAttach()
if you like.
Okay, I lied a little: The DogListAdapter
doesn’t have everything you need! In the onBindViewHolder()
method in DogListAdapter
, add this code to the bottom.
viewHolder.itemView.setOnClickListener {
listener.onDogSelected(dog)
}
This adds a View.OnClickListener
to each dog breed so that it invokes the callback on the listener, the activity, to pass along the selection.
Open MainActivity.kt and update the class definition to implement OnDogSelected
:
class MainActivity : AppCompatActivity(),
DogListFragment.OnDogSelected {
You will get an error asking you to make MainActivity
abstract or implement the abstract method onDogSelected(dogModel: DogModel)
. Don’t fret yet, you’ll resolve it soon.
This code specifies that MainActivity
is an implementation of the OnDogSelected
interface.
For now, you’ll show a toast to verify that the code works. Add the following import below the existing imports so that you can use toasts:
import android.widget.Toast
Then add the following method below onCreate()
:
override fun onDogSelected(dogModel: DogModel) {
Toast.makeText(this, "Hey, you selected " + dogModel.name + "!",
Toast.LENGTH_SHORT).show()
}
The error is gone! Build and run. Once the app launches, click one of the dog breed. You should see a toast message naming the clicked item:
Now you’ve got the activity and its fragments talking. You’re like a master digital diplomat!
Fragment Arguments and Transactions
Currently, DogDetailsFragment
displays a static Drawable
and set of Strings
. But what if you want it to display the user’s selection?
First, replace the entire view in fragment_dog_details.xml
with:
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="dogModel"
type="com.raywenderlich.android.eldogo.DogModel" />
</data>
<ScrollView xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:ignore="RtlHardcoded">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/name"
style="@style/TextAppearance.AppCompat.Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dog_detail_name_margin_top"
android:layout_marginBottom="0dp"
android:text="@{dogModel.name}" />
<ImageView
android:id="@+id/dog_image"
imageResource="@{dogModel.imageResId}"
android:layout_width="wrap_content"
android:layout_height="@dimen/dog_detail_image_size"
android:layout_marginTop="@dimen/dog_detail_image_margin_vertical"
android:layout_marginBottom="@dimen/dog_detail_image_margin_vertical"
android:adjustViewBounds="true"
android:contentDescription="@null"
android:scaleType="centerCrop" />
<TextView
android:id="@+id/description"
style="@style/TextAppearance.AppCompat.Body1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="@dimen/dog_detail_description_margin_left"
android:layout_marginTop="0dp"
android:layout_marginRight="@dimen/dog_detail_description_margin_right"
android:layout_marginBottom="@dimen/dog_detail_description_margin_bottom"
android:autoLink="web"
android:text="@{dogModel.text}" />
</LinearLayout>
</ScrollView>
</layout>
This is almost the same as the layout was before except with data binding added. At the top you’ll see that you’ve added a variable for our DogModel. The text for name and description is bound to the variables of the same name in the DogModel object. Then, you’re using this variable to set values on the views.
Binding Adapters
On the ImageView
for the dog image you’ll notice the following tag:
imageResource="@{dogModel.imageResId}"
This corresponds to a binding adapter in the DataBindingAdapters.kt
file.
@BindingAdapter("android:src")
fun setImageResoruce(imageView: ImageView, resource: Int) {
imageView.setImageResource(resource)
}
A binding adapter allows you to perform actions on an element which are not supported by default data binding. In your case, you are storing a resource integer for the image to display, but data binding does not provide a default way to display an image from an ID.
To fix that, you have a BindingAdapter that takes a reference to the object from which it was invoked, along with a parameter. It uses that to call setImageResource
on the imageView
that displays the image of the dog.
Now that your view is set up, replace newInstance()
in DogDetailsFragment
with the code shown below:
private const val DOGMODEL = "model"
fun newInstance(dogModel: DogModel): DogDetailsFragment {
val args = Bundle()
args.putSerializable(DOGMODEL, dogModel)
val fragment = DogDetailsFragment()
fragment.arguments = args
return fragment
}
A fragment can take initialization parameters through its arguments, which you access via the arguments
property. The arguments are actually a Bundle
that stores them as key-value pairs, like the Bundle
in Activity.onSaveInstanceState
or the Activity extras from intent.extras
.
You create and populate the arguments’ Bundle
, set the arguments
and, when you need the values later, you reference arguments
property to retrieve them.
As you learned earlier, when a fragment is re-created, the default empty constructor is used— no parameters for you.
Because the fragment can recall initial parameters from its persisted arguments, you can utilize them in the re-creation. The above code also stores information about the selected breed in the DogDetailsFragment
arguments.
Add the following import to the top of DogDetailsFragment.kt:
import com.raywenderlich.android.eldogo.databinding.FragmentDogDetailsBinding
FragmentDogDetailsBinding
to be available
Now, replace the contents of onCreateView() with the following:
// 1
val fragmentDogDetailsBinding =
FragmentDogDetailsBinding.inflate(inflater, container, false)
// 2
val model = arguments!!.getSerializable(DOGMODEL) as DogModel
// 3
fragmentDogDetailsBinding.dogModel = model
model.text = String.format(getString(R.string.description_format),
model.description, model.url)
return fragmentDogDetailsBinding.root
Breaking it down:
- Inflate the view using
FragmentDogDetailsBinding
. Since you want to dynamically populate the UI of theDogDetailsFragment
with the selection, you grab the reference to theFragmentDogDetailsBinding
. - Get the
DogModel
from thearguments
. -
Next, you bind the view
dogModel
with theDogModel
that you’ve passed toDogDetailsFragment
.
Finally, you need to create and display a DogDetailsFragment
when a user clicks an item, instead of showing a toast. Open MainActivity and replace the logic inside onDogSelected
with:
// 1
val detailsFragment =
DogDetailsFragment.newInstance(dogModel)
supportFragmentManager
.beginTransaction()
// 2
.replace(R.id.root_layout, detailsFragment, "dogDetails")
// 3
.addToBackStack(null)
.commit()
You’ll find this code is similar to your first transaction which added the list to MainActivity
, but there are also some notable differences. In this code you:
- Create a fragment instance that includes some nifty parameters.
- Call
replace()
, instead ofadd
, which removes the fragment currently in the container and then adds the new Fragment. - Call another new friend: the
addToBackStack()
ofFragmentTransaction
. Fragments have a back stack, or history, like Activities.
Navigating the Fragment Back Stack
The fragment back stack is not independent of the activity back stack. Think of it as an extra stack of history on top of that of the host activity.
When you navigate between activities, each one gets placed on the activity back stack. Whenever you commit a FragmentTransaction
, you have the option to add that transaction to the back stack.
So, what does addToBackStack()
do? It adds the replace()
to the back stack so that when the user hits the device’s back button it undoes the transaction. In this case, hitting the back button sends the user back to the full list.
The add()
transaction for the list omits calling addToBackStack()
. This means that the transaction is part of the same history entry as the entire activity. If the user hits the back button from the list, it backs the user out of the app.
Now, build and run and you should see details about each breed when you tap on them:
With that you’re done! You now have an app El Dogo that displays details about the dogs breeds.
Where To Go From Here?
You can find the Final Project for this tutorial by clicking the Download Materials button at the top or bottom of this tutorial.
There is a lot more to learn and do with fragments. Like any kind of tool or feature, consider whether fragments fit your app’s needs and, if they do, try to follow best practices and conventions.
To take your skills to the next level, here are some additional things to explore:
- Use fragments within a
ViewPager
. Many apps, including the Play Store, utilize a swipeable, tabbed content structure viaViewPagers
. You can learn more in our ViewPager tutorial - Use a more powerful, advantageous
DialogFragment
instead of a plain vanilla dialog orAlertDialog
. - Play with how fragments interact with other parts of an Activity, like the app bar.
- Create adaptive UIs with fragments. In fact, you should run through Adaptive UI in Android Tutorial.
- Use fragments as part of the implementation of a high-level behavioral architecture. You can take a look at Common Design Patterns for Android as a good starting point to get the architecture ball rolling.
- To learn more about Data Binding check this reference.
.
We hope that you’ve enjoyed this tutorial. If you have any questions or comments, please join the forum discussion below!
All videos. All books.
One low price.
A Kodeco subscription is the best way to learn and master mobile development — plans start at just $19.99/month! Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalog of 50+ books and 4,000+ videos.
Learn more