DEV Community

Cover image for Using Fragments Dynamically
Pete
Pete

Posted on

Using Fragments Dynamically

One difference between the lifecycle methods of activities and fragments is in their access modifiers. Activity lifecycle methods are protected while Fragment lifecycle methods are public.

The First Problem With Fragments

In fragments, adding the onClick property to a button or any subclass of the Button class does not work the expected way.
When you add the onClick property in a fragment, android looks for the callback method in the fragment's parent activity, and if the method isn't there, the app crashes(even if the method is in the Fragment class).

The Solution???

You can try to solve this problem by moving the fragment's methods into the parent activity. That solution would work but its side effect would be that if you wanted to reuse the fragment in another activity, you would have to declare the same methods in that activity.

You want your fragments to be self-contained so that won't be recommended. Like every programming problem, there is a solution somewhere. You just have to find it.

The Real Solution

To be able to define your onClick handler methods in your fragment, you can take these steps:

  1. Make your Fragment class implement the View.OnClickListener interface.
  2. Override the fragment's onClick method and use an if-else or a switch to give it different callbacks depending on the id of the view that was clicked. 3 For every button you want to handle, attach the onClick listener to it with button.setOnClickListener(this).

The Second Problem With Fragments

A dynamic fragment's state does not survive configuration changes if it is nested into an activity's layout with the <fragment/> tag. However, it survives if it is added to the activity with a FragmentTransaction and a little tweak.

The Little Tweak

The tweak is adding a fragment to a FrameLayout dynamically and doing that only if the activity is being created from scratch so that you won't overlay a fragment that is being recreated.

Doing this is very simple. Add code to the onCreate method of the activity that checks if the Bundle named savedInstanceState is null.
If the bundle is null, it means the activity is being created from scratch. If it isn't null, it means the activity is being recreated.

Look at the code snippet below.

@Override
protected void onCreate(Bundle savedInstanceState) {
  ...
  if (savedInstanceState == null) {
    DemoFragment frag = new DemFragment();
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.add(R.id.fragment_container, frag);
    transaction.addToBackStack(null);
    transaction.commit();
  }
}
Enter fullscreen mode Exit fullscreen mode

Code breakdown

This code snippet is used to add a fragment to an activity only if the activity is being created from scratch.

DemoFragment is the name of the fragment class that you must have created somewhere in your code.

frag is the name of the Fragment instance that you want to add to the activity.

fragment_container is the id of the FrameLayout you want to place your fragment in.

If savedInstanceState is null, it means the activity is being created from scratch, the child fragment has not been rendered yet, and you proceed to add logic for adding the child fragment.

Be sure to notice how the onCreate method's access modifier is protected

Previous article: Switching Fragments With Code

Next article: Displaying Nested Fragments

Top comments (0)