lundi 10 octobre 2016

Android: template pattern with fragments

This should be an easy question, but for some reason I am having trouble with it. Let's say I have a FragmentOne and FragmentTwo. FragmentOne looks like this:

private static final String PATH_KEY = "path_key";

private Asset asset;

public FragmentOne() {
    // Required empty public constructor
}


public static FragmentOne newInstance(Asset asset) {
    FragmentOne fragment = new FragmentOne();
    Bundle args = new Bundle();
    args.putSerializable(PATH_KEY, asset);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        asset = (Asset) getArguments().getSerializable(PATH_KEY);
    }
}

@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
        final Bundle savedInstanceState) {
    final FragmentOneBinding binding = DataBindingUtil
            .inflate(inflater, R.layout.fragment_video, container, false);
    bindAsset(binding, asset);
    return binding.getRoot();
}

public void bindAsset(FragmentOneBinding binding, Asset asset) {
    binding.textView.setText("FragOne displays asset like this " + asset.text);
    //this is the only method which differs from FragmentTwo

}

while FragmentTwo looks like this:

private static final String PATH_KEY = "path_key";

private Asset asset;

public FragmentTwo() {
    // Required empty public constructor
}


public static FragmentTwo newInstance(Asset asset) {
    FragmentTwo fragment = new FragmentTwo();
    Bundle args = new Bundle();
    args.putSerializable(PATH_KEY, asset);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        asset = (Asset) getArguments().getSerializable(PATH_KEY);
    }
}

@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
        final Bundle savedInstanceState) {
    final FragmentTwoBinding binding = DataBindingUtil
            .inflate(inflater, R.layout.fragment_video, container, false);
    bindAsset(binding, asset);
    return binding.getRoot();
}

public void bindAsset(FragmentOneBinding binding, Asset asset) {
    binding.textView.setText("But FragTwo, which is very different, displays asset like this " + asset.image.getName());
    //this is the only method which differs from FragmentOne

}

As you can see, in both fragments, the newInstance, onCreate, and onCreateView methods are structurally the same. The only real difference is that the bindView method called from inside the onCreateView of both fragments is not the same.

Using generics, abstract classes, interfaces, or some combination, can I simplify things down to a template design pattern? So that the next time I want to make a fragment with the exact same structure I can do something a little like this?

class FragmentThree extends TemplateFragment {

    @Override
    public void bindAsset(FragmentThreeBinding binding, Asset asset){
        binding.textView.setText(asset.name);
    }

}

I tried making an abstract class already, but you can't have a static method in an abstract class, so newInstance() stops me here. I've tried a few ways of implementing interfaces as well, but am not having any luck.

Aucun commentaire:

Enregistrer un commentaire