Question

This is a design question, rather than a technical one.

General case: I want an UI event in a Fragment to make Activity-wide changes.

Specific case: I have two fragments, hosted in the same activity. When the user clicks a button in one of those fragments, I want it to be replaced by the other.

I don't want, however, my Fragments touching my activity. I may want to change the behavior later (maybe, in a bigger screen, show both fragments instead of replacing the first), and I don't want my Fragment code to have that logic.

What I did was implement a Listener class in my fragments, that reports events back to the Activity. This way, if I want to use another Activity class with different display behavior, I can just change the listener and leave the Fragment code untouched.

Is this a good way to go about it? Is there a standard good practice, or a better design pattern?

Was it helpful?

Solution

Using listeners is the recommended way of communicating between Fragment and your activity.

See this Android documentatin section for infromation. Long story short they just implement a listener interface by the Activity class and cast getActivity() result in a fragment to a listener.

From my personal experience this is very convenient because lets you to:

  1. Easilly switch underlying activity (e.g. you host entire fragment in a wrapper activity for compatibility in pre-3.0 and host this fragment along with others in 11+)
  2. Easilly control if the wrapper activity supports callbacks or not. Just check is it does implement the listener and do your app specific actions if it doesn't.

OTHER TIPS

You are right on about using a Listener. This is something I also had to deal with in a project at work. The best way to handle it is to make the Fragment stand-alone in nature. Anything wishing to interact with the Fragment should use its public API and/or set listeners for specific events. If you are familiar with Design Patterns, this is the Observer pattern. The events can be general or specific as well as contain data or no data.

As an example of my project, I had two Fragments. A ListFragment and an InfoFragment that displayed the selected ListItem. The ListFragment already has a Listener interface for my Activity to hook into, but the InfoFragment does not since its your basic Fragment. I added a Listener interface to the InfoFragment that would be notified when the Fragment wanted to close. For the Fragment, this could be by a button press, or specific action occured, but as far as my Activity is concerned, when the Event is triggered, it would close up the Fragment view.

Don't be afraid to use a lot of Listeners for Fragments, but also try to group them by a specific action using data parameters to individualize them. Hope this helps!

A technical answer for:

I have two fragments, hosted in the same activity. When the user clicks a button in one of those fragments, I want it to be replaced by the other.

    FragmentTransaction ft = this.getFragmentManager().beginTransaction();
    Fragment mFragment = Fragment.instantiate(this.Activity(), Fragment2.class.getName());
    ft.replace(android.R.id.content, mFragment);
    ft.commit();
public class Example_3_Mainfile extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);        
         setContentView(R.layout.example_3_mainfile);

                 Fragment fr ;//make class that extend to thefragment 
                 fr = new Act_2_1();                 
                     FragmentManager fm = getFragmentManager();
                     FragmentTransaction fragmentTransaction = fm.beginTransaction();
                     fragmentTransaction.replace(R.id.fragment_place, fr);
                    //id get of fragment tag  from xml file there decelar
                     fragmentTransaction.commit();
                     }
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top