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:
- Make your Fragment class implement the
View.OnClickListener
interface. - 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 withbutton.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();
}
}
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)