MVP框架理解(登录界面MVC和MVP抽取对比)

1,MVP架构模式

  • 概念解释

    • MVP是Model(数据) View(界面) Presenter(表现层)的缩写,它是MVC架构的变种,强调Model和View的最大化解耦和单一职责原则

    • Model:负责数据的来源和封装,比如网络请求类,数据库操作类以及java bean,如果有必要则提供接口暴露自己处理数据的状态和进度。

    • View:负责UI相关,如布局UI的初始化,各种listener的设置。在Android中,我们通常写的Activity和Fragment就是属于View层;在web开发中,html则是View层。

    • Controller:业务逻辑控制器,主要负责当获取到数据后对数据进行逻辑处理,然后将数据绑定到View上;比如:请求一个url,从网络获取到数据,进行解析javabean,然后各种set数据。对于控制器的概念大家很好理解,因为我们每天都在这样做,在Activity中请求数据然后更新UI。但是结合View的概念来看,很显然Activity和Fragment不但承担了View的任务,还负责完成的Controller的功能,随着业务功能的增多,Activity的代码越来越难以阅读和维护,这就是在Android中使用MVC的弊端,为了解决MVC模式下View层的臃肿,MVP模式应运而生。

    • Presenter:专门从C独立出来的业务逻辑层,主要负责处理原先View层的业务逻辑,解决了Activity的臃肿问题,让Activity只负责处理UI,职责更加明确;并且将View层的业务逻辑抽取到P层之后,View层与Model层也实现了解耦;便于后期代码的扩展和维护,并且业务逻辑层独立后代码还得到很大的重用性

    • 总结:MVC模式下,V和C纠缠不清,并且View和Model相互关联,而

      • MVP模式下Model和VIew解耦,便于单元测试,项目维护,代码重用,优点:解耦性强,缺点多了很多接口类

 

    MVVM(了解):叫布局文件和javabean 关联,当修改布局文件时同时会修改 javabean 中的内容。 android端十分麻烦。

 

<item   申明user/>

<TextView

    android.id = "{user.name}"  

 

 

2, MAC模式创建登录界面

【1】创建布局

<?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"

    android:gravity="center_horizontal"

    android:padding="30dp"

    tools:context="com.itheima96.mvpdemo.view.LoginActivity">





    <EditText

        android:layout_marginTop="30dp"

        android:id="@+id/et_user"

        android:hint="请输入用户名"

        android:layout_width="match_parent"

        android:layout_height="wrap_content" />





    <EditText

        android:layout_marginTop="30dp"

        android:id="@+id/et_psw"

        android:hint="请输入密码"

        android:layout_width="match_parent"

        android:layout_height="wrap_content" />





    <Button

        android:id="@+id/btn_login"

        android:text="登录"

        android:layout_marginTop="30dp"

        android:textSize="20sp"

        android:textColor="#000"

        android:layout_width="match_parent"

        android:layout_height="wrap_content" />

</LinearLayout>

【2】Activity 实现登录,并且对登录页面进行登录模拟

  • 模拟请求网络

public class HttpHelper {

    private static HttpHelper mInstance = new HttpHelper();

    private HttpHelper() {

    }

    public static HttpHelper create(){

        return mInstance;

    }

    public void execGet(String url, HttpCallback callback) {

        //真正的请求网络操作

    }

    public void execPost(String url, HttpCallback callback) {

    }

    public interface HttpCallback {

        void onSuccess(String data);

        void onFail(Exception e);

    }

}
  • 登录页面处理

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.et_user)

    EditText etUser;

    @BindView(R.id.et_psw)

    EditText etPsw;

    @BindView(R.id.btn_login)

    Button btnLogin;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        ButterKnife.bind(this);

    }



    //点击进行登录

    @OnClick(R.id.btn_login)

    public void onViewClicked() {

        //1,获取用户和密码

        String user = etUser.getText().toString();

        String psw = etPsw.getText().toString();

        if (checkInput(user, psw)) {

            HttpHelper.create().execGet("url", new HttpHelper.HttpCallback() {

                @Override

                public void onSuccess(String data) {

                    saveUserData();

                    gotoMain();

                }

                @Override

                public void onFail(Exception e) {

                }

            });

        }

    }





    /**

     * 跳转页面

     */

    private void gotoMain() {

        //跳转页面

    }





    /**

     * 保存登录信息

     */

    private void saveUserData() {

        //保存登录信息

    }





    /**

     * 对用户名密码进行操作

     * @param user

     * @param psw

     * @return

     */

    private boolean checkInput(String user, String psw) {

        //1,判断是否为空

        if (TextUtils.isEmpty(user) || TextUtils.isEmpty(psw)) {

            showNotNull();

            return false;

        }

        //2,判断长度是否正确

        if (user.length() != 11) {

            showLengthError();

            return false;

        }





        return true;

    }

    /**

     *   显示登录失败

     */





    public void showLoginFail() {

        Toast.makeText(this, "登录失败,请检查网络", Toast.LENGTH_SHORT).show();

    }

    

    /**

     *  显示用户名长度不正确

     */

   

    public void showLengthError() {

        Toast.makeText(this, "用户名长度不正确!", Toast.LENGTH_SHORT).show();

    }





    /**

     *  显示用户名和密码不能为空

     */

   

    public void showNotNull() {

        Toast.makeText(this, "用户名或密码不能为空!", Toast.LENGTH_SHORT).show();

    }





}

3,MVP模式创建登录界面

【1】项目分包

view       activity  fragment

model       bean     helper

presenter    

【2】BasePresenter 处理Activity的生命周期

  • 创建BasePresenter 里面为对应的Activity提供调用方法

public class BasePresenter {

    public void onViewResume(){

    }

    public void onViewPause(){

    }

    public void onViewStart(){

        //重新开始轮询

    }

    public void onViewStop(){

        //做一些停止ViewPgaer轮询的操作

    }

    /**

     * 当View层被销毁的时候做一些释放操作

     */

    public void onViewDestory(){

        //比如取消网络请求

    }

}

BaseActivity中当生命周期被执行时,调用BasePresenter中对应要实现的方法

public class BaseActivity extends AppCompatActivity {

    BasePresenter presenter;

    @Override

    protected void onResume() {

        super.onResume();

        presenter.onViewResume();

    }

    @Override

    protected void onPause() {

        super.onPause();

        presenter.onViewPause();

    }

    @Override

    protected void onStart() {

        super.onStart();

        presenter.onViewStart();

    }

    @Override

    protected void onStop() {

        super.onStop();

        presenter.onViewStop();

    }

    @Override

    protected void onDestroy() {

        super.onDestroy();

        //取消网络请求

        presenter.onViewDestory();

    }

}

【3】创建登录界面的业务层。

  • LoginPresenter指定的view层的接口需求,

public interface ILoginView  {

    void showLoginFail();

    void showNotNull();

    void showLengthError();

}
  • 登录逻辑的封装抽取类

public class LoginPresenter extends BasePresenter{

    private ILoginView loginView;

    public LoginPresenter(ILoginView loginView){

        this.loginView = loginView;

    }

    /**

     * 登录的方法

     * @param user

     * @param psw

     */

    public void login(String user,String psw){

        //2.检查输入是否合法

        if(checkInput(user,psw)){

            //3.执行登录请求

            HttpHelper.create().execPost("url", new HttpHelper.HttpCallback() {

                @Override

                public void onSuccess(String data) {

                    //保存登录数据

                    saveUserData();

                    //跳转界面

                    gotoMain();

                }

                @Override

                public void onFail(Exception e) {

                    loginView.showLoginFail();

                }

            });

        }

    }

    //跳转主界面

    private void gotoMain() {

    }

    //保存用户登录数据

    private void saveUserData() {

    }

    //检查输入的

    private boolean checkInput(String user, String psw) {

        //1.判断是否为空

        if(TextUtils.isEmpty(user) || TextUtils.isEmpty(psw)){

            loginView.showNotNull();

            return false;

        }

        //2.判断长度是否正确

        if(user.length()!=11){

            loginView.showLengthError();

            return false;

        }

        return true;

    }

}

【4】LoginActivity 实现ILoginView 接口  重写对应的UI显示状态。

public class LoginActivity extends BaseActivity implements ILoginView{

    @Bind(R.id.et_user)

    EditText etUser;

    @Bind(R.id.et_psw)

    EditText etPsw;

    @Bind(R.id.btn_login)

    Button btnLogin;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        ButterKnife.bind(this);





        presenter = new LoginPresenter(this);

    }

    @OnClick(R.id.btn_login)

    public void onClick() {

        //1.获取用户和密码

        String user = etUser.getText().toString();

        String psw = etPsw.getText().toString();

        //2.调用loginPresenter进行登录

        ((LoginPresenter)presenter).login(user,psw);

    }

    //显示登录失败

    public void showLoginFail() {

        Toast.makeText(this, "登录失败,请检查网络", Toast.LENGTH_SHORT).show();

    }

    //显示用户名长度不正确

    public void showLengthError() {

        Toast.makeText(this, "用户名长度不正确!", Toast.LENGTH_SHORT).show();

    }

    //显示用户名和密码不能为空

    public void showNotNull() {

        Toast.makeText(this, "用户名或密码不能为空!", Toast.LENGTH_SHORT).show();

    }

}





 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兴帅_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值