You just need abstraction. Since resources are identified using an integer index into the R class, you can use int variables as placeholders for the layout files, and given the fact a layout element ID is searched within the active layout, you can recycle the common elements. First, create a common fragment class, with all the common elements:
public abstract class BaseFlavorFragment extends Fragment {
/*Define an interface for whatever code the fragment may need from the outside and a member for keeping reference of that. You can also use the host activity, this is just for flexibility*/
public interface whateverThisDoes{
void do();
}
/*All the common fragment members go here, as protected so you can reach them from every subclass*/
protected TextView title;
protected Button mainButton;
protected whateverThisDoes listener;
public void setWhateverThisDoes(whateverThisDoes listener){
this.listener = listener;
}
/*Finally, create a int variable that will hold the reference to the layout file you need to use. you will set this in every flavor using the setContainer method.*/
protected int layout = 0;
/*this will allow you to select which XML to use
layout = R.layout.flavorlayout*/
public abstract setContainer();
/*Use this method to inflate any flavor members, like the Frame you mentioned*/
public abstract void inflateComponents();
/*Use this to set listeners, data, or anything the flavor controls do*/
public abstract void setBehaviors();
/*Set here anything the common controls do*/
protected void setCommonBehaviors(){
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//whatever
}
});
setBehaviors();
}
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContainer();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(layout, container, false);
/*Inflate common components*/
title = (TextView) root.findViewById(R.id.title);
button = (Button) root.findViewById(R.id.button);
/*inflate flavor components, if there's any*/
inflateComponents();
/*assign data, listeners, whatever the flavor controls do*/
setBehaviors();
return view;
}
}
Now, you can just create an implementation for Foo and Bar. if the only difference is the layout file, put everything into the base class, and set the layout file using setContainer(). If you have more differences you just need to deal with them into each abstract method. The base class can live into the the common code, the implementations, into each flavor. If you don't need to set any behavioral code from the outside, you can drop the interface.