Android之MVP框架模式

基本步骤

一.在Application类中定义一个全局的OkHttp对象用于访问网络数据,并将该Application在配置文件中声明。

二.构造Model层,比如说用户登录表UserInfo,定义相关字段并添加get/set方法。

三.构造Net层,该层主要负责访问并加载网络数据,设置访问回调接口。

四.构造Presener,将网络数据和view视图联系起来!

五.实现View层,将数据绑定到视图上!

六.将通用的方法抽成工具类Utils

简单代码示例如下:



1.MvpApplication.java

package com.example.yang.mvp;

import android.app.Application;

import cn.finalteam.okhttpfinal.OkHttpFinal;
import cn.finalteam.okhttpfinal.OkHttpFinalConfiguration;


public class MvpApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        //在application中获得全局的okhttp对象
        OkHttpFinalConfiguration.Builder builder=new OkHttpFinalConfiguration.Builder();
        OkHttpFinal.getInstance().init(builder.build());

    }
}

2.IpInfo.java

package com.example.yang.mvp.model;

public class IpInfo {
    private int code;
    private IpData ipData;

    public int getCode() {
        return code;
    }

    public IpData getIpData() {
        return ipData;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public void setIpData(IpData ipData) {
        this.ipData = ipData;
    }
}

3.IpData.java

package com.example.yang.mvp.model;

public class IpData {
    private String country;
    private String city;
    private String area;
    public String getCity() {
        return city;
    }

    public String getCountry() {
        return country;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public void setArea(String area) {
        this.area = area;
    }

    public String getArea() {
        return area;
    }
}



4.NetTask.java(总网络访问接口)

package com.example.yang.mvp.net;

import com.example.yang.mvp.LoadTasksCallback;
public interface NetTask<T> {
    void execute(T data, LoadTasksCallback callBack);
}

5.LoadTasksCallBack.java(回调监听接口)

package com.example.yang.mvp;

public interface LoadTasksCallback<T> {
    void onSuccess(T t);
    void onStart();
    void onFailed();
    void onFinish();
}

6.IpInfoTask.java(NetTask实现类获取IpInfo数据)

package com.example.yang.mvp.net;
import com.example.yang.mvp.LoadTasksCallback;
import com.example.yang.mvp.model.IpInfo;
import cn.finalteam.okhttpfinal.BaseHttpRequestCallback;
import cn.finalteam.okhttpfinal.HttpRequest;
import cn.finalteam.okhttpfinal.RequestParams;

public class IpInfoTask implements NetTask<String> {
    private static IpInfoTask INSTANCE=null;
    private static final String HOST="xxxx数据所在地址";
    //实现NetTask以获取数据,IpInfoTask是一个单例类,在execute方法中通过OkHttpFinial来获取数据
    //同时在OkhttpFinal的回调函数中调用自己定义的回调函数。

    public IpInfoTask(){

    }
    public static IpInfoTask getInstance() {
        if(INSTANCE==null){
            INSTANCE=new IpInfoTask();
        }
        return INSTANCE;
    }

    @Override
    public void execute(String ip, final LoadTasksCallback callBack) {
        RequestParams params=new RequestParams();
        params.addFormDataPart("ip",ip);
        System.out.println(ip);
        //接口回调,当我们取得数据开始失败成功结束该做些什么
        HttpRequest.post(HOST,params,new BaseHttpRequestCallback<IpInfo>(){
            @Override
            public void onStart() {
                super.onStart();
                callBack.onStart();
            }

            @Override
            protected void onSuccess(IpInfo ipInfo) {
                super.onSuccess(ipInfo);
                callBack.onSuccess(ipInfo);
            }

            @Override
            public void onFailure(int errorCode, String msg) {
                super.onFailure(errorCode, msg);
                callBack.onFailed();
            }

            @Override
            public void onFinish() {
                super.onFinish();
                callBack.onFinish();
            }
        });
    }
}

7.IpInfoContract.java

主要作用:用来存放相同业务的presener和view的接口,便于查找和维护,简言之,将处理同一业务的数据和view的接口存放在这里,便于实现。
package com.example.yang.mvp.ipinfo;

import com.example.yang.mvp.BaseView;
import com.example.yang.mvp.model.IpInfo;

public interface IpInfoContract {
    //首先定义一个契约接口,契约接口主要用来存放相同业务的presener和view的接口,便于查找和维护
    //定义了获取数据的方法,再view中定义了与界面交互的方法,isActive()方法用于判断Fragment是否
    //添加到Activity中,另外View继承自BaseView
    interface Presenter{
        void getIpInfo(String ip);
    }
//先要实现setPresener()方法
    interface View extends BaseView<Presenter> {
        void setIpInfo(IpInfo ipInfo);
        void showLoading();
        void hideLoading();
        void showError();
        boolean isActive();
    }
}

8.BaseView.java

主要作用:给view绑定Presener,并实现Presener接口
package com.example.yang.mvp;

public interface BaseView<T> {
    //该接口的目的是给view绑定数presener
    void setPresenter(T presenter);
}

9.IpInfoPresener.java

package com.example.yang.mvp.ipinfo;

import com.example.yang.mvp.LoadTasksCallback;
import com.example.yang.mvp.model.IpInfo;
import com.example.yang.mvp.net.NetTask;

public class IpInfoPresener implements IpInfoContract.Presenter,LoadTasksCallback<IpInfo> {
    //IpInfoPresener中含有NetTask和IpInfoContract.View的实例,并且实现了LoadTasksCallBack接口
    //在代码1处将自身传入NetTask的execute方法来获取数据,并回调给IpInfoPresener,最后通过addTaskView与view
    //进行交互,并更改界面。
    //presener就是一个中间人的角色,通过NetTask,也就是Model层获得和保存数据,然后通过view更新界面,这期间
    //通过定义接口使得View和Model没有任何得交互
    private NetTask netTask;
    private IpInfoContract.View addview;
    public IpInfoPresener(NetTask netTask,IpInfoContract.View addview){
        this.netTask=netTask;
        this.addview=addview;

    }
    @Override
    public void onSuccess(IpInfo ipInfo) {
       if(addview.isActive()){
           addview.setIpInfo(ipInfo);
       }
    }

    @Override
    public void onStart() {
        if(addview.isActive()){
            addview.showLoading();
        }
    }

    @Override
    public void onFailed() {
        if(addview.isActive()){
            addview.showError();
            addview.hideLoading();
        }
    }

    @Override
    public void onFinish() {
        if(addview.isActive()){
            addview.hideLoading();
        }
    }
    //上面实现的接口作为参数传进execute方法中

    @Override
    public void getIpInfo(String ip) {
       netTask.execute(ip, this);//1
    }
}

10.IpInfoFragment.java

主要作用:将view和Presener联系起来
package com.example.yang.mvp.ipinfo;

import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.example.yang.mvp.R;
import com.example.yang.mvp.model.IpData;
import com.example.yang.mvp.model.IpInfo;

public class IpInfoFragment extends Fragment implements IpInfoContract.View {
    private TextView tv_country,tv_city,tv_area;
    private Button bt_ipinfo;
    private Dialog mDialog;
    private IpInfoContract.Presenter mPresener;
    public static IpInfoFragment newinstance(){
        return new IpInfoFragment();
    }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState) {
        View view=inflater.inflate(R.layout.fragment_ipinfo, container,false);
        tv_country=view.findViewById(R.id.tv_country);
        tv_city=view.findViewById(R.id.tv_city);
        tv_area=view.findViewById(R.id.tv_area);
        bt_ipinfo=view.findViewById(R.id.bt_ipinfo);
        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mDialog=new ProgressDialog(getActivity());
        mDialog.setTitle("数据加载中");
        bt_ipinfo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mPresener.getIpInfo("xxxxxx(请求数据如username)");
            }
        });
    }

    @Override
    public void setIpInfo(IpInfo ipInfo) {
        if(ipInfo!=null&&ipInfo.getIpData()!=null){
            IpData ipData=ipInfo.getIpData();
            tv_country.setText(ipData.getCountry());
            tv_city.setText(ipData.getCity());
            tv_area.setText(ipData.getArea());
        }
    }

    @Override
    public void showLoading() {
         mDialog.show();
    }

    @Override
    public void hideLoading() {
        if(mDialog.isShowing()){
            mDialog.dismiss();
        }
    }

    @Override
    public void showError() {
        Toast.makeText(getActivity().getApplicationContext(), "网络出错", Toast.LENGTH_LONG).show();
    }

    @Override
    public boolean isActive() {
        return isAdded();
    }

    @Override
    public void setPresenter(IpInfoContract.Presenter presenter) {
        mPresener=presenter;
    }
}

11.IpInfoActivity.java

package com.example.yang.mvp.ipinfo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.example.yang.mvp.R;
import com.example.yang.mvp.net.IpInfoTask;
import com.example.yang.mvp.util.ActivityUtils;

public class IpInfoActivity extends AppCompatActivity {
private IpInfoPresener ipInfoPresener;
//声明了一个中间人,联系数据以及view;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        IpInfoFragment ipInfoFragment=IpInfoFragment.newinstance();
            ActivityUtils.addFragmentToActivity(getSupportFragmentManager(),ipInfoFragment ,R.id.contentFrame);
        IpInfoTask ipInfoTask=IpInfoTask.getInstance();
        ipInfoPresener=new IpInfoPresener(ipInfoTask,ipInfoFragment);
        ipInfoFragment.setPresenter(ipInfoPresener);
    }
}

11.ActivityUtils.java

package com.example.yang.mvp.util;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;

public class ActivityUtils {
    public static void addFragmentToActivity(FragmentManager fragmentManager,Fragment fragment,int frameID){
        FragmentTransaction transaction=fragmentManager.beginTransaction();
        transaction.add(frameID, fragment);
        transaction.commit();

    }
}

以上步骤只是针对案例给出的,实际情况不同可能有的步骤可以合并有的还需要细分。

发布了123 篇原创文章 · 获赞 74 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43927892/article/details/102328017