纯净的MVP架构思路

① 添加基于OKHTTP的网络请求封装框架okhttpfinal

implementation 'cn.finalteam:okhttpfinal:2.0.7'

② 初始化okhttpfinal

 @Override
    public void onCreate() {
        super.onCreate();
        OkHttpFinalConfiguration.Builder builder=new OkHttpFinalConfiguration.Builder();
        OkHttpFinal.getInstance().init(builder.build());
    }

③ 创建实体类(为了看的清晰,把原本的内部类ResultBean和DataBean抽离出来)

。。。
private String reason;
    private ResultBean result;
    private int error_code;。。。。

④ 定义网络监听回调接口

public interface LoadTasksCallBack<T> {
    void onStart();

    void onFinish();

    void onSuccess(T t);

    void onFailed();

}

⑤ 定义获取网络数据的接口类,定义获取数据的方法

public interface NetTask<T> {
    void execute(T data,LoadTasksCallBack callBack);
}

创建获取网络数据接口NetTask的实现类实际去获取数据

package com.gradle.ytf.mvpapplication.api;

import com.gradle.ytf.mvpapplication.module.TitleData;

import cn.finalteam.okhttpfinal.BaseHttpRequestCallback;
import cn.finalteam.okhttpfinal.HttpRequest;
/**
 * ⑥创建获取网络数据接口NetTask的实现类实际去获取数据,根据返回数据类型确定泛型string
 * IpInfoTask是一个单例类,在execute方法中通过okhttpfinal获取数据,
 * 同时在okhttpfinal的回调函数中调用自己定义的回调函数loadTasksCallBack
 * @author YTF
 */

public class IpInfoTask implements NetTask<String> {

    private IpInfoTask() {
    }

    public static IpInfoTask getInstance() {
        return SingletonHolder.sInstance;
    }

    private static class SingletonHolder {
        private static final IpInfoTask sInstance = new IpInfoTask();
    }

    @Override
    public void execute(final String url, final LoadTasksCallBack callBack) {

        HttpRequest.get(url, new BaseHttpRequestCallback<TitleData>() {
            @Override
            public void onStart() {
                super.onStart();
                callBack.onStart();
            }

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

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

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

⑦定义一个持有presenter的view层接口,用于view和module层的交互

package com.gradle.ytf.mvpapplication.view;

/**
 * ⑦定义一个持有presenter的view层接口,用于view和module层的交互,
 * 并提供view层绑定presenter层的方法
 * @param <T>
 */
public interface BaseView<T> {
    void setPresenter(T presenter);
}

⑧ 契约接口

package com.gradle.ytf.mvpapplication.contract;

import com.gradle.ytf.mvpapplication.module.TitleData;
import com.gradle.ytf.mvpapplication.view.BaseView;

/**
 * ⑧ 契约接口主要用来存放相同业务的Presenter和View的接口,便于查找和维护。
 */
public interface IpInfoContract {
    /**
     * Presenter接口定义获取数据的方法
     */
    interface Presenter {
        void getIpInfo(String url);
    }

    /**
     * view接口定义与页面交互的方法
     * isActive方法用于判断Fragment是否添加到了Activity中
     */
    interface View extends BaseView<Presenter> {
        void setIpInfo(TitleData ipData);

        void showLoading();

        void hideLoading();

        void showError();

        boolean isActivie();
    }
}

⑨ 实现Presenter接口

package com.gradle.ytf.mvpapplication.presenter;

import com.gradle.ytf.mvpapplication.api.LoadTasksCallBack;
import com.gradle.ytf.mvpapplication.api.NetTask;
import com.gradle.ytf.mvpapplication.contract.IpInfoContract;
import com.gradle.ytf.mvpapplication.module.TitleData;

/**
 * ⑨实现Presenter接口:
 * Presenter实际就是一个中间人,它通过NetTask(Model层)获取和保存数据,然后通过View更新界面。
 期间通过定义接口使得View和Model没有任何交互。
 */
public class IpInfoPresenter implements IpInfoContract.Presenter, LoadTasksCallBack<TitleData> {
    /**
     * IpInfoPresenter中含有NetTask和InfoContract.View的实例,并且实现了LoadTasksCallBack接口
     * mNetTask.execute(ip, this)用于获取数据并且回调给InInfoPresenter,回调给InInfoPresenter后通过mAddTaskView和页面进行交互,更改界面。
     */
    private NetTask mNetTask;
    private IpInfoContract.View mAddTaskView;

    public IpInfoPresenter(NetTask netTask, IpInfoContract.View addTaskView) {
        mNetTask = netTask;
        mAddTaskView = addTaskView;
    }

    @Override
    public void onStart() {
        if (mAddTaskView.isActivie()) {
            mAddTaskView.showLoading();
        }
    }

    @Override
    public void onFinish() {
        if (mAddTaskView.isActivie()) {
            mAddTaskView.hideLoading();
        }
    }

    @Override
    public void onSuccess(TitleData titleData) {
        if (mAddTaskView.isActivie()) {
            mAddTaskView.setIpInfo(titleData);
        }
    }

    @Override
    public void onFailed() {
        if (mAddTaskView.isActivie()) {
            mAddTaskView.showError();
            mAddTaskView.hideLoading();
        }
    }

    @Override
    public void getIpInfo(String url) {
        mNetTask.execute(url, this);
    }
}

⑩将fragment添加到acvitity中的工具方法

package com.gradle.ytf.mvpapplication.util;


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

/**
 * ⑩将fragment添加到acvitity中的工具方法
 */
public class ActivityUtils {
    public static void addFragmentToActivity(FragmentManager fragmentManager, Fragment fragment, int frameId) {
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(frameId, fragment);
        fragmentTransaction.commit();
    }
}

11、fragment实现了view接口,用来接收IpinfoPresenter的回调并更新界面

package com.gradle.ytf.mvpapplication.view;

import android.app.ProgressDialog;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
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.gradle.ytf.mvpapplication.R;
import com.gradle.ytf.mvpapplication.contract.IpInfoContract;
import com.gradle.ytf.mvpapplication.module.DataBean;
import com.gradle.ytf.mvpapplication.module.TitleData;

import java.util.List;

/**
 * 11、fragment实现了view接口,用来接收IpinfoPresenter的回调并更新界面
 */
public class IpInfoFragment extends Fragment implements IpInfoContract.View {

    private Button mBt_ipinfo;
    private TextView mNews;
    private ProgressDialog mProgressDialog;

    private IpInfoContract.Presenter mPresenter;


    private static final String URL = "http://v.juhe.cn/toutiao/index?type=top&key=cc651913ae067cf88c7d9ec710fe5b3a";

    public static IpInfoFragment newInstance() {
        return new IpInfoFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_ip_info, container, false);
        mNews = (TextView) root.findViewById(R.id.tv_news);
        mBt_ipinfo = (Button) root.findViewById(R.id.bt_ipinfo);
        return root;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mProgressDialog = new ProgressDialog(getActivity());
        mProgressDialog.setTitle("获取数据中");
        mBt_ipinfo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mPresenter.getIpInfo(URL);
            }
        });
    }

    /**
     * getIpInfo方法获取ip地址的信息:也就是调用presenter
     * @param ipInfo
     */
    @Override
    public void setIpInfo(TitleData ipInfo) {
        if (ipInfo != null && ipInfo.getResult().getData() != null) {
            List<DataBean> data = ipInfo.getResult().getData();
            mNews.setText(data.get(0).getTitle());
        }
    }

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

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

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

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

    /**
     * setPresenter方法注入IpInfoPresenter。
     * @param presenter
     */
    @Override
    public void setPresenter(IpInfoContract.Presenter presenter) {
        mPresenter = presenter;
    }
}

12、acvitity的实现

package com.gradle.ytf.mvpapplication.view;

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

import com.gradle.ytf.mvpapplication.R;
import com.gradle.ytf.mvpapplication.api.IpInfoTask;
import com.gradle.ytf.mvpapplication.presenter.IpInfoPresenter;
import com.gradle.ytf.mvpapplication.util.ActivityUtils;

/**
 * @author YTF
 */
public class MainActivity extends AppCompatActivity {
    private IpInfoPresenter ipInfoPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //  把Fragment添加到Activity中
        IpInfoFragment ipInfoFragment = (IpInfoFragment) getSupportFragmentManager().findFragmentById(R.id.contentFrame);
        if (ipInfoFragment == null) {
            ipInfoFragment = IpInfoFragment.newInstance();
            ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), ipInfoFragment, R.id.contentFrame);
        }
        //  把Model和View注入Presenter,并且把Presenter注入Fragment
        IpInfoTask ipInfoTask = IpInfoTask.getInstance();
        ipInfoPresenter = new IpInfoPresenter(ipInfoTask, ipInfoFragment);
        ipInfoFragment.setPresenter(ipInfoPresenter);
    }
}

最后不要忘记添加网络请求权限
效果图:
这里写图片描述
Git地址:https://gitee.com/ytfunny_site/MVP_YTF.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值