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?
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!