Cómo implementar el visor usando la arquitectura MVP
El significado correspondiente de MVP: M-Model-model, V-View-view, P-Presenter-presenter.
Vista
La vista generalmente se implementa mediante Actividad y la Vista de fragmento contendrá una o más referencias del Presentador para satisfacer la lógica empresarial de la vista. La interacción entre Vista y Presentador es bidireccional, es decir, la capa Vista puede llamar a los métodos lógicos del Presentador y el Presentador también puede controlar la visualización de la Vista.
Presentador
Como puente entre el Modelo y la Vista, el Presentador es responsable de obtener datos del Modelo, procesarlos y devolverlos a la Vista. Sin embargo, la comunicación entre el Presentador y las otras dos capas se realiza a través de protocolos de interfaz, por lo que cada Presentador suele contener uno o más protocolos de interfaz.
El modelo, al igual que MVC, sirve como almacén de datos y solo es responsable de procesar los datos de la aplicación. Los ejemplos en la práctica del modelo MVP de desarrollo de Android dividen la aplicación en las siguientes cuatro capas.
Entidades: Clases empresariales en APP. Casos de Uso: Responsable de procesar y empaquetar datos de Entidades. Presentadores: obtienen datos procesados de
casos de uso y luego proporcionan los datos apropiados a la interfaz de usuario de acuerdo con la lógica de demanda. UI: obtenga datos finales procesados de los presentadores e interactúe directamente con los usuarios.
El principio de estas cuatro capas de diseño es que las llamadas de código solo pueden expandirse desde el círculo exterior al círculo interior. El círculo interior no puede interferir y no necesita preocuparse por la lógica funcional del círculo exterior. Esto está en línea con la idea de MVP: los casos de uso y los presentadores separan las entidades y la interfaz de usuario, de modo que las entidades y la interfaz de usuario solo necesitan preocuparse por su propia lógica y el procesamiento de datos queda completamente a cargo. las otras dos capas.
Aquí, algunos estudiantes pueden tener preguntas: ¿por qué los Presentadores acordados tienen
Casos de Uso que interrumpen la situación? De hecho, este es también el propósito de elegir este proyecto como ejemplo. He leído muchos artículos de MVP, todos los cuales hablan sobre cómo el Presentador interactúa con las otras dos capas a través del protocolo de interfaz, pero la mayoría ignora la estructura de. la capa del Presentador en sí, porque solo aplican el modelo MVP. Aunque reduce el acoplamiento de la Vista hasta cierto punto, debido a que el Presentador no solo procesa datos sino que también controla la interacción de la interfaz de usuario según los requisitos, es probable que haya redundancia en la lógica del Presentador. que ocurra. El siguiente proyecto de ejemplo engloba los casos de uso
entre Presenter y el modelo, y entrega el procesamiento de lógica de datos a los casos de uso, lo que permite a Presenter centrarse más en la interacción de la interfaz de usuario.
NO1. Cree una nueva interfaz de visualización pública ***: /** *?Creada?por?Bluesky?el?2015/8/27 *?La interfaz pública *** de la capa V. en MVP* /
public?interface?IView?{
public?void?showProgressPar();
public?void?hideProgressPar(); p>
public?void?showError(Object?o);
}
La vista hereda la interfaz pública ***IView/** *?Creado?por?Bluesky ?el?2015/8/27. *?Iniciar sesión Ver interfaz*/
public?interface?ILogin?extends?IView?{ public?void?showSuccess(Object?o);
}
La implementación de NO2 y VIew.
Es decir, Actividad implementa la interfaz ILogin: /** *Página de inicio de sesión Actividad */
public?class?MainActivity?extends?Activity?implements?ILogin?{
private?LoginPresenter ?mPresenter ;
privado?Usuario?mUser;
privado?ProgressDialog?mDialog;
@Override
protegido?void?onCreate (Paquete ?savedInstanceState)?{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPresenter?=?new? LoginPresenter( this);
mUser?=?new?User();
initVIew();
}
¿privado? ¿void? initVIew()?{
final?EditText?pwd?=?(EditText)?findViewById(R.id.pwd);
final?EditText?name?=? (EditText )?findViewById(R.id.name);
Button?loginBtn=?(Button)?findViewById(R.id.login_btn);
loginBtn.setOnClickListener(new ?Ver .OnClickListener()?{
@Override
public?void?onClick(View?view)?{
mUser.setName(nombre.getText () .toString());
mUser.setPassword(pwd.getText().toString());
mPresenter.login(mUser);
}
});
}
@Override
¿público?boolean?onCreateOptionsMenu(¿Menú?menú)?{ p>
//?Inflar?el?menú;?esto?agrega?elementos?a?la?barra?de?acciones?si?está?presente.
getMenuInflater().inflate( R. menu.menu_main,?menu);
return?true;
}
@Override
public?boolean?onOptionsItemSelected (MenuItem?item)?{
//?¿Maneja?barra de acciones?¿elemento?hace clic?aquí.?La?barra?de?acciones?
//?manejará automáticamente ?hace clic en el botón Inicio/Arriba durante un tiempo prolongado
//?mientras?especifique?una?actividad?principal?en?AndroidManifest.xml.
int?id?=?elemento
.getItemId();
//noinspection?SimplifiableIfStatement
if?(id?==?R.id.action_settings)?{
return?true ;
}
return?super.onOptionsItemSelected(item);
}
@Override
público ?void?showSuccess(Object?o)?{
Usuario?user=?(Usuario)?o;
Toast.makeText(this,"Mensaje de inicio de sesión exitoso:"+usuario .getName()+"?/"+user.getPassword(),Toast.LENGTH_LONG).show();
}
@Override
público ?void?showProgressPar()?{
mDialog?=?new?ProgressDialog(MainActivity.this);
mDialog.setMessage("Cargando...");
p>mDialog.show();
}
@Override
public?void?hideProgressPar()?{
mDialog.hide();
}
@Override
public?void?showError(Object?o)?{
Toast.makeText(this,"Exception:"+((Exception)o).getMessage(),Toast.LENGTH_LONG).show();
}
} p >
Diseño XML de la actividad: android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/hello_world"/> android:id="@+id/name" Android :layout_width="match_pare nt" android:layout_height="wrap_content" android:hint="Ingrese su nombre de usuario" /> < Editar texto android:id="@+id/pwd" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Por favor, introduce tu contraseña" /> android:id="@+id/login_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Iniciar sesión"/>
No3. Cree un nuevo LoginPresenter. Estamos programando para interfaces, por lo que no hay ningún método en la demostración para crear una interfaz de Presenter.
interfaz del presentador/** *?Creado?por?Bluesky?el?27/8/2015 *?P capa en MVP*/
interfaz?pública?Presentador?{
}
Inicie sesión en el presentador para implementar la interfaz del presentador, donde los puentes de las capas Vista y Modelo están conectados, se realiza la programación comercial y desempeña un papel de mando/** *?Creado?por?Bluesky ?el?2015/8/27 . */
público?clase?LoginPresenter?implements?Presenter?{
privado?ILogin?mLoginView;
privado ?ILoginBiz?mLoginBiz;
privado?Handler?mHandler?=?new?Handler();
público?LoginPresenter(ILogin?mLoginView)?{
this.mLoginView?=?mLoginView;
this.mLoginBiz?=?new?LoginBizImpl();
}
/** *?Iniciar sesión* * ?@param?o */
public?void?login(Object?o)?{
mLoginView.showProgressPar();
mLoginBiz.login( o,?new?Listener() ?{
@Override
public?void?complete()?{
mHandler.post(new?Runnable( )?{
@Override
public?void?run()?{
mLoginView.hideProgressPar();
}
}) ;
}
@Override
public?void?onSuccess(final?Object?o)?{
mHandler.post( new?Runnable()?{
@Override
public?void?run()?{
mLoginView.showSuccess (o);
}
});
}
@Override
¿público?void? onFailed(final?Exception?e)?{
mHandler.post(new?Runnable()?{
@Override
public?void?run( )?{
mLoginView.showError(e);
}
});
}
});
}
}
No4, la capa Modelo realiza el procesamiento de lógica de negocios. Cree una nueva interfaz de capa de modelo y luego implemente el procesamiento de lógica de negocios, el procesamiento asincrónico y la comunicación entre subprocesos y subprocesos principales.
interfaz del modelo: /** *?Creado?por?Bluesky?el?27/8/2015 */
interfaz?pública?ILoginBiz?{
public?void?login. (Objeto?o,Listener?listener);
}
Implementación del modelo: /** *?Creado?por?Bluesky?el?2015/8/27 */<. /p>
¿clase?pública?LoginBizImpl?implementos?ILoginBiz?{
@Override
público?void?login(Objeto?o,?final?Listener?listener) ?{
final?Usuario?usuario?=?(Usuario)?o;
¿nuevo?Hilo(nuevo?Ejecutable()?{
@Override
public?void?run()?{
¿intentar?{
Thread.sleep(2?*?1000);
}?catch?(InterruptedException?e)?{
e.printStackTrace();
}
listener.complete();
if?(user.getName().equals(user.getPassword()))?{//Éxito
listener.onSuccess(usuario);
}?else ?{//Failed
listener.onFailed(new?Exception("Excepción en ejecución..."));
}
}
}).start();
}
}
Clase de entidad: /** *?Creado?por?Bluesky?en?2015 /8/27. */
¿Clase?pública?¿Usuario?implementos?Serializable?{
¿Cadena?privada?nombre;
¿Cadena?privada?contraseña. ;
público?String?getPassword()?{
return?contraseña;
}
público?void?setPassword(String ?contraseña)?{
esta.contraseña?=?contraseña;
}
¿pública?String?getName()?{
return?name;
}
public?void?setName(String?name)?{
este.nombre?=?name;
}
}
Interfaz de devolución de llamada: /** *?Creado?por?Bluesky?el?2015/8/27 */
pública?void?complete();
pública?void?onSuccess(Object?o);
pública? void?onFailed(¿Excepción?e);
}