¿Cómo inyectar la dependencia al fragmento androide anidado?
Para un ordinario (no anidados fragmento), uso el siguiente enfoque
1) crear un método de dependencias (…) para establecer las dependencias de los fragmentos
- Uso de Dagger 2 para inyectar en servicio
- Dagger no puede crear el gráfico del objeto aunque puede producir el archivo del punto
- InjectView en RoboFragment
- Daga 2 - dos proporciona el método que proporcionan la misma interfaz
- Android: ¿Cómo pasar mejor los datos a una vista?
class MyFragment extends MyFragment { void dependencies(Deps deps); }
2) en la actividad de los padres MyFragment onAttachFragment () sólo proporciono dependencias para el fragmento
class MyActivity{ void onAttachFragment(Fragment f){ ((MyFragment)f).dependencies(deps); } }
Para el fragmento anidado no hay más fragmento onAttachFragment llamado. Proporcionar dependencias de fragmento sólo para proporcionar dependencias de fragmentos anidados parece ser muy engorroso. Entonces, ¿cómo puedo proporcionar dependencias para ello?
- @Named proveedores con los mismos tipos de retorno terminan dando java.lang.IllegalArgumentException: Duplicar
- Aplicación para Android con RoboGuice 2.0 - Cómo inyectar un singleton con el contexto de la aplicación
- Obtener la actividad actual de Application.Context - MonoAndroid
- Alcance y subcomponentes de Dagger 2
- Android Dagger actualiza los valores fuera del módulo
- Manejo del componente de la daga en el cambio de orientación
- ¿Cómo probar una actividad que utiliza un ContentProvider sin afectar la base de datos de producción?
- Cómo inyectar el contexto usando RoboGuice en Android?
Sólo hazlo fuera del contexto que será una actividad. Cree un getter para las dependencias de su actividad. Los fragmentos tienen acceso a la actividad padre si están anidados o no. Transmita el contexto y luego llama al getter para obtener las dependencias en la actividad anidada.
Si MyFragment
depende de MyNestedFragment
, y MyNestedFragment
depende de Deps
; Se deduce que MyFragment
también depende de Deps
. Por supuesto, no existe ninguna instancia de MyNestedFragment
cuando se llama a Activity.onAttachFragment()
, por lo que tendrá que esperar hasta que haya inflado el diseño en MyFragment.onCreateView()
antes de proporcionar MyNestedFragment
con sus dependencias.
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 todo esto parece un poco desordenado, eso es porque Fragmentos no son POJOs que sólo puede cablear de alguna manera arbitraria. Sus ciclos de vida deben ser gestionados por FragmentManagers anidados. Si crea sus fragmentos de forma programática en lugar de utilizar el elemento <fragment>, tendrá un poco más de control sobre su ciclo de vida a costa de más complejidad.
Si desea tratar Android como un contenedor IoC, entonces RoboGuice puede ser lo que está buscando:
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()"); } }
Intenta establecer las dependencias, cuando se adjuntan los fragmentos. En lugar de esto, intente obtener las dependencias del fragmento cuando sea necesario. Hay un ejemplo:
public class MyActivity extends Activity { public Deps getDepsForFragment(Fragment fragment) { if (fragment instanceof MyFragment) { return depsForMyFragment; } else if (fragment instanceof MyNestedFragment) { return depsForMyNestedFragment; } else { return null; } } } public class MyFragment extends Fragment { private Deps deps; @Override public void onAttach(Context context) { super.onAttach(context); try { MyActivtiy myActivity = (MyActivtiy) context; deps = myActivity.getDepsForFragment(this); } catch (ClassCastException e) { throw new ClassCastException("This fragment attached to an activity which can't provide the required dependencies."); } } } // this is the same as the MyFragment public class MyNestedFragment extends Fragment { private Deps deps; @Override public void onAttach(Context context) { super.onAttach(context); try { MyActivtiy myActivity = (MyActivtiy) context; deps = myActivity.getDepsForFragment(this); } catch (ClassCastException e) { throw new ClassCastException("This fragment attached to an activity which can't provide the required dependencies."); } } }
Por supuesto, puede hacer un método separado para obtener deps en la actividad (como getDepsForMyFragment
y getDepsForMyNestedFragment
).
Basta con mantener la lógica de la jerarquía, y debe ser algo como esto:
class MyActivity{ void onAttachFragment(Fragment f){ ((MyFragment)f).dependencies(deps); } } class MyFragment extends MyFragment { void dependencies(Deps deps) { //TODO: do dependencies of my fragment before ((MyNestedFragment)childF).nestedDependencies(deps); //TODO: do dependencies of my fragment after } } class MyNestedFragment extends MyNestedFragment { void nestedDependencies(Deps deps); }
- AdjustResize no funciona con CoordinatorLayout
- Obtención de pantalla en negro cuando se agrega ExoPlayer a GLSurfaceView