Fragment And Activity Working Together |
Written by Mike James | ||||||
Thursday, 27 March 2014 | ||||||
Page 2 of 5
The Fragment template creates a static factory method for your Fragment unless you untick the option Include fragment factory methods. The factory methods starts off by creating and instance of your Fragment class using the default parameterless constructor:
The factory method is static and hence it has to be called from the class rather than any instance of the class. That is you call it using:
The parameters param1 and param2 are stand-ins for you to change to the number and type of parameters you actually want to use. The parameters are the arguments you are going to use to customise your Fragment's View hierarchy. The template also automatically adds two private fields for you to to store the parameter values in if you need to:
Again you have to change the type, name and number of these variables to fit in with whatever you are passing as parameters. Now we come to the tricky part. You don't want to make use of the parameters passed to the factory method when the Fragment is constructed because it can be destroyed and recreated by the system via the parameterless constructor. Just as in the case of an Activity you have to be prepared to re-set the state of a Fragment when the system restores it and to do this we have to make use of a Bundle. This is exactly what we have to do with the Activity's state and the way a Bundle works was described in Chapter 4. The basic idea is that a Bundle is just an object that you can use to store simple values as name, value pairs. To make this slightly easier, the template creates some default names for each for the parameters it has generated:
Again you need to change these names to suit your actual parameters. For example if the first parameter was a count of something you might edit the first line to read:
The factory method now creates a Bundle object and stores the parameters in it:
and again you need to edit these lines to use appropriate names for the parameters. You also need to change putString to what ever data type you are using of each parameter. Notice that you can only store a limited range of data types in a Bundle - you can't use it to pass an object say (unless the object can be serialized). Finally you make use of the Fragment's setArguments method to store the Bundle:
Ok so now you have stored the Fragment's arguments safely in a Bundle and you can rely on the system to take care of them even if the Fragment is removed. We have yet to see how to make use of the Bundle but this is fairly easy. The complete factory method is:
For the sake of completeness let's see how the same job could have been done using a parametrized constructor instead of a factory method:
To sum up: if the system needs to destroy the Fragment it will preserve its Arguments bundle and make it available again when it restores the Fragment. Using The BundleOk, this is fine but where to you actually make use of them? You have some freedom in this. The basic idea is that you can make use of the getArguments method to retrieve the arguments Bundle anywhere in your Fragment that they are needed. Of course it only makes sense to do this in methods that are called when the Fragment is being created or recreated. In most cases this means retrieving the arguments in the Fragment's onCreate event handler or in the onCreateView handler. The onCreate method is called before the onCreateView handler and it is most often used to retrieve the arguments and store them in locations that the rest of the Fragment can access. It also has the advantage that it keeps the onCreateView method dedicated to what it is supposed to do i.e. create the view. The generated onCreate simply checks to see if there are any arguments to retrieve and if there are it retrieves them and stores them in the private variables:
Following this the arguments that you have passed are accessible via the private fields from anywhere within the Fragment class. if you are following this description it should be clear to you why the template doesn't just store the arguments into the private fields using the factory method or the parametrized constructor. So to summarise:
If you follow these two rules your Fragment will be correctly initialized when you create it and when the system recreates it. The final thing we have to do is look at the onCreateView event handler. This simply inflates the XML layout file and returns it as a result. In a more general situation it might use mParam1 or mParam2 to modify the UI in some way:
A Short ExampleFor an example of changing the UI via the parameters add a Button and a EditText object to the Fragment and we can then set their text fields to whatever is passed in by the factory method:
If you now create the Fragment in the Activity's OnCreate using:
(This code goes anywhere after the setContentView call). You also need to remember to assign the id container to Activity's layout, i.e. @+id/container. Also notice that we are using the support library because that is what the template does - hence getSupportFragmentManager. |
||||||
Last Updated ( Saturday, 25 July 2015 ) |