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