Android设计模式之 MVP和泛型结合
来源:互联网 发布:mac发布会时间 编辑:程序博客网 时间:2024/04/19 04:50
什么是MVP?
MVP设计模式有大量的的博客去讲解,我今天还是要讲讲什么是MVP模式因为想让自己有个更加深刻理解,再加上自己最近看了项目发现和Java中的泛型结合可以让整个MVP模式代码更加优雅和简洁,好了现在说正题了MVP.
M:数据提供层:Model 一般由请求网络类或者数据库等组成。
V :数据展示层:View activity,fragment组成
P:业务逻辑层:Presenter 处理Model View之间逻辑代码组成
MVP关系图:
上面的图已经很好说明Model View Presenter 三者之间的关系我就不都说了
讲讲T-MVP肯定要用举例子才更好理解它,那我就用登录这个功能来讲讲MVP模式吧!
目录结构
我们来看下基类包中
首先baseModel接口
可以看到并没有任何代码 由于这个小项目所以一部涉及 Model 抽取
BasePresenter类
public abstract class BasePresenter <V,M>{ public V mView; public M mModel; public void setVM(V view,M modle){ this.mView=view; this.mModel=modle; }}
BaseView接口
public interface BaseView { //请求开始调用 void RequstStart(); //请求结束调用 void ReqeustEnd(); //网络错误的方法 void onInternetError(); //请求错误的方法 void ReqeustError();}
看完MVP基类 , 发现在Presenter 会有二元组泛型 这个就是泛型和MVP结合精华所在,
现在再看BaseActivity
public abstract class BaseActivity<P extends BasePresenter,M extends BaseModel > extends AppCompatActivity implements BaseView { public P mPresenter; public M mBaseModel; public Activity mActivity; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(getContentView()); System.out.println("BaseActivity.onCreate"); mPresenter= CommUtils.getT(this,0); mBaseModel=CommUtils.getT(this,1); if(this instanceof BaseView){ mPresenter.setVM(this,mBaseModel); } mActivity=this; init(); initView(); initData(); } /** * 初始化变量 */ public abstract void init(); /** * 初始化控件 */ public abstract void initView(); /** * 初始化数据 */ public abstract void initData(); /** * 获得activity布局文件 * @return */ public abstract int getContentView();}
介绍完基类就来看 具体实现吧
/** * Created by Administrator on 2016/12/14. * 管理登录接口类 作用:统一管理,减少类在包中 */public interface LoginContract { interface View extends BaseView{ String getUserName(EditText editText); String getPassWorld(EditText editText); } interface Model extends BaseModel{ void login(String userName,String passWorld,LoginListener listener); } abstract class Presenter extends BasePresenter<View, Model>{ public abstract void login(Context context,String userName,String passWorld ,LoginListener listener); } interface LoginListener{ void loginSuccess(); void loginFail(); }}
loginModel 具体实现类
/** * Created by Administrator on 2016/12/14. * 数据提供层 */public class LoginModel implements LoginContract.Model{ private Handler mHandler=new Handler(Looper.getMainLooper()); @Override public void login(final String userName,final String passWorld, final LoginContract.LoginListener listener) { /** * 模拟网路请求 */ new Thread(){ @Override public void run() { if(userName.equals("jack")&&passWorld.equals("123456")){ System.out.println("登录成功"); } try { Thread.sleep(1*1000); //回调到主线程中 mHandler.post(new Runnable() { @Override public void run() { listener.loginSuccess(); } }); } catch (InterruptedException e) { e.printStackTrace(); mHandler.post(new Runnable() { @Override public void run() { listener.loginFail(); } }); } } }.start(); }}
LoginPresenter
/** * Created by Administrator on 2016/12/14. * 业务逻辑控制层 */public class LoginPresenter extends LoginContract.Presenter { @Override public void login(Context context, String userName, String passWorld ,LoginContract.LoginListener loginListener) { mView.RequstStart(); mModel.login(userName,passWorld,loginListener); }}
LoginActivity
public class LoginActivity extends BaseActivity<LoginPresenter,LoginModel> implements LoginContract.View{ EditText mEtUserName; EditText mEtPassWorld; Button mBtnLogin; private AlertDialog.Builder mBuilder; private AlertDialog mDialog; @Override public void init() { mBuilder = new android.support.v7.app.AlertDialog.Builder(this); mBuilder.setTitle("登录"); mBuilder.setMessage("正在登录 请稍等"); } @Override public void initView() { mBtnLogin= (Button) this.findViewById(R.id.btn_login); mEtUserName= (EditText) this.findViewById(R.id.et_userName); mEtPassWorld= (EditText) this.findViewById(R.id.et_passWorld); } @Override public void initData() { mBtnLogin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { String userName=getUserName(mEtUserName); String passWorld=getPassWorld(mEtPassWorld); if (userName==null||userName.equals("")){ Toast.makeText(mActivity,"用户名为空,请填写",Toast.LENGTH_SHORT).show(); return; } if (passWorld==null||passWorld.equals("")){ Toast.makeText(mActivity,"密码为空,请填写!",Toast.LENGTH_SHORT).show(); return; } mPresenter.login(mActivity, userName, passWorld, new LoginContract.LoginListener() { @Override public void loginSuccess() { Toast.makeText(mActivity,"登录成功了",Toast.LENGTH_SHORT).show(); ReqeustEnd(); } @Override public void loginFail() { Toast.makeText(mActivity,"登录失败",Toast.LENGTH_SHORT).show(); ReqeustEnd(); } }); } }); } @Override public void RequstStart() { mDialog= mBuilder.show(); } @Override public void ReqeustEnd() { mDialog.dismiss(); } @Override public void onInternetError() { } @Override public void ReqeustError() { } @Override public int getContentView() { return R.layout.activity_main; } @Override public String getUserName(EditText editText) { String userName=null; if(editText!=null){ userName= editText.getText().toString().trim(); } return userName; } @Override public String getPassWorld(EditText editText) { String passWorld =null; if(editText!=null){ passWorld= editText.getText().toString().trim(); } return passWorld; }}
CommUtils
public class CommUtils { public static <T> T getT(Object o, int i) { try { return ((Class<T>) ((ParameterizedType) (o.getClass() .getGenericSuperclass())).getActualTypeArguments()[i]) .newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassCastException e) { e.printStackTrace(); } return null; }}
最后把布局文件代码贴下
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.jack.test.LoginActivity"><TextView android:layout_width="match_parent" android:text="用户名:" android:layout_height="wrap_content" /> <EditText android:id="@+id/et_userName" android:layout_width="match_parent" android:hint="请输入用户名" android:layout_height="wrap_content" /> <TextView android:layout_width="match_parent" android:text="密 码:" android:layout_height="wrap_content" /> <EditText android:id="@+id/et_passWorld" android:layout_width="match_parent" android:hint="请输入你密码" android:password="true" android:inputType="textPassword" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_login" android:text="登录" android:textSize="16sp" android:layout_width="match_parent" android:layout_height="wrap_content" /></LinearLayout>
项目运行图
讲解的不多 相信大家看代码就会懂 如果还要什么错误或者很好的建议请留言
0 0
- Android设计模式之 MVP和泛型结合
- Android之mvp设计模式
- Android之MVP设计模式
- Android设计模式之MVP
- Android之MVP设计模式
- Android设计模式之MVP
- Android设计模式之MVP
- Android设计模式之MVP
- 浅谈Android MVP设计模式(简单结合RxJava+Retrofit)
- Android Mvp设计模式结合RxJava+OkHttp+retrofit浅谈
- Android设计模式之浅谈MVP
- android设计模式之mvp详解
- Android设计模式之浅谈MVP
- Android设计模式之浅谈MVP
- Android设计模式之浅谈MVP
- Android设计模式之浅谈MVP
- Android设计模式之浅谈MVP
- android之MVP设计模式详解
- CentOS 7使用Docker出现x509: certificate signed by unknown authority的解决
- USACO training训练题解【1】
- Java 位运算
- Ajax+JSP+JSON的实例
- 一些有用的网站
- Android设计模式之 MVP和泛型结合
- 用Dockerfile构建java web环境
- 线程相关
- 电视剧里的小角色以及我生活里的那些人001
- TextView 下划线
- c语言
- 《JavaScript高级程序设计》读书笔记--6-面向对象的程序设计
- 计算该日是本年的第几天
- 哈佛大学公开课《死亡》