MVP是在MVC的基础上演变过来的,MVP包括Model,View,Presenter3层,View和Model相互独立,通过Presenter作为桥梁将View和Model联系起来,从而实现视图和模型的完全分离。MVP模式下,View只管接受Presenter的调度刷新UI,Model只管像Presenter提供数据,Presenter负责处理业务逻辑。
下面展示的是一个录入数据的小项目
一、项目前准备:
1.引入RxJava,Retrofit的依赖
compile 'io.reactivex:rxjava:1.0.14'
compile 'io.reactivex:rxandroid:1.0.1'
compile 'com.squareup.retrofit2:retrofit:2.2.0'
compile 'com.squareup.retrofit2:converter-gson:2.2.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.2.0'
2.安装MVPHelper插件
在androidStudio的Browse Repositories中搜索MVPHelper安装重起androidStudio就可以了,MVPHelp能够帮助我们快速的构建mvp模式的相关包和类,非常的方便
如果没用过这个插件,使用方式自行百度。
2、项目目录结构展示
看了上图,应该对mvp的结构有一定的了解了,首先跟据模块来分的,logging是录入数据的模块,里面清晰的看到的包有adapter,api,bean,callback,contract,model,presenter包,其中
- adapter:存放适配器
- api:存放网络接口
- bean:存放实体
- callback:访问网络的接口回调
- contract:存放接口,在这个包里统一管理View,Model,Presenter的接口,使用contract大大的减少了类的个数
- model:存放model的实现类,进行网络访问返回数据
- presenter:存放presenter的实现类
3项目MVP各层具体展示
3.1LoggingContract.java,所有的接口都写在此类中,为了方便管理各个接口
package com.cool.loggingdata.logging.contract;
import com.cool.loggingdata.logging.bean.NfcInfoBean;
import com.cool.loggingdata.logging.callback.LoggingCallBack;
/**
* Created by cool on 2017/3/21.
*/
public class LoggingContract {
public interface ILoggingView {
void showProgress();
void hideProgress();
void loadDataSuccess(NfcInfoBean nfcInfoBean);
void loadDataFail(String msg);
}
public interface ILoggingPresenter {
void loadData();
}
public interface ILoggingModel {
void loadData(LoggingCallBack callBack);
}
}
把目光转向ILoggingView,此接口需要Activity去实现,在activity中获取数据,抽取其中的方法,总的有显示和隐藏进度条,加载数据成功和加载数据失败,activity中实现这几个方法就可以了,数据怎么去加载,如何去加载都不再关心,只管发起请求处理数据,逻辑非常的直观和明了。
再看ILoggingModel这个接口封装了一个个加载数据的方法,是真实从网络上加载数据的方法。
最后看ILoggingPresenter,这个调用ILoggingModel的实现类的LoadData的方法并传相关数据,获取数据进行相关的业务逻辑的处理,再调用ILoggingView中的相关方法进行刷新UI
3.2LoggingService.java,接口类
package com.cool.loggingdata.logging.api;
import com.cool.loggingdata.logging.bean.NfcInfoBean;
import retrofit2.http.GET;
import rx.Observable;
/**
* Created by cool on 2017/3/21.
*/
public interface LoggingService {
@GET("spaceandequipmentcode")
Observable<NfcInfoBean> getData();
}
3.3LoggingModelImpl.java
package com.cool.loggingdata.logging.model;
import com.cool.loggingdata.AppConfig;
import com.cool.loggingdata.RetrofitUtils;
import com.cool.loggingdata.logging.api.LoggingService;
import com.cool.loggingdata.logging.bean.NfcInfoBean;
import com.cool.loggingdata.logging.callback.LoggingCallBack;
import com.cool.loggingdata.logging.contract.LoggingContract;
import rx.Observer;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
/**
* Created by cool on 2017/03/21
*/
public class LoggingModelImpl implements LoggingContract.ILoggingModel{
@Override
public void loadData(final LoggingCallBack callBack) {
RetrofitUtils.newInstence(AppConfig.url)
.create(LoggingService.class)
.getData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<NfcInfoBean>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
if(callBack != null){
callBack.loadFail(e.getMessage());
}
}
@Override
public void onNext(NfcInfoBean nfcInfoBean) {
if(callBack != null){
if(nfcInfoBean.Status.equals("success")){
callBack.loadSuccess(nfcInfoBean);
}else {
callBack.loadFail(nfcInfoBean.ErrorMsg);
}
}
}
});
}
}
3.4LoggingPresenterImpl.java
package com.cool.loggingdata.logging.presenter;
import com.cool.loggingdata.logging.bean.NfcInfoBean;
import com.cool.loggingdata.logging.callback.LoggingCallBack;
import com.cool.loggingdata.logging.contract.LoggingContract;
import com.cool.loggingdata.logging.model.LoggingModelImpl;
/**
* Created by cool on 2017/03/21
*/
public class LoggingPresenterImpl implements LoggingContract.ILoggingPresenter{
private LoggingContract.ILoggingView mLoggingView;
private LoggingContract.ILoggingModel mLoggingModel;
public LoggingPresenterImpl( LoggingContract.ILoggingView loggingView){
this.mLoggingView = loggingView;
mLoggingModel = new LoggingModelImpl();
}
@Override
public void loadData() {
mLoggingView.showProgress();
mLoggingModel.loadData(new LoggingCallBack() {
@Override
public void loadSuccess(NfcInfoBean nfcInfoBean) {
mLoggingView.loadDataSuccess(nfcInfoBean);
mLoggingView.hideProgress();
}
@Override
public void loadFail(String msg) {
mLoggingView.loadDataFail(msg);
mLoggingView.hideProgress();
}
});
}
}
3.5HomeActivity
package com.cool.loggingdata.logging;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;
import com.cool.loggingdata.R;
import com.cool.loggingdata.logging.adapter.LoggingAdapter;
import com.cool.loggingdata.logging.bean.NfcInfoBean;
import com.cool.loggingdata.logging.bean.NfcInfoBean.DataBean.ListmodelBean;
import com.cool.loggingdata.logging.contract.LoggingContract;
import com.cool.loggingdata.logging.presenter.LoggingPresenterImpl;
import com.cool.loggingdata.write.WriteToNFCActivity;
import java.util.ArrayList;
import java.util.List;
public class HomeActivity extends AppCompatActivity implements LoggingContract.ILoggingView, LoggingAdapter.OnItemClickListener {
private RecyclerView mListRecycleView;
private LoggingPresenterImpl loggingPresenter;
private ProgressDialog progressDialog;
private List<ListmodelBean> mList = new ArrayList<>();
private ListmodelBean listmodelBean;
private LoggingAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
getSupportActionBar().setTitle("空间设备信息列表");
mListRecycleView = (RecyclerView) findViewById(R.id.rv_list);
loggingPresenter = new LoggingPresenterImpl(this);
progressDialog = new ProgressDialog(this);
loggingPresenter.loadData();
initRecycleView();
}
private void initRecycleView() {
mAdapter = new LoggingAdapter(this,mList);
mListRecycleView.setLayoutManager(new LinearLayoutManager(this));
mListRecycleView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(this);
}
@Override
public void onItemClick(View view, int position) {
listmodelBean = mList.get(position);
Intent intent = new Intent(this, WriteToNFCActivity.class);
intent.putExtra("name",listmodelBean.name);
intent.putExtra("context",listmodelBean.context);
startActivityForResult(intent,1);
}
@Override
public void showProgress() {
progressDialog.show();
}
@Override
public void hideProgress() {
progressDialog.dismiss();
}
@Override
public void loadDataSuccess(NfcInfoBean nfcInfoBean) {
mList.addAll(nfcInfoBean.Data.listmodel);
mAdapter.notifyDataSetChanged();
}
@Override
public void loadDataFail(String msg) {
Toast.makeText(this,msg,Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1 && resultCode ==1){
mList.remove(listmodelBean);
mAdapter.notifyDataSetChanged();
}
}
}
3.6LoggingCallBack.java
package com.cool.loggingdata.logging.callback;
import com.cool.loggingdata.logging.bean.NfcInfoBean;
/**
* Created by cool on 2017/3/22.
*/
public interface LoggingCallBack {
void loadSuccess(NfcInfoBean nfcInfoBean);
void loadFail(String msg);
}
3.7NfcInfoBean.java
package com.cool.loggingdata.logging.bean;
import java.util.List;
/**
* Created by cool on 2017/3/21.
*/
public class NfcInfoBean {
public DataBean Data;
public String ErrorCode;
public String ErrorMsg;
public String Status;
public static class DataBean {
public List<ListmodelBean> listmodel;
public static class ListmodelBean {
public String context;
public String name;
}
}
}
3.8RetrofitUtils
package com.cool.loggingdata;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
/**
* Created by cool on 2017/3/21.
*/
public class RetrofitUtils {
//定义一个静态私有变量(不初始化,不使用final关键字,使用volatile保证了多线程访问时mRetrofit变量的可见性,避免了mRetrofit初始化时其他变量属性还没赋值完时,被另外线程调用)
private static volatile Retrofit mRetrofit;
private RetrofitUtils() {
}
public static Retrofit newInstence(String url) {
// 对象实例化时与否判断(不使用同步代码块,instance不等于null时,直接返回对象,提高运行效率)
if(mRetrofit == null) {
//同步代码块(对象未初始化时,使用同步代码块,保证多线程访问时对象在第一次创建后,不再重复被创建)
synchronized (RetrofitUtils.class) {
mRetrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
// .addConverterFactory(ScalarsConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
}
return mRetrofit;
}
}
项目地址:https://github.com/coolfuwei/LoggingData