简体   繁体   中英

Organize multiple Fragment interfaces in an Activity

I'm creating an app that uses multiple fragments in a single activity, and most of the fragments need to interact with the Activity. I'm using a separate Interface for each fragment, which the Activity implements.

To give you an idea of how it looks like presently

public class MainActivity extends AppCompatActivity implements
    Fragment1.Fragment1Interface,
    Fragment2.Fragment2Interface,
    ListAdapter1.ListAdapter1Interface,   
    Fragment3.Fragment3Interface,
    MyDrawerLayout.MyDrawerCallbacks {

       /* Code omitted for brevity... */

        @Override
        public void onCancel(long id) {

        }

        @Override
        public void onSave(long id) {

        }

}

As you can see, there are quite a lot of interfaces that need to be implemented. This is okay, but what bothers me is that the implementation of the methods of the various interfaces don't give any clue about which interface/fragment they belong to. onCancel() and onSave() are very generic, so by only looking at the code there is no way to know if they belong to Fragment1Interface , Fragment2Interface , etc.

Of course, I could prefix each interface method with the interface name, resulting in something like

@Override
public void Fragment1Interface_onCancel(long id) {

}

@Override
public void Fragment2Interface_onSave(long id) {

}

and so on.

Is there any easy way to achieve some kind of "scoping" in regards to interface implementations? I know I could pass an object to each fragment which implements the respective interface, but it's quite a bit more work than simply relying on the Activity which can be easily retrieved by getActivity() from within the Fragment.

Another option I considered was to have a common interface like

public interface FragmentInteractionInterface{
    public FragmentInterface getInterface(Fragment fragment);
}

public interface FragmentInterface{}


public interface Fragment1Interface extends FragmentInterface{
    public void onCancel(long id);
}

public interface Fragment2Interface extends FragmentInterface{
    public void onSave(long id);
}

The idea being here that the Activity would only implement the FragmentInteractionInterface, and return a specific implementation of FragmentInterface based on the type of fragment in getInterface() , like so

public FragmentInterface getInterface(Fragment fragment){
    if( fragment instanceof Fragment1 )
        return mFragment1InterfaceImplementation;
    else if( fragment instanceof Fragment2 )
        return mFragment2InterfaceImplementation;
}


Fragment1Interface mFragment1InterfaceImplementation = new Fragment1Interface(){
    @Override
    public void onCancel(long id){
        // Do something
    }
}

Fragment2Interface mFragment2InterfaceImplementation = new Fragment2Interface(){
    @Override
    public void onSave(long id){
        // Do something
    }
}

(Obviously the names of the fragments are more descriptive in real life!)

The only other (easy) way I can think of is to surround each of the implemented interface methods with comments, grouping them together (some interfaces contain many methods).

It seems like there should be a better way of achieving this kind of "grouping" in an easy way, without resorting to having to pass separate implementation objects to each fragment... any ideas?

In general, it's a good practice to prevent clients (fragments) knowing about methods they don't use. Such interfaces called role interfaces, so I'd stick with interface per fragment approach.

Answering your question, why you're so convinced that implementer should explicitly specify interface/method relation? You pointed that method names are too generic, but that's naming problem. Actions scoped to fragment should stay there, and actions logically related to activity, therefore, would have the appropriate naming.

If you still persist on this idea of clean separation, I'd recommend using some sort of annotation processing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM