Si MyFragment
dépend de MyNestedFragment
et MyNestedFragment
dépend de Deps
; il s'ensuit que MyFragment
dépend également de Deps
. Bien sûr, aucune instance de MyNestedFragment
n'existe lorsque Activity.onAttachFragment()
est appelée, vous devrez donc attendre après avoir gonflé la mise en page dans MyFragment.onCreateView()
avant de fournir MyNestedFragment
avec ses dépendances.
public class MyActivity {
...
void onAttachFragment(Fragment f){
((MyFragment)f).dependencies(deps);
}
public static class MyFragment extends Fragment {
private Deps deps;
void dependencies(Deps deps) {
this.deps = deps;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
// <fragment> element in fragment_main layout has
// android:tag set to nested_fragment
((MyNestedFragment)getChildFragmentManager()
.findFragmentByTag("nested_fragment"))
.dependencies(this.deps);
return rootView;
}
}
public static class MyNestedFragment extends Fragment {
void dependencies(Deps deps) {
...
}
}
...
}
Si tout cela semble un peu en désordre, c'est parce que les fragments ne sont pas POJO vous pouvez simplement câbler d'une certaine manière arbitraire. Leurs cycles de vie doivent être gérés par des gestionnaires de fragments imbriqués. Si vous créez vos fragments par programme plutôt que d'utiliser l'élément <fragment>, vous aurez un peu plus de contrôle sur leur cycle de vie au prix de plus de complexité.
Si vous voulez traiter Android comme un conteneur IoC, alors RoboGuice peut-être ce que vous cherchez:
public class MyActivity extends roboguice.activity.RoboFragmentActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
// This only needs to be called once for the whole app, so it could
// be in the onCreate() method of a custom Application subclass
RoboGuice.setUseAnnotationDatabases(false);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public static class MyNestedFragment extends Fragment {
@Inject
private Deps deps;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// this isn't necessary if you extend RoboFragment
roboguice.RoboGuice.getInjector(activity).injectMembers(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//This would not even be possible in the previous example
// because onCreateView() is called before dependencies()
// can be called.
deps.method();
View rootView = inflater.inflate(R.layout.fragment_nested, container, false);
return rootView;
}
}
}
@Singleton
public class Deps {
public void method() {
System.out.println("Deps.method()");
}
}
Utilisez dagger2? Il a été conçu pour gérer ce genre de choses –
Mimmo Grottoli, je sais dagger2. Mais c'est juste une bibliothèque pour éliminer le code standard de l'injection de dépendance. Il devrait toujours être possible d'injecter des dépendances par constructeur ou par une méthode spéciale. – wilddev
Un constructeur de fragments ou d'activités qui injecte une dépendance?Bien sûr, vous pouvez essayer, mais à la fin, vous trouverez que poignard ou dague2 sont les meilleures choses que vous pouvez développer par vos propres moyens (au moins, c'est vrai pour moi) –