Introduction to Android App Development With Kotlin: Fragments (Part 3)
Learn more about Android app development with Fragments.
Join the DZone community and get the full member experience.
Join For FreeIn this tutorial, we’ll learn more about Fragments — what are they, how to use them, and how to create them.
What Are Fragments?
A Fragment represents a portion of the user interface. You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities.
A fragment must always be hosted in an activity, and the fragment's lifecycle is directly affected by the host activity's lifecycle.
In essence, we’ll use Fragments as our screens. Each screen of our app will be represented as a Fragment. Whenever we navigate to another screen, we will display another Fragment.
How Do I Create a Fragment?
Step 1
In the Project Structure View, navigate to the package that contains the MainActivity. Right-click it, and then click New > Fragment > Fragment (Blank):
Step 2
Time to configure our new Fragment!
- Make sure “Create layout XML” is checked. This will generate the XML layout file for us — how convenient.
- Check “Include fragment factory methods?”
- Check “Include interface callbacks?”
- Source language is naturally Kotlin
- Name it
NewMovieFragment
The newly-created Fragment may seem a little overwhelming at first, but fear not, we’ll break it down into smaller, more manageable chunks, so you’ll know exactly what’s going on.
First of all, what are these constants doing OUTSIDE of the class?
Those are simply static constants and that’s how we define them in Kotlin. If you’d like a more in-depth explanation, read this blog post. We can delete those as we won’t be passing any arguments to this Fragment.
Next up are instance variables and the onCreate
method.
No need to explain the Strings. You may wonder about the OnFragmentInteractionListener
type. This listener will be used to communicate with our activity. Our MainActivity
will implement this listener. You will see the assignment in just a second.
If you haven’t coded in Kotlin before, you may also wonder about this strange argument?.let
expression. arguments
is a nullable type; it can be null. The question mark ?
is also known as a Safe Call operator in Kotlin. let
simply executes a block of code. In this case, if arguments
is null, this block of code will not be executed.
As mentioned above, we won’t need any arguments, so this lets the statement, along with param1 and param2 instance variables, be removed.
onCreateView
method is next in line. This method is responsible for inflating the appropriate XML layout for this Fragment. If you click CMD + Click or CTRL + Click on the name of the layout file (fragment_new_movie), the IDE will take you straight to it.
Next is the onButtonPressed
method, which showcases how we interact with the listener and how we can pass an argument back to our activity. Notice the safe call operator after the listener
, because the listener may be null. It takes in Uri type as an argument. We won’t need this, for now, so let’s go ahead and delete this method also.
onAttach
and onDetach
are up. The code in onAttach
will ensure that our MainActivity
does, in fact, implement the OnFragmentInteractionListener
listener. If it doesn’t, a RuntimeException
will get thrown. onDetach
simply resets the listener to null.
Then, we have the interface definition for OnFragmentInteractionListener
. It defines one method for now, onFragmentInteraction
. Our MainActivity
will have to implement this method.
Last but not least is a construct that allows us to instantiate a Singleton pattern in Kotlin.
As you can see, it takes in two arguments. Let’s remove those then the rest of the code becomes obsolete and we’re left with this
Fragments are not so scary after all, huh? Now that we have our new shiny Fragment, it would be good to use it and tell the MainActivity
to display it for us.
Let’s go back to the MainActivity
layout file: activity_main.xml and replace all of its contents with
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/flContent"
tools:context=".MainActivity">
</FrameLayout>
We’ll use the FrameLayout
to display our new Fragment in it. We’ve assigned it an id of flContent
, which we’ll refer to in the code. Also notice that this FrameLayout
width and height is set to match_parent
, meaning it will take up the whole screen, which is exactly what we want.
Now, in the MainActivity
in the onCreate
method:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (savedInstanceState == null) {
val manager = supportFragmentManager
val transaction = manager.beginTransaction()
transaction.replace(R.id.flContent, NewMovieFragment.newInstance())
transaction.commit()
}
}
Here, we are using the supportFragmentManager
to begin a transaction. The transaction doesn’t get executed until the commit()
method is called, which is advantageous when you are looking to make multiple changes at the same time. In this case, we’re only calling replace()
on whatever is already displayed in flContent
.
You can go ahead and run this code, but we’ll be faced with a nasty exception. Do you know what it is?
2019-02-13 11:41:10.827 28556-28556/ie.redstudio.dzoneapplicationone E/AndroidRuntime: FATAL EXCEPTION: main
Process: ie.redstudio.dzoneapplicationone, PID: 28556
java.lang.RuntimeException: ie.redstudio.dzoneapplicationone.MainActivity@1e15bbf must implement OnFragmentInteractionListener
at ie.redstudio.dzoneapplicationone.NewMovieFragment.onAttach(NewMovieFragment.kt:33)
I hope you do! Our MainActivty
is not implementing OnFragmentInteractionListener
! Let’s fix that. Again, in our MainActivity
, we must declare inheritance on OnFragmentInteractionListener.
It’s easily achieved:
class MainActivity : AppCompatActivity(), NewMovieFragment.OnFragmentInteractionListener {
override fun onFragmentInteraction(uri: Uri) {
}
If we run the code now, everything should be fine and dandy. You’ll see this screen
Conclusion
In this tutorial, we got a bit more intimate with Fragments. It’s important that you understand their structure because they are quite important in the Android ecosystem. You will find yourself creating them all of the time.
In the next tutorial, we’ll be working with the UI layer and you’ll get familiar with the Layout Editor and some of its widgets.
Here’s the complete code from this lesson — simply checkout code tagged as lesson-3.
Opinions expressed by DZone contributors are their own.
Comments