In Java an inner class, like the OnClickListener has access to the local variables of its containing class but only if they are declared final. A variable that is declared final can only be assigned to once and in this case there is no reason not to declare the TextView as final - it isn't going to change the object it references.

Now all we have to do is set the onClick hander of the button to the OnClickListener object onclick that we have created:

b.setOnClickListener(onclick);

This is all we have to do. Notice however that it is slightly more subtle than you might think as all of the View objects are only created when the Activity calls the onCreateView method.

If you now run the program you will find that when the button is clicked its text is transferred to the TextView. Notice that this would be true no matter what Activity used the Fragment.

It is behavior inherent to the Fragment.

You also need to be clear what is going on when the system destroys and recreates the Fragment.

If you run the app and click the button you will see the TextView change. If you then rotate the device you will see that the TextView reverts to its original text. If you click the button you will again see that the text changes i.e. the event handler is still working.

What happens is that the system calls the onCreateView when it recreates the Fragment - this sets up the UI and attaches the event handler. All previous state information is lost.

If you want to keep the state information through a destroy-create cycle you have to use the savedInstanceState Bundle that is passed to the onCreateView method. This works in much the same way as for the Activity.

Saving State

Saving the state of a Fragment is very easy.

All you have to do is override the onSaveInstanceState event handler and use the savedInstanceState bundle to store any additional data you need to persist. For example to keep the TextView's current content all you have to do is:

What Does The Activity Do?

In a lot of cases the Fragment is the right place to handle events but what about the Activity - does it get to do anything useful?

The whole point of a UI, even a fragment of a UI, is to provide some data to or display some data from the application. At some point the Fragment has to accept data or give data to the application and the Activity in particular.

To get data from the Fragment there is nothing new as the Activity can simply access the View objects created by the Fragment in the usual way using findViewById or similar. To put data to the Fragment the Activity can use the same technique. The Fragment can also offer the Activity public properties which it can set and get. There is nothing new here.

The only complication is that the Fragment can be destroyed and recreated by the system by calling its onCreateView. What this means is that any public properties it might have could be re-initialised at any time.

The solution is, of course, to preserve the state of the Fragment using the Bundles provided for the job.

There is a tricky problem if the Activity tries to attach an event handler to a View provided by the Fragment. There is nothing wrong with creating a listener in the Activity and setting it as the event handler for a View object created by the Fragment. This works perfectly until the moment the Fragment is destroyed and recreated by the system calling the onCreateView. At this point the View object that the event handler was attached to is recreated and the connection to the event handler is lost.

The simplest solution is to set the event handler each time the Activity onCreate is called but this turns out to have lots of subtle difficulties - there are better but more elaborate solutions which will be explained in detail in the next chapter.

You just need to be very aware that the fact that the Fragment can be destroyed and recreated at any time makes its use more complicated than you might first think.

When you have a single Fragment backed by an Activity there seems to be little point in splitting the code between the two. However if you keep in mind the idea that the Fragment should provide the UI and the Activity should provide the processing then you have a good division of concerns and code which should allow the Fragment or the Activity to be reused. If you know about the MVC - Model View Controller - design pattern then you can think of the Fragment as the View and the Activity as the Model.

Things get much more interesting when you build an application with multiple Fragments and this is something we have to look at in a later installment.