Se MyFragment
dipende MyNestedFragment
, e MyNestedFragment
dipende Deps
; Ne consegue che MyFragment
dipende anche da Deps
. Ovviamente, nessuna istanza di Activity.onAttachFragment()
viene invocata quando Activity.onAttachFragment()
viene chiamato, quindi è necessario attendere fino a dopo aver gonfiato il layout in MyFragment.onCreateView()
prima di fornire MyNestedFragment
con le sue dipendenze.
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) {
...
}
}
...
}
Se tutto questo sembra un po 'confuso, è perché i frammenti non sono POJO si può semplicemente cablare in qualche modo arbitrario. I loro cicli di vita devono essere gestiti da FragmentManager annidati. Se crei i tuoi frammenti a livello di codice anziché utilizzare l'elemento <frammento>, avrai un po 'più di controllo sul loro ciclo di vita al costo di una maggiore complessità.
Se si desidera trattare Android come un contenitore CIO, quindi RoboGuice può essere quello che stai cercando:
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()");
}
}
Utilizzare dagger2? È stato progettato per gestire questo tipo di cose –
Mimmo Grottoli, so di dagger2. Ma è solo una libreria per eliminare il codice boilerplate dell'iniezione di dipendenza. Ci dovrebbe sempre essere il modo di iniettare dipendenze per costruttore o metodo speciale. – wilddev
Un costruttore di frammenti o attività che inietta alcune dipendenze?Certo che puoi provare, ma alla fine scoprirai che il pugnale o il pugnale2 sono le cose migliori che puoi sviluppare da te (almeno, questo è vero per me) –