30
loading...
This website collects cookies to deliver better user experience
extends
the Fragment
class.public class ExampleFragment extends Fragment {
}
extend
the androidX Fragment class. This allows the Android OS to recognize the class as an activity and it allows us use our own app logic any overridden Fragment methods. Well will later add a constructor to inflate the view but for now just leave it as it is.<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity
. The reason for this is that a fragment can not exist outside of an activity. A fragment does not replace an activity, it simply enhances one. Next notice the FragmentContainerView
, this defines where the fragment is going to be placed within the activity's view hierarchy. You may have seen FrameLayout
being used instead of FragmentContainerView but that is now depreciated. The documentation specifically states, It is strongly recommended to always use a FragmentContainerView as the container for fragments, as FragmentContainerView includes fixes specific to fragments that other view groups such as FrameLayout do not provide.
. So if you see any tutorials that use FrameLayout make sure to replace them with FragmentContainerView.<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/crime_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/example_text" />
</LinearLayout>
public class ExampleFragment extends Fragment {
public ExampleFragment(){
super(R.layout.fragment_example);
}
}
Notice that all we are doing is adding our fragment's XML file to the super constructor of our previously defined ExampleFragment class. We can do this because the Fragment class has an alternative constructor that can be called to provide a default layout. This fits perfect with our simple layout. However, if you have a more complex layout with extra logic, say you need to add a TextWatcher to a TextView. If that is the case then you can inflate the View inside of the onCreateView() method. Just make sure to only inflate inside of that method. The logic should be moved to the onViewCreated() method.
Now before we move onto the fifth and final step we need to talk about a few things. We need to understand what a FragmentManager
, FragmentTransaction
is and understand a little about the fragment lifecycle
.
back stack
. If you are unfamiliar with the back stack
it simply a data structure that is used to organize fragments and it operates on the typical stack notion of first in last out
. Thanks to the back stack the user is able to navigate with the back button. In terms of the fragment's lifecycle the Fragment Manager is responsible for determining what state the fragment should be in and then moving it to that state.So at runtime we can use the FragmentManager class to add, remove, replace or other actions with fragments. Each set of fragment changes that we commit is called a fragment transaction
. We save each transaction to the back stack that is managed by the Fragment Manager. As you will see later, we create a fragment transaction by calling beginTransaction()
.
Now that we have those terms defined, lets move on to step 5.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(savedInstanceState == null){
getSupportFragmentManager().beginTransaction()
.setReorderingAllowed(true)
.add(R.id.fragment_container_view,ExampleFragment.class,null)
.commit();
}
}
}
Normally our fragment must be embedded within a FragmentActivity class to be able to contribute a portion of the UI to that activity's layout. However, AppCompatActivity is actually a subclass of FragmentActivity so we still inherit from FragmentActivity. AppCompatActivity not only provides us with the FragmentActivity methods, it also allows older Android devices access to newer features, like built in switching between light and dark mode. Then we check if the savedInstance is null, why do we do this? Well this ensures that the fragment is added only once when the activity is first created. When something like a configuration change occurs(screen flip) and the savedInstance is no longer null, the fragment will be automatically restored from the savedInstanceState.
Then we have the classic onCreate() method that gets called during the activity's creation. It gets passed a Bundle
object which contains any previously saved state. the super.onCreate(savedInstanceState);
is to make sure the original onCreate() method gets called, despite us overriding it. setContentView(R.layout.activity_main)
is setting the activity's view. Now lets explain some of those weird looking method calls.
ExampleFragment.class
is accessing the instance of this class in memory. What this means is that for any class that we create, Java will automatically create and store an instance of it in memory. So the ExampleFragment.class
is us accessing the stored instance in memoryThe final call on each fragment transaction must commit the transaction. commit() signals to the fragment manager that all operations have been added to the transaction
That is it, we have successfully finished all of the steps to create an fragment in android. But before we go I want to talk a little about the fragment lifecycle.
INITIALIZED
state. In this state the methods onCreateView() and onViewCreated() are called. In our example we don't use those methods but we should still notice that they are being called. In order for a fragment to transition through the rest of its lifecycle it must be added to a fragment manager. The fragment manager is responsible for determining what state a fragment should be in and then moving them into that state. Once a fragment has been added to the fragment manager it enters the CREATED
state. This state is where we would want to restore any previously saved state.public class ExampleFragment extends Fragment {
public ExampleFragment(){
super(R.layout.fragment_example);
}
}