studio practices medium guidelines course best app android mvp

practices - Android MVP-Cómo comunicarse entre el presentador de actividades y el presentador de fragmentos



mvp android studio (4)

Tengo una actividad con 3 fragmentos, actualmente uso ViewPager. Quiero implementar MVP y comunicarme entre el presentador de actividades y los presentadores de fragmentos, es decir:

  • Pasar datos del presentador de actividad a los presentadores de fragmentos
  • Enviar evento de presentadores de fragmentos a presentador de actividades
  • ...

Pero no sé cómo hacerlo de manera oficial. Puedo usar BusEvent pero no creo que sea una buena práctica.


Datos dinámicos:

Aquí hay un ejemplo usando rxjava2, dagger2 y moxy.

Condicionalidades:

  • Los presentadores no dependen del ciclo de vida de la vista.
  • Un presentador - una vista. Las vistas no comparten a los presentadores entre sí y una vista tiene solo un presentador.

La solución es similar a EventBus, pero en lugar de eso usa Subject con un tiempo de vida limitado. Está en el componente que se crea cuando se inicia la actividad y se destruye cuando sale. Tanto la actividad como los fragmentos tienen un acceso implícito, pueden cambiar el valor y responder a ellos a su manera.

Proyecto de ejemplo: https://github.com/Anrimian/ViewPagerMvpExample

Esto es solo un ejemplo, nunca cambies el tema de esta manera.

Datos estáticos:

Solo usa argumentos en el fragmento y eso es todo.


Para comunicarse entre un Fragment y una Activity (ya sea entre sus presentadores o sus clases), necesita una interfaz que implemente su actividad (como ShoppingInteractor ).

De esta manera puede llamar a ((ShoppingInteractor)getActivity()).doSomething() en los fragmentos. Si desea que el presentador de su actividad se encargue de la tarea, debe llamar al presentador en el doSomething dentro de la actividad.

Puede hacer lo mismo con los fragmentos con otra interfaz y llamar al interactor del fragmento dentro de la actividad.

Incluso puede tener un Presenter getPresenter() dentro de estas interfaces para tener acceso al presentador real. ( ((ShoppingInteractor)getActivity()).getPresenter().sendData(data) ). Lo mismo ocurre con los fragmentos.


Puedes usar un presentador para ese caso.

Use su presentador de actividades para obtener todos los datos que necesitan sus fragmentos. luego crea una clase de interfaz e implementala en tus fragmentos.

Por ejemplo:

Cree una interfaz pública para su PageAFragment (esta interfaz será el puente de sus datos desde la actividad hasta el fragmento). y use el método de su interfaz para manejar el resultado de su presentador para ver.

Este es el ejemplo de la clase de interfaz que creé para los datos recibidos. para el parámetro, usted puede elegir lo que quiera, depende de su necesidad, pero para mí elijo el modelo.

public interface CallbackReceivedData { void onDataReceived(YourModel model); }

En MainActivity Class, verifique la instancia del fragmento que se adjunta a su actividad. Ponga su instancia de comprobación después de confirmar el fragmento.

public class MainActivity extends AppCompatActivity{ private CallbackReceivedData callbackReceivedData; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //after commit the fragment if (fragment instanceof PageAFragment){ callbackReceivedData = (CallbackReceivedData)fragment; } } //this is the example method of MainActivity Presenter, //Imagine it, as your view method. public void receivedDataFromPresenter(YourModel model){ callbackReceivedData.onDataReceived(model); } }

Asumí que el valor recibido de DataDataFromPresenter es el que recibimos y obtenemos los datos para el presentador.

Y ahora pasaremos los datos del presentador a callbackReceivedData

En PageAFragment, implemente el método CallbackReceivedData y anule el método onDataReceived . Ahora puedes pasar los datos de la actividad a tu fragmento.

public class PageAFragment extends Fragment implements CallbackReceivedData{ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onDataReceived(YourModel model) { } }

Nota: De manera alternativa, puede usar Bundle y pasar los datos con el uso de setArguments.

Si desea enviar el Evento de Fragmento a la Actividad , puede seguir esta Idea.

Cree una clase de interfaz e impleméntela en su MainActivity e invalide el método de la interfaz a su actividad, para Mi caso, lo hago de esta manera.

Aquí está mi clase CallbackSendData .

public interface CallbackSendData { void sendDataEvent(String event); }

Implemente la interfaz CallbackSendData en su MainActivity y anule el método sendDataEvent .

public class MainActivity extends AppCompatActivity implements CallbackSendData{ private CallbackReceivedData callbackReceivedData; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //after commit the fragment if (fragment instanceof PageAFragment){ callbackReceivedData = (CallbackReceivedData)fragment; } } //this is the example method of MainActivity Presenter, //Imagine it, as your view method. public void receivedDataFromPresenter(YourModel model){ callbackReceivedData.onDataReceived(model); } @Override public void sendDataEvent(String event){ //You can now send the data to your presenter here. } }

Y para tu PageAFragment necesitas usar el método de conexión para lanzar tu interfaz. El método de enlace llamado una vez que el fragmento está asociado con su actividad. Si desea comprender el ciclo de vida del fragmento, haga clic en este enlace: https://developer.android.com/reference/android/app/Fragment.html .

public class PageAFragment extends Fragment implements CallbackReceivedData{ private CallbackSendData callbackSendData; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onDataReceived(YourModel model) { //Received the data from Activity to Fragment here. } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.PagerAFragment, container, false); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); Button Eventbutton; Eventbutton = view.findViewById(R.id.event_button); Eventbutton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { callbackSendData.sendDataEvent("send Data sample"); } }); } @Override public void onAttach(Context context) { super.onAttach(context); try{ callbackSendData = (CallbackSendData) context; }catch (ClassCastException e){ e.printStackTrace(); } }

}

Y ahora puede usar el CallbackSendData para enviar los datos de la actividad al fragmento.

Nota: Es mucho más fácil si está utilizando la inyección de dependencia en su proyecto, puede usar la biblioteca Dagger2.

Buena suerte.


Según mi entendimiento, para su UseCase, supongamos que ActivityA tiene un viewPager que tiene 3 fragmentos (FragmentA, FragmentB, FragmentC).

ActivityA have ActivityPresenterA

FragmentA tiene FragmentPresenterA

Según MVP, FragmentPresenterA debe ser responsable de todos los flujos lógicos y comerciales de FragmentA solamente y debe comunicarse con FragmentA solamente. Por lo tanto, FragmentPresenterA no puede comunicarse directamente con ActivityPresenterA.

Para la comunicación de Fragmento a Actividad, el presentador no debe participar y esto debe hacerse como lo haríamos en una arquitectura que no sea MVP, es decir, con la ayuda de la interfaz.

Lo mismo se aplica para la comunicación Actividad a Fragmento.

Para la comunicación entre Actividad y Fragmento lea here