上一篇主要講mvp的概念颁虐,怎么將原來一個activity分成model,presenter,activity三部分舱权,不熟悉的可以點擊下面鏈接
MVP框架搭建(1):界面數(shù)據(jù)分離
這一片主要講如何將封裝三部分的基類挎春,以及演示三部分如何串聯(lián)起來。
BaseView
當presenter收到網(wǎng)絡(luò)返回的響應(yīng)時枫吧,通過baseView傳遞給activity更新界面
public interface DaggerBaseView {
/**
* 顯示網(wǎng)絡(luò)請求加載轉(zhuǎn)圈
*/
void showLoading();
/**
* 關(guān)閉加載轉(zhuǎn)圈
*/
void hideloading();
/**
* 吐息一些信息
* @param msg
*/
void showToast(String msg);
void showErr();
Context getContext();
}
BaseModel
采用了泛型浦旱,防止因為數(shù)據(jù)類型不一致導(dǎo)致創(chuàng)建多個model的基類
public interface DaggerBaseModel <T>{
/**
* 創(chuàng)建接口對象
*/
void getNetApi();
/**
* 發(fā)送get請求
* @param callback
*/
void requestGetAPI( BaseCallBack<T> callback);
/**
* 發(fā)送post請求
* @param params
* @param callBack
*/
void requestPostAPI( Map params, BaseCallBack<T> callBack);
BasePresenter
也用到了泛型,因為每個Presenter里都需要一個View對象九杂,所以用了一個繼承BaseView的泛型對象
public abstract class DaggerBasePresenter<V extends DaggerBaseView,T> implements BaseCallBack<T> {
private V mvpView;
/**
* 綁定view颁湖,在獲取網(wǎng)絡(luò)響應(yīng)之后通過view傳遞給activity
* @param mvpView
*/
public void attachView(V mvpView){
this.mvpView=mvpView;
}
/**
* 解綁view
*/
public void detachView(){
this.mvpView=null;
}
/**
* 判斷是否解綁 在網(wǎng)絡(luò)請求時頁面被終結(jié)宣蠕,導(dǎo)致后續(xù)出現(xiàn)nullpointException
* @return
*/
public boolean isViewAttached(){
return mvpView!=null;
}
public V getMvpView(){
return mvpView;
}
/**
* 在頁面對象創(chuàng)建完成后調(diào)用,可以用來初始化數(shù)據(jù)層對象
*/
public abstract void onStart();
}
BaseActivity
使用了一個presenter的泛型爷狈,一個view的泛型植影, 每個邏輯不同的頁面要生成不同的view和presenter
public abstract class DaggerBaseActivity<V extends DaggerBaseView,T extends DaggerBasePresenter> extends Activity implements DaggerBaseView {
protected T presenter;
private ProgressDialog progressDialog;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutRes());
//將當前activity加入自定義的app管理中
AppManager.getInstance().addActivity(this);
presenter=creatPresenter();
if(presenter!=null){
//綁定當前頁面的view,用于presnter獲取數(shù)據(jù)之后控制activity的變化
presenter.attachView((V)this);
}
ButterKnife.bind(this);
progressDialog=new ProgressDialog(this);
progressDialog.setCancelable(false);
init(savedInstanceState);
if(presenter!=null){
presenter.onStart();
}
}
/**
* 做一些初始化操作
* @param savedInstanceState
*/
protected abstract void init(Bundle savedInstanceState);
/**
* 指定需要加載的布局文件
* @return
*/
protected abstract int getLayoutRes();
/**
* 創(chuàng)建presenter對象
*/
protected abstract T creatPresenter();
/**
* 使用presenter對象
* @return
*/
public T getPresnter(){
return presenter;
}
@Override
public void showLoading() {
progressDialog.show();
}
@Override
public void hideloading() {
progressDialog.hide();
}
@Override
public void showToast(String msg) {
Toast.makeText(getContext(),msg,Toast.LENGTH_SHORT).show();
}
@Override
public void showErr() {
Toast.makeText(getContext(),"出錯",Toast.LENGTH_SHORT).show();
}
@Override
public Context getContext() {
return DaggerBaseActivity.this;
}
@Override
protected void onDestroy() {
super.onDestroy();
if(presenter!=null){
presenter.detachView();
}
presenter=null;
AppManager.getInstance().finishActivity(this);
}
}
需要導(dǎo)入的三方依賴
compile 'com.jakewharton:butterknife:7.0.1'
//rxjava與retrofit
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
compile 'io.reactivex.rxjava2:rxjava:2.0.7'
// Android 支持 Retrofit
compile 'com.squareup.retrofit2:retrofit:2.1.0'
// 銜接 Retrofit & RxJava
// 此處一定要注意使用RxJava2的版本
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
// 支持Gson解析
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
下面展示一個例子,演示怎么使用
api接口 這里用到是愛詞霸的公開接口做測試涎永,大家可以在網(wǎng)上查找
public interface GetDatas {
@GET(Urls.test)
Observable<Translation> getCall();
}
model實現(xiàn)獲取網(wǎng)絡(luò)數(shù)據(jù)的方法
public class YoudaoDataModel implements DaggerBaseModel<String> {
GetDatas getDatas;
@Override
public void getNetApi() {
getDatas= ApiFactory.getInstance().create(GetDatas.class);
}
@Override
public void requestGetAPI(final BaseCallBack<String> callback) {
getDatas.getCall()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Translation>() {
@Override
public void onSubscribe(Disposable d) {
Log.e("yzh","onSubscribe");
}
@Override
public void onNext(Translation translation) {
Log.e("yzh","oNext--"+translation.show());
callback.onSuccess(translation.show());
}
@Override
public void onError(Throwable e) {
Log.e("yzh","onError--"+e.getMessage());
callback.onFailure(e.getMessage());
}
@Override
public void onComplete() {
Log.e("yzh","onComplete--");
callback.onComplete();
}
});
}
@Override
public void requestPostAPI( Map params, BaseCallBack<String> callBack) {
}
view繼承基類思币,添加當前頁面需要的額外方法
public interface YouDaoView extends DaggerBaseView {
/**
* 加載網(wǎng)絡(luò)請求回來的數(shù)據(jù)
* @param msg
*/
void showNetData(String msg);
}
presenter現(xiàn)在在基類中是實現(xiàn)callback,在具體頁面時用泛型傳遞具體的數(shù)據(jù)類型,之前是在網(wǎng)絡(luò)請求的時候直接new一個callback羡微,還沒對比出哪個更好一些
public class YouDaoPresenter extends DaggerBasePresenter<YouDaoView,String> {
private YoudaoDataModel youdaoDataModel;
@Override
public void onStart() {
youdaoDataModel=new YoudaoDataModel();
youdaoDataModel.getNetApi();
}
public void getNetData(){
if(!isViewAttached()){
//已經(jīng)解綁了
return;
}
getMvpView().showLoading();
youdaoDataModel.requestGetAPI(this);
}
@Override
public void onSuccess(String data) {
if(isViewAttached()){
getMvpView().showNetData(data);
}
}
@Override
public void onFailure(String msg) {
if(isViewAttached()){
getMvpView().showToast(msg);
getMvpView().hideloading();
}
}
@Override
public void onError() {
if(isViewAttached()){
getMvpView().hideloading();
getMvpView().showErr();
}
}
@Override
public void onComplete() {
if(isViewAttached()){
getMvpView().hideloading();
}
}
Activity
public class YoudaoActivity extends DaggerBaseActivity<YouDaoView,YouDaoPresenter> implements YouDaoView {
@Bind(R.id.tv_get_data)
TextView tv_get_data;
@Bind(R.id.tv_data)
TextView tv_data;
@Override
public void showNetData(String msg) {
tv_data.setText(msg);
}
@Override
protected void init(Bundle savedInstanceState) {
}
@Override
protected int getLayoutRes() {
return R.layout.activity_youdao;
}
@Override
protected YouDaoPresenter creatPresenter() {
return new YouDaoPresenter();
}
@OnClick(R.id.tv_get_data)
public void getNetData(){
presenter.getNetData();
}
}
演示效果
谷饿。。妈倔。博投。gif傳不上去,各位看官就自行code吧
下一步會優(yōu)化網(wǎng)絡(luò)請求方式這一塊盯蝴,包括返回數(shù)據(jù)結(jié)構(gòu)的優(yōu)化毅哗,大家可以看到這些類都帶了一個Dagger,沒錯我就是要用Dagger做解耦,但是我好像在入門到放棄的道路上越走越遠了