• 【架构】整理了一份通用的MVP框架示例代码


           最近回顾了一下MVP框架,结合阅读到的几篇不错的博客,自己整理了一份可用于实际工作的MVP框架示例代码,这里做个记录,也顺便和网友们分享一下。

           代码示例演示的是一个输入员工号查询员工信息并显示的场景,查询后的界面如下:

     本文以该场景举例来搭建一个可以通用的MVP架构,代码整体结构如下:

    具体的代码及结构说明:

    mvpbase:所有MVP业务通用的方法

    BaseModel.java

     1 package com.song.mvpdemo.mvpbase.model;
     2 
     3 import java.util.Map;
     4 
     5 /**
     6  * 该类抽象出不同业务获取数据的通用方法
     7  */
     8 public abstract class BaseModel<T> {
     9     //数据请求参数
    10     protected String[] mParams;
    11 
    12     /**
    13      * 设置数据请求参数
    14      *
    15      * @param args 参数数组
    16      */
    17     public BaseModel params(String... args) {
    18         mParams = args;
    19         return this;
    20     }
    21 
    22     /**
    23      * 添加Callback并执行数据请求,具体的数据请求由子类实现
    24      */
    25     public abstract void execute(ModelCallback<T> modelCallback);
    26 
    27     /**
    28      * 执行Get网络请求,此类看需求由自己选择写与不写
    29      */
    30     public void requestGetApi(String url, ModelCallback<T> modelCallback) {
    31         //这里写具体的网络请求
    32     }
    33 
    34     //执行Post网络请求,此类看需求由自己选择写与不写
    35     public void requestPostApi(String url, Map params, ModelCallback<T> modelCallback) {
    36         //这里写具体的网络请求
    37     }
    38 }

    ModelCallback.java

     1 package com.song.mvpdemo.mvpbase.model;
     2 
     3 /**
     4  * Presenter层调用Model层后数据回调
     5  */
     6 public interface ModelCallback<T> {
     7     void onSuccess(T result);
     8 
     9     void onFailOrError();
    10 
    11     void onCompleted();
    12 }

    DataModel.java

     1 package com.song.mvpdemo.mvpbase.model;
     2 
     3 /**
     4  * 该类用于创建具体的业务Model
     5  */
     6 public class DataModel {
     7     public static BaseModel createModel(Class clazz) {
     8         BaseModel model = null;
     9         try {
    10             model = (BaseModel) clazz.newInstance();
    11         } catch (IllegalAccessException e) {
    12             e.printStackTrace();
    13         } catch (InstantiationException e) {
    14             e.printStackTrace();
    15         }
    16         return model;
    17     }
    18 }

    BasePresenter.java

     1 package com.song.mvpdemo.mvpbase.presenter;
     2 
     3 import com.song.mvpdemo.mvpbase.view.IBaseView;
     4 
     5 /**
     6  * 不同业务Presenter层通用的操作
     7  */
     8 public class BasePresenter<V extends IBaseView> {
     9     private V mView;
    10 
    11     public void attachView(V baseView) {
    12         mView = baseView;
    13     }
    14 
    15     public void dettachView() {
    16         mView = null;
    17     }
    18 
    19     public boolean isViewAttached() {
    20         return mView != null;
    21     }
    22 
    23     public V getView() {
    24         return mView;
    25     }
    26 }

    IBaseView.java

    1 package com.song.mvpdemo.mvpbase.view;
    2 
    3 public interface IBaseView {
    4     void showLoading();
    5 
    6     void hideLoading();
    7 
    8     void showFailOrError(String msg);
    9 }

    BaseActivity.java

     1 package com.song.mvpdemo.mvpbase.view;
     2 
     3 import android.app.ProgressDialog;
     4 import android.os.Bundle;
     5 
     6 import androidx.appcompat.app.AppCompatActivity;
     7 
     8 import com.song.mvpdemo.mvpbase.presenter.BasePresenter;
     9 
    10 public abstract class BaseActivity extends AppCompatActivity implements IBaseView {
    11 
    12     private ProgressDialog mProgressDialog;
    13 
    14     @Override
    15     protected void onCreate(Bundle savedInstanceState) {
    16         super.onCreate(savedInstanceState);
    17         initPresenter();
    18         if (getPresenter() != null) {
    19             getPresenter().attachView(this);
    20         }
    21 
    22         mProgressDialog = new ProgressDialog(this);
    23         mProgressDialog.setCancelable(false);
    24         mProgressDialog.setMessage("Loading...");
    25     }
    26 
    27     @Override
    28     public void showLoading() {
    29         if (mProgressDialog != null && !mProgressDialog.isShowing()) {
    30             mProgressDialog.show();
    31         }
    32     }
    33 
    34     @Override
    35     public void hideLoading() {
    36         if (mProgressDialog != null && mProgressDialog.isShowing()) {
    37             mProgressDialog.dismiss();
    38         }
    39     }
    40 
    41     /**
    42      * 初始化Presenter的实例,子类实现
    43      */
    44     protected abstract void initPresenter();
    45 
    46     /**
    47      * 获取Presenter实例,子类实现
    48      */
    49     protected abstract BasePresenter getPresenter();
    50 
    51     @Override
    52     protected void onDestroy() {
    53         super.onDestroy();
    54         if (getPresenter() != null) {
    55             getPresenter().dettachView();
    56         }
    57     }
    58 }

    StaffInfo.java

     1 package com.song.mvpdemo.staffinfo.model;
     2 
     3 public class StaffInfo {
     4     private String staffId;
     5     private String name;
     6     private int age;
     7     private float salary;
     8 
     9     public StaffInfo(String staffId, String name, int age, float salary) {
    10         this.staffId = staffId;
    11         this.name = name;
    12         this.age = age;
    13         this.salary = salary;
    14     }
    15 
    16     public String getStaffId() {
    17         return staffId;
    18     }
    19 
    20     public void setStaffId(String staffId) {
    21         this.staffId = staffId;
    22     }
    23 
    24     public String getName() {
    25         return name;
    26     }
    27 
    28     public void setName(String name) {
    29         this.name = name;
    30     }
    31 
    32     public int getAge() {
    33         return age;
    34     }
    35 
    36     public void setAge(int age) {
    37         this.age = age;
    38     }
    39 
    40     public float getSalary() {
    41         return salary;
    42     }
    43 
    44     public void setSalary(float salary) {
    45         this.salary = salary;
    46     }
    47 
    48     @Override
    49     public String toString() {
    50         return "StaffInfo{" +
    51                 "staffId='" + staffId + '\'' +
    52                 ", name='" + name + '\'' +
    53                 ", age=" + age +
    54                 ", salary=" + salary +
    55                 '}';
    56     }
    57 }

    StaffInfoDataModel.java

     1 package com.song.mvpdemo.staffinfo.model;
     2 
     3 import android.os.Handler;
     4 
     5 import com.song.mvpdemo.mvpbase.model.BaseModel;
     6 import com.song.mvpdemo.mvpbase.model.ModelCallback;
     7 
     8 public class StaffInfoDataModel extends BaseModel<StaffInfo> {
     9 
    10     @Override
    11     public void execute(ModelCallback<StaffInfo> modelCallback) {
    12         new Handler().postDelayed(new Runnable() {
    13             @Override
    14             public void run() {
    15                 switch (mParams[0]) {
    16                     case ""://输入的staffid为空,则显示失败
    17                         modelCallback.onFailOrError();
    18                         break;
    19                     default:
    20                         StaffInfo staffInfo = new StaffInfo(mParams[0], "张三", 20, 20000);
    21                         modelCallback.onSuccess(staffInfo);
    22                         break;
    23                 }
    24                 modelCallback.onCompleted();
    25             }
    26         }, 5000);
    27     }
    28 }

    StaffInfoPresenter.java

     1 package com.song.mvpdemo.staffinfo.presenter;
     2 
     3 import com.song.mvpdemo.mvpbase.presenter.BasePresenter;
     4 import com.song.mvpdemo.mvpbase.model.DataModel;
     5 import com.song.mvpdemo.mvpbase.model.ModelCallback;
     6 import com.song.mvpdemo.staffinfo.model.StaffInfo;
     7 import com.song.mvpdemo.staffinfo.model.StaffInfoDataModel;
     8 import com.song.mvpdemo.staffinfo.view.IStaffInfoView;
     9 
    10 public class StaffInfoPresenter extends BasePresenter<IStaffInfoView> {
    11 
    12     public void queryStaffInfo(String param) {
    13         getView().showLoading();
    14 
    15         DataModel.createModel(StaffInfoDataModel.class)
    16                 .params(param)
    17                 .execute(new ModelCallback<StaffInfo>() {
    18                     @Override
    19                     public void onSuccess(StaffInfo result) {
    20                         if (isViewAttached()) {
    21                             getView().showStaffInfo(result);
    22                         }
    23                     }
    24 
    25                     @Override
    26                     public void onFailOrError() {
    27                         if (isViewAttached()) {
    28                             getView().showFailOrError("fail");
    29                         }
    30                     }
    31 
    32                     @Override
    33                     public void onCompleted() {
    34                         if (isViewAttached()) {
    35                             getView().hideLoading();
    36                         }
    37                     }
    38                 });
    39     }
    40 }

    IStaffInfoView.java

     1 package com.song.mvpdemo.staffinfo.view;
     2 
     3 import com.song.mvpdemo.mvpbase.view.IBaseView;
     4 import com.song.mvpdemo.staffinfo.model.StaffInfo;
     5 
     6 public interface IStaffInfoView extends IBaseView {
     7     /**
     8      * 具体业务特有的方法,无法做为通用的方法提取出来
     9      */
    10     String getStaffId();
    11 
    12     void showStaffInfo(StaffInfo staffInfo);
    13 
    14     void clearStaffId();
    15 }

    StaffInfoActivity.java

     1 package com.song.mvpdemo.staffinfo.view;
     2 
     3 import android.os.Bundle;
     4 import android.view.View;
     5 import android.widget.EditText;
     6 import android.widget.TextView;
     7 
     8 import com.song.mvpdemo.mvpbase.view.BaseActivity;
     9 import com.song.mvpdemo.mvpbase.presenter.BasePresenter;
    10 import com.song.mvpdemo.R;
    11 import com.song.mvpdemo.staffinfo.presenter.StaffInfoPresenter;
    12 import com.song.mvpdemo.staffinfo.model.StaffInfo;
    13 
    14 public class StaffInfoActivity extends BaseActivity implements IStaffInfoView {
    15     private TextView mStaffInfoTv;
    16     private EditText mStaffIdEt;
    17     private StaffInfoPresenter mStaffInfoPresenter;
    18 
    19     @Override
    20     protected void onCreate(Bundle savedInstanceState) {
    21         super.onCreate(savedInstanceState);
    22         setContentView(R.layout.activity_staffinfo);
    23         initView();
    24     }
    25 
    26     private void initView() {
    27         mStaffInfoTv = findViewById(R.id.tv_result);
    28         mStaffIdEt = findViewById(R.id.staffId_et);
    29         findViewById(R.id.btn_submit).setOnClickListener(new View.OnClickListener() {
    30             @Override
    31             public void onClick(View view) {
    32                 mStaffInfoPresenter.queryStaffInfo(getStaffId());
    33             }
    34         });
    35 
    36         findViewById(R.id.btn_clear).setOnClickListener(new View.OnClickListener() {
    37             @Override
    38             public void onClick(View view) {
    39                 clearStaffId();
    40             }
    41         });
    42     }
    43 
    44 
    45     @Override
    46     protected void initPresenter() {
    47         mStaffInfoPresenter = new StaffInfoPresenter();
    48     }
    49 
    50     @Override
    51     protected BasePresenter getPresenter() {
    52         return mStaffInfoPresenter;
    53     }
    54 
    55     @Override
    56     public void showFailOrError(String msg) {
    57         mStaffInfoTv.setText(msg);
    58     }
    59 
    60     @Override
    61     public String getStaffId() {
    62         return mStaffIdEt.getText().toString();
    63     }
    64 
    65     @Override
    66     public void showStaffInfo(StaffInfo staffInfo) {
    67         mStaffInfoTv.setText(staffInfo.toString());
    68     }
    69 
    70     @Override
    71     public void clearStaffId() {
    72         mStaffIdEt.setText("");
    73     }
    74 }

    activity_staffinfo.xml

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     xmlns:app="http://schemas.android.com/apk/res-auto"
     4     xmlns:tools="http://schemas.android.com/tools"
     5     android:layout_width="match_parent"
     6     android:layout_height="match_parent"
     7     tools:context=".staffinfo.view.StaffInfoActivity">
     8 
     9     <TextView
    10         android:id="@+id/tv_result"
    11         android:layout_width="wrap_content"
    12         android:layout_height="wrap_content"
    13         android:layout_marginTop="50dp"
    14         android:text=""
    15         app:layout_constraintLeft_toLeftOf="parent"
    16         app:layout_constraintRight_toRightOf="parent"
    17         app:layout_constraintTop_toTopOf="parent" />
    18 
    19     <EditText
    20         android:id="@+id/staffId_et"
    21         android:layout_width="200dp"
    22         android:layout_height="wrap_content"
    23         android:layout_marginTop="20dp"
    24         android:hint="input staff id"
    25         app:layout_constraintLeft_toLeftOf="parent"
    26         app:layout_constraintRight_toRightOf="parent"
    27         app:layout_constraintTop_toBottomOf="@id/tv_result" />
    28 
    29 
    30     <Button
    31         android:id="@+id/btn_submit"
    32         android:layout_width="200dp"
    33         android:layout_height="wrap_content"
    34         android:layout_marginTop="50dp"
    35         android:text="submit"
    36         app:layout_constraintLeft_toLeftOf="parent"
    37         app:layout_constraintRight_toRightOf="parent"
    38         app:layout_constraintTop_toBottomOf="@id/staffId_et" />
    39 
    40     <Button
    41         android:id="@+id/btn_clear"
    42         android:layout_width="200dp"
    43         android:layout_height="wrap_content"
    44         android:text="clear"
    45         app:layout_constraintLeft_toLeftOf="parent"
    46         app:layout_constraintRight_toRightOf="parent"
    47         app:layout_constraintTop_toBottomOf="@id/btn_submit" />
    48 
    49 </androidx.constraintlayout.widget.ConstraintLayout>

    参考:

    Android MVP升级路(一)乞丐版的自我救赎

    Android MVP升级路(二)轻项目标配之时尚版

    Android MVP升级路(三)随心所欲的旗舰版

    浅谈 MVP in Android

     
     
     
  • 相关阅读:
    codeforces 459 C. Pashmak and Buses(思维)
    poj 2763 Housewife Wind(树链剖分+单点查询+区间修改)
    codeforces E. Phone Talks(dp)
    BZOJ 1036: [ZJOI2008]树的统计Count(树链剖分+单点更新+区间求和+区间求最大值)
    SPOJ
    hdu 3966 Aragorn's Story(树链剖分+区间修改+单点查询)
    codeforces H. Queries for Number of Palindromes(区间dp)
    codeforces 245 D. Restoring Table(位运算+思维)
    codeforces 402 D. Upgrading Array(数论+贪心)
    codeforces 793 D. Presents in Bankopolis(记忆化搜索)
  • 原文地址:https://www.cnblogs.com/andy-songwei/p/15592245.html
Copyright © 2020-2023  润新知