Fundamentos de Android Fragments: ¿por qué? ¿Es esto conceptualmente erróneo?

Tengo una pregunta sobre la "programación adecuada" en Android.

Actualmente estoy desarrollando una aplicación usando fragmentos. Implica fragmentos añadidos dinámicamente a la actividad, fragmentos inflados de XML, fragmentos anidados de XML o agregados dinámicamente. Digamos, un poco de todo.

El concepto en el que esta pregunta se centra es el proceso de comunicación involucrado con los fragmentos. Por lo tanto, he leído los documentos y esta no es la primera vez que intento utilizar fragmentos.

El sentido común (y los docs) dicen que si un fragmento quiere hablar o comunicarse con su actividad, debemos utilizar una interfaz.

Ejemplo:

TestFragment

public class TestFragment extends Fragment { private TestFragmentInterface listener; public interface TestFragmentInterface { void actionMethod(); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { if (getActivity() instanceof TestFragmentInterface) { listener = (TestFragmentInterface) getActivity(); } // sending the event if (listener != null) listener.actionMethod(); } } 

TestActivity

 public class Test implements TestFragmentInterface { @Override public void actionMethod() { .. } } 

Todo bien aquí.

Esto mejora la reutilización, ya que mi TestFragment de esta manera puede interactuar con cualquier tipo de Actividad, dado que la Actividad implementa la interfaz que declaro.

Al revés, la Actividad puede interactuar con el fragmento manteniendo una referencia y llamando a sus métodos públicos. Este es también el camino sugerido para fragmentar la comunicación fragmentada, usando la Actividad como un puente.

Esto es genial, pero a veces se siente como usar una interfaz para esto es sólo un poco "demasiado".

Pregunta A

En el escenario los fragmentos que adjunto tienen un papel bastante centrado, lo que significa que se realizan para esa actividad en particular y no se utilizaría de otra manera, es conceptualmente erróneo ignorar la aplicación de interfaz y sólo hacer algo como

 ((TestActivity) getActivity().myCustomMethod(); 

?

Esto también va al escenario donde (no es mi caso, sino simplemente tomarlo como un "en su peor") mi actividad tiene que hacer frente a una gran variedad de estos DIFERENTES fragmentos, lo que significa que debe implementar un método para cada fragmento que debe manejar . Esto trae el código a un lío grande de "líneas potencialmente no necesarias".

Avanzando más: todavía con el uso de fragmentos "enfocados", destinados a trabajar sólo de cierta manera, ¿qué es con el uso de fragmentos anidados?

Se les agregó como

 public class TestFragment extends Fragment { private void myTestMethod() { NestedFragment nested = new NestedFragment(); getChildFragmentManager() .beginTransaction() .add(R.id.container, nested) .commit(); } } 

Esto enlaza NestedFragment a TestFragment. Lo digo de nuevo, NestedFragment, al igual que TestFragment, es para ser utilizado sólo de esta manera, no tiene sentido para trabajar de otra manera.

De vuelta a la pregunta, ¿cómo debo comportarme en esta situación?

Pregunta B

1) debo proporcionar una interfaz en NestedFragment, y hacer que TestFragments implementa NestedFragmentInterface? En este caso yo actuaría como siguiente

NestedFragment

 public class NestedFragment extends Fragment { private NestedFragmentInterface listener; public interface NestedFragmentInterface { void actionMethodNested(); } @Override public void onViewCreated(View view, Bundle savedInstanceState) { if (getParentFragment() instanceof NestedFragmentInterface) { listener = (NestedFragmentInterface) getParentFragment(); } // sending the event if (listener != null) listener.actionMethodNested(); } } 

2) debería (o podría) ignorar la interfaz, y simplemente llamar

 getParentFragment().publicParentMethod(); 

?

3) debo crear la interfaz en NestedFragment, pero dejar que la actividad lo implemente, para que la actividad llamada TestFragment?

Pregunta C

Respecto a la idea de utilizar la Actividad como un puente entre fragmentos, creo que está hecho para un buen ciclo de manejo de todos estos objetos. ¿Es todavía viable hacer un fragmento directo a un fragmento (utilizando la interfaz o llamar directamente a métodos públicos) al tratar de manejar manualmente la excepción que el sistema podría lanzarme?

Intentaré despejarlo todo un poco.

En primer lugar, considere acercarse a establecer el oyente para el fragmento. No es bueno establecer listener en el método onViewCreated, ya que leeds al oyente de reseting exceso cualquier fragmento es creado. Basta con configurarlo en el método onAttach.

Hablé de líneas de código. Llévame a notar, es bueno tener BaseFragment implementado comportamiento común en su aplicación como configuración de FragmentListener crear vista desde el recurso.

Y más que eso para reducir las líneas de código y obtener parte de la reutilización de código puede utilizar genéricos en BaseFragment. Así que mira el siguiente fragmento de código:

 public abstract BaseFragment<T extends BaseFragmentListener> extends Fragment { T mListener; public void onAttach(Activity activity) { super.onAttach(activity); if (Activity instanceof T) mListener = (T) activity; } abstract int getLayoutResourceId(); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View layout = inflater.inflate(getLayoutResourceId(), null); // you can use some view injected tools here, mb ButterKnife return layout; } } 

Respuesta A (para la pregunta A):

Si tienes fragmento sólo exactamente una actividad que debes decidir: "¿De verdad necesitas usar Fragmento aquí?". Pero mb es bueno tener fragmento exactamente para una actividad para extraer alguna lógica de vista de la actividad y borrar la lógica de base. Pero para borrar la lógica de la arquitectura base para su aplicación, utilice Listeners. Esto facilitará la vida a otros desarrolladores

Respuesta B: Para los fragmentos anidados que necesita para resolver, lo que necesitan para utilizar la actividad exacta o sólo fragmentos y utilizarlo como un puente a otro sistema. Si usted sabe que el fragmento anidado será anidado todo el tiempo que usted, usted necesita declarar el fragmento del padre como oyente si no usted tiene que utilizar el otro acercamiento.

Aviso: Como el enfoque base para comunicarse entre la parte diff de la aplicación que puede utilizar los eventos, tratar de mirar también en el autobús de eventos, por ejemplo. Le da un enfoque común para la comunicación y puede extraer la lógica de la llamada de métodos personalizados de los oyentes y más otro, toda la lógica se situará en el manejo de eventos y tendrá un sistema mediador para la cooperación.

Respuesta C: Explico parcialmente una de las aproximaciones a la cooperación entre fragmentos. El uso de un distribuidor de eventos evita que tenga muchos oyentes para toda la comunicación diferente. Algunas veces es muy rentable.

O creo que es más usable usar Actividad, u otras vidas de clase en Actividad, para un mediador para la cooperación de Fragmentos porque hay mucha situación de Fragmentos cambiando durante el ciclo de vida tanto de manejo como de sistema. Y enfoca toda esta lógica en un solo lugar y hace que su código sea más claro.

Espero que mis consideraciones te ayuden.

Ill hacer todo lo posible para responder a la pared de texto aquí 🙂

Pregunta A:

Los fragmentos están diseñados para ser módulos reutilizables que se pueden conectar y reproducir con cualquier actividad. Debido a esto, la única forma correcta de interactuar con la actividad es tener la actividad heredada de una interfaz que el fragmento entienda.

 public class MapFragment extends Fragment { private MapFragmentInterface listener; public interface MapFragmentInterface { //All methods to interface with an activity } @Override public void onViewCreated(View view, Bundle savedInstanceState) { // sending the event if (listener != null) listener.anyMethodInTheAboveInterface(); } } 

Luego, haga que la actividad implemente la interfaz

 public class MainActivity extends Activity implement MapFragmentInterface{ //All methods need to be implemented here } 

Esto permite que su fragmento se utilice con cualquier actividad, siempre y cuando la actividad implemente esta interfaz. La razón por la que necesita esta interfaz es porque el fragmento se puede utilizar con cualquier actividad. Llamar a un método como

 ((TestActivity) getActivity().myCustomMethod(); 

Se basa en el hecho de que su fragmento sólo puede trabajar dentro de una actividad de prueba y, por tanto, "rompe" las reglas de los fragmentos.

Pregunta B y C:

Suponiendo que usted está siguiendo las directrices correctas para los fragmentos y que son módulos independientes. Entonces usted nunca debe tener una situación donde los fragmentos necesitan saber el uno del otro. 99% del tiempo que las personas piensan que necesitan fragmentos para comunicarse directamente pueden re-factor de su problema a la situación que dio más arriba mediante el uso de un MVC Patten o algo similar. Haga que la actividad actúe como el controlador y diga los fragmentos cuando necesitan actualizar y luego crear un almacén de datos independiente.

  • El archivo AIDL no genera un archivo Java
  • Devuelve un valor después del método Activity.runOnUiThread ()
  • Utilizar lista de matrices de objetos como adaptador de hiladora
  • Android: Escuchar cambios de variables
  • Método opcional en la interfaz Java
  • Cómo detectar la dirección de desplazamiento entre izquierda / derecha y arriba / abajo
  • Haciendo que un botón sea más fácil de hacer clic
  • Implementación de la interfaz View.IOnTouchListener
  • Fuentes personalizadas y diseños XML (Android)
  • ¿Podemos usar un ScrollView dentro de un LinearLayout?
  • ¿Es posible utilizar la herencia en las interfaces AIDL?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.