PHP小丑 发表于 2021-11-23 11:36:29

【架构】整理了一份通用的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) {
16                     case ""://输入的staffid为空,则显示失败
17                         modelCallback.onFailOrError();
18                         break;
19                     default:
20                         StaffInfo staffInfo = new StaffInfo(mParams, "张三", 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

https://www.cnblogs.com/andy-songwei/p/15592245.html
页: [1]
查看完整版本: 【架构】整理了一份通用的MVP框架示例代码