热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

安卓/androidMVP开发模式的理解,以及代码讲解

安卓androidMVP开发模式的理解,以及代码讲解,Go语言社区,Golang程序员人脉社

MVP开发模式的理解,以及简单代码讲解

最近在网上看的MVP文章,根据自己的理解,特在此发篇文章记录下,这里我采用的是反向流程,文章如有需要优化之处,欢迎指导。也可加群进行讨论:855207609
在这里插入图片描述
在此啰嗦一句,首先看图,拿登录功能打比方说:
1、在View中调用P层(带输入数据)进行加载数据(此时还没请求接口)
2、在P中创建View和Model对象(此时的model层还没有创建,可以先省略)然后创建有参构造方法(View)
3、Model请求完接口后,将数据通过回调接口返回到P层,P在返回给VIew进行显示

项目结构图

在这里插入图片描述

  • MVP理解
    1.Model层:处理业务逻辑数据,如加载网络数据等(方法以及接口)
    2.View层:当P和V层执行完数据加载后进行回调给主线程进行显示(纯接口)
    3.Presenter层:是M和V的桥梁,是去小树林的必经之路。将View传递的请求数据传递给Model进行使用,当M请求完接口后,通过回调接口返回给P,此时P层通过已实例化的View将数据射入显示回调方法中进行UI显示。
View层

这里我把弹框抽离出来—使之公用;当然你也可以写在对应View层
作用:在主线程中进行implement此两个View用于最后的数据回调显示

public interface DialogView {
    /**
     * 显示弹框
     * @param message
     */
    void showDialog(String message);
    /**
     * 关闭弹框
     */
    void dismissDialog();
}

public interface LoginView {
    /**
     * 回调数据
     * @param result
     */
    void showData(String result);

//    /**
//     * 显示弹框
//     * @param message
//     */
//    void showDialog(String message);
//    /**
//     * 关闭弹框
//     */
//    void dismissDialog();
}
View层-Activity主线程调用:

首先实现View回调方法,然后调用P层方法,此时P层还没有创建

public class Login extends AppCompatActivity implements DialogView, LoginView {

    @BindView(R.id.et_Log_UserName)
    AutoCompleteTextView etLogUserName;
    @BindView(R.id.et_Log_PassWord)
    EditText etLogPassWord;
    @BindView(R.id.bt_Loading)
    Button btLoading;
    @BindView(R.id.email_login_form)
    LinearLayout emailLoginForm;
    private ProgressDialog mProgressDialog;

    private Handler mHandler;
    private Context mContext;
    private LoginPresenter loginPresenter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ButterKnife.bind(this);
        init();
        MyClick();

    }
    private void init(){
        mContext=Login.this;
        if (loginPresenter==null){
            loginPresenter=new LoginPresenter(this,this);
        }
        mHandler=new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what){
                    case 1:
                        Intent intent=new Intent(Login.this,Menu.class);
                        intent.putExtra("result",msg.obj.toString());
                        startActivityForResult(intent,1);
                        break;
                    default:
                            break;
                }
            }
        };

    }
    private void MyClick(){
        btLoading.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                loginPresenter.reqLogin("test","123");
            }
        });
    }


    @Override
    public void showData(String result) {
//        Looper.prepare();
//        Toast.makeText(mContext, result+"", Toast.LENGTH_SHORT).show();
//        Looper.loop();
        Message msg=new Message();
        msg.what=1;
        msg.obj=result;
        mHandler.sendMessage(msg);

    }

    @Override
    public void showDialog(String message) {
        if (mProgressDialog==null){
            mProgressDialog=new ProgressDialog(Login.this);
        }
        mProgressDialog.setMessage(message);
        mProgressDialog.show();
    }

    @Override
    public void dismissDialog() {
        mProgressDialog.dismiss();
    }

}

Presenter层:

首先implement《P层》以及LoginModel对象等(此时还没有创建,所以我们要先去创建接口,然后在此实现其方法)》

public class LoginPresenter implements LoginIPresenter{
    private DialogView mDialog;
    private LoginView mLoginView;
    private LoginModel loginModel;
    public LoginPresenter(DialogView mDialog,LoginView mLoginView){
        this.mDialog=mDialog;
        this.mLoginView=mLoginView;
        if (loginModel==null){
            loginModel=new LoginModel();
        }
    }

//此处省略一些代码,内容请往下看
}


public interface LoginIPresenter {
    void reqLogin(String userName,String passWord);
}
Model层:

reqLogin方法中的LoginModel.LoginCallBack参数,可以先写上。此处是用于当请求完接口时直接回调给P层(如果有疑问,可以往下看,到P层可以看到请求方法中实现了一个 回调参数)

public interface LoginMode {
    void reqLogin(String userName, String passWord, LoginModel.LoginCallBack callBack);
}
Model层:

此时reqLogin方法中的参数添加了成功或失败回调接口,然后整体看一下是不是感觉,就像以前写在activity中的请求方法

public class LoginModel implements LoginMode{
    public LoginView loginView;
    @Override
    public void reqLogin(String userName, String passWord, final LoginCallBack callBack) {
        new Thread(){
            @Override
            public void run() {
                super.run();
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int code=0;
                //请求接口
                //并返回数据,然后返回给view
                if (code==0){
                    callBack.onSuccess("登录成功");
                }else {
                    callBack.onError("登录失败,用户名或密码错误");
                }
            }
        }.start();
    }
	//这里的接口可以单独抽离出来,这里我就不抽离了
    public interface LoginCallBack{
        void onSuccess(String result);
        void onError(String error);
    }
}

Presenter层:

当P接口和M层创建完成后,创建弹框DialogView,登录LoginView,和登录LoginModel对象,然后创建有参构造并实例化View和Model并实例化,实现其方法

public class LoginPresenter implements LoginIPresenter{
    private DialogView mDialog;
    private LoginView mLoginView;
    private LoginModel loginModel;
    public LoginPresenter(DialogView mDialog,LoginView mLoginView){
        this.mDialog=mDialog;
        this.mLoginView=mLoginView;
        if (loginModel==null){
            loginModel=new LoginModel();
        }
    }

    @Override
    public void reqLogin(String userName, String passWord) {
        mDialog.showDialog("正在登陆中...");
        loginModel.reqLogin(userName, passWord, new LoginModel.LoginCallBack() {
            /**
             * 成功回调数据
             * @param result
             */
            @Override
            public void onSuccess(String result) {
                mDialog.dismissDialog();
                mLoginView.showData(result);
            }

            //失败回调原因
            @Override
            public void onError(String error) {
                mDialog.dismissDialog();
                mLoginView.showData(error);
            }
        });
    }
}

推荐文章:https://blog.csdn.net/limonzet/article/details/53328315
源码Git___Demo------>>>>>>diudiudiu


推荐阅读
  • iOS Swift中如何实现自动登录?
    本文介绍了在iOS Swift中如何实现自动登录的方法,包括使用故事板、SWRevealViewController等技术,以及解决用户注销后重新登录自动跳转到主页的问题。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 十大经典排序算法动图演示+Python实现
    本文介绍了十大经典排序算法的原理、演示和Python实现。排序算法分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。文章还解释了时间复杂度和稳定性的概念,并提供了相关的名词解释。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • 标题: ... [详细]
  • 深入理解CSS中的margin属性及其应用场景
    本文主要介绍了CSS中的margin属性及其应用场景,包括垂直外边距合并、padding的使用时机、行内替换元素与费替换元素的区别、margin的基线、盒子的物理大小、显示大小、逻辑大小等知识点。通过深入理解这些概念,读者可以更好地掌握margin的用法和原理。同时,文中提供了一些相关的文档和规范供读者参考。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • Android日历提醒软件开源项目分享及使用教程
    本文介绍了一款名为Android日历提醒软件的开源项目,作者分享了该项目的代码和使用教程,并提供了GitHub项目地址。文章详细介绍了该软件的主界面风格、日程信息的分类查看功能,以及添加日程提醒和查看详情的界面。同时,作者还提醒了读者在使用过程中可能遇到的Android6.0权限问题,并提供了解决方法。 ... [详细]
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
author-avatar
chunhuai
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有