Reputation: 2789
I'm not sure if this is doable, but I'm trying to pass a Fragment Class as a parameter so that I can have a centralized class with ONE method for multiple other classes.
Here is the method that I'm trying to write but I'm missing the "Fragment Class argument" in the method:
public void onStartFragment(??? ???, Fragment fragment, int containerViewId) {
fragment = (???) getChildFragmentManager().
findFragmentByTag(???.class.getName());
if (fragment == null) {
fragment = ???.newInstance();
}
FragmentTransaction childFragmentTransaction = getChildFragmentManager().beginTransaction();
childFragmentTransaction.replace(containerViewId,
fragment, ???.class.getName())
.addToBackStack(null).commit();
}
My Goal is to have one method that can be used to start any fragment.
Upvotes: 1
Views: 3386
Reputation: 2789
Continuing on @natario answer, I used the start fragment method in a separate class:
public class FragmentSeparateClass extends Fragment {
public void onStartFragment(Context context, FragmentManager fragmentManager, String className, int containerViewId) {
Fragment fragment = fragmentManager.findFragmentByTag(className);
if (fragment == null) {
fragment = Fragment.instantiate(context, className);
}
fragmentManager.beginTransaction()
.replace(containerViewId, fragment, className)
.addToBackStack(className)
.commit();
}
}
Then I used the method in the needed Fragment classes, for instance:
fragmentSeperateCLass.onStartFragment(getContext(), getChildFragmentManager(), FirstChildFragment.class.getName(),
R.id.firstChildFragmentLayout);
}
Upvotes: 1
Reputation: 25194
If you are planning to use the class name as a tag (and maybe a backstack entry name), just pass the class name, not the fragment.
Then use Fragment.instantiate(context, className)
to have an instance of your class.
public void onStartFragment(String className, int containerViewId) {
FragmentManager manager = getChildFragmentManager();
Fragment fragment = manager.findFragmentByTag(className);
if (fragment == null) {
fragment = Fragment.instantiate(context, className);
// fragment is a className instance now
}
manager.beginTransaction()
.replace(containerViewId, fragment, className)
.addToBackStack(className)
.commit();
}
The method can be refined further depending on your desired behaviour, but you got the point. You can also pass a Class<? extends Fragment>
if you wish.
Upvotes: 2
Reputation: 191743
Method overloading might help you here
public void onStartFragment(FragmentManger manager, Fragment fragment, String tag, int containerViewId) {
// could check for tag here
manager
.beginTransaction()
.replace(containerViewId, fragment, tag)
.addToBackStack(null).commit();
}
public void onStartFragment(Fragment fragment, String tag, int containerViewId) {
onStartFragment(
getFragmentManager() // Or child, if you are in a Fragment already
fragment, tag, containerViewId);
}
public void onStartFragment(Fragment fragment, int containerViewId) {
onStartFragment(fragment, null, containerViewId);
}
Place whereever you need to call those methods,
MyFragment frag = new MyFragment();
onStartFragment(frag, frag.class.getName(), R.id.container); // for example
In other words, this should probably be handled externally of that method since I'm not sure you can reliably get ???.class.getName()
fragment = (???) getChildFragmentManager().
findFragmentByTag(???.class.getName());
if (fragment == null) {
fragment = ???.newInstance();
}
Upvotes: 1