-
- ① 添加基于OKHTTP的网络请求封装框架okhttpfinal
- ② 初始化okhttpfinal
- ③ 创建实体类(为了看的清晰,把原本的内部类ResultBean和DataBean抽离出来)
- ④ 定义网络监听回调接口
- ⑤ 定义获取网络数据的接口类,定义获取数据的方法
- 创建获取网络数据接口NetTask的实现类实际去获取数据
- ⑦定义一个持有presenter的view层接口,用于view和module层的交互
- ⑧ 契约接口
- ⑨ 实现Presenter接口
- ⑩将fragment添加到acvitity中的工具方法
- 11、fragment实现了view接口,用来接收IpinfoPresenter的回调并更新界面
- 12、acvitity的实现
① 添加基于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