如果想知道MVPPlugin的使用的話可以看一下這個鏈接,非常詳細:http://mp.weixin.qq.com/s/fo34hyvjzNSURSh_V8y4oQ
根據鏈接創造出來的項目如下:
LoginActivity.java,LoginPresenter.java,LoginContract.java三個文件都是由MVPPlugin插件自動創建的,然後我根據登陸需要進行的操作進行完善一下。
然後我們進入到LoginActivity.java文件看一下內容是啥:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import com.example.administrator.mvpfiletest.R;
import com.example.administrator.mvpfiletest.mvp.MVPBaseActivity;
/**
* MVPPlugin
*/
public class LoginActivity extends MVPBaseActivity<LoginContract.View, LoginPresenter> implements LoginContract.View {
TextView log;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
log = (TextView) findViewById(R.id.log);
final EditText name = (EditText) findViewById(R.id.name);
final EditText pwd = (EditText) findViewById(R.id.pwd);
findViewById(R.id.login).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mPresenter.onlogin(name.getText().toString(),pwd.getText().toString());
}
});
}
@Override
public void onSuccess() {
log.setText("登陸成功");
}
@Override
public void onError() {
log.setText("登陸失敗");
}
}
可以看到LoginActivity是繼承於MVPBaseActivity的,代表View層,這個View層的作用是一般也就做加載UI視圖、設置監聽再交由Presenter處理的一些工作,本層所需要做的操作就是在每一次有相應交互的時候,調用presenter的相關方法就行。然後還傳遞了兩個泛型進去,分別是BaseView的子類LoginContract.View跟BasePresenterImpl的子類LoginPresenter,
然後看看MVPBaseActivity裏面是啥:
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import java.lang.reflect.ParameterizedType;
/**
* MVPPlugin
* 郵箱 [email protected]
*/
public abstract class MVPBaseActivity<V extends BaseView,T extends BasePresenterImpl<V>> extends AppCompatActivity implements BaseView{
public T mPresenter; // T等價於LoginPresenter
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPresenter= getInstance(this,1);
mPresenter.attachView((V) this); //V等價於LoginContract.View接口
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mPresenter!=null)
mPresenter.detachView();
}
@Override
public Context getContext(){
return this;
}
public <T> T getInstance(Object o, int i) {
try {
return ((Class<T>) ((ParameterizedType) (o.getClass()
.getGenericSuperclass())).getActualTypeArguments()[i])
.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassCastException e) {
e.printStackTrace();
}
return null;
}
}
可以看到MVPBaseActivity其實就是通過getInstance創建了LoginPresenter實例,然後通過attachView把LoginContract.View的接口實例傳遞進去給LoginPresenter的父類BasePresenterImpl的mView,進去看一下BasePresenterImpl的函數:
public class BasePresenterImpl<V extends BaseView> implements BasePresenter<V>{
protected V mView;
@Override
public void attachView(V view) {
mView=view;
}
@Override
public void detachView() {
mView=null;
}
}
BasePresenter的接口內容:
public interface BasePresenter <V extends BaseView>{
void attachView(V view);
void detachView();
}
可以看出MVPBaseActivity的作用是使得LoginPresenter實例化,然後使得LoginContract.View實例化,這樣在後面的使用時候可以用mPresenter來處理邏輯關係,用mView來更新View視圖
所以LoginPresenter的內容如下:
public class LoginPresenter extends BasePresenterImpl<LoginContract.View> implements LoginContract.Presenter{
@Override
public void onlogin(String name, String pwd) { //處理耗時的操作 比如訪問服務器,數據庫 根據結果調用不同的接口
if (name.equals("test") && pwd.equals("123")){
mView.onSuccess();
}else {
mView.onError();
}
}
}
總結一下LoginPresenter可以控制UI更新,然後可以在這邊做一些耗時的工作,MVPBaseActivity是實例化了mPresenter,跟後面用來更新UI的mView
不是說處理耗時的操作要放在Model上面嗎!怎麼在Presenter層上面就做了那些耗時的操作了?然後Model層在哪裏?怎麼只看到了Presenter跟View層呢?!這哪裏是標準的MVP模式!!!其實這邊是沒有model的,但是要加的話也是可以的,LoginModel如下:public class LoginModel implements LoginContract.Model {
@Override
public void login(String name, String pwd,LoginContract.LoginResult result) {
if (name.equals("test") && pwd.equals("123")){
result.onSuccess();
}else {
result.onError();
}
}
}
然後要在LoginContract增加一個Model有結果時候對LoginPresenter操作的接口:
interface LoginResult{
void onSuccess();
void onError();
}
然後在LoginPresenter實現這個接口:
public class LoginPresenter extends BasePresenterImpl<LoginContract.View> implements LoginContract.Presenter,LoginContract.LoginResult{
@Override
public void onlogin(String name, String pwd) { //處理耗時的操作 比如訪問服務器,數據庫 根據結果調用不同的接口
LoginContract.Model model = new LoginModel();
model.login(name,pwd,this);
}
@Override
public void onSuccess() {
mView.onSuccess();
}
@Override
public void onError() {
mView.onError();
}
這樣做Model層是有了,但是感覺是不是比剛纔麻煩了許多?增加了許多的接口,然後邏輯也變得複雜了,而且耦合性並沒有降低。然後看了一下MVPPlugin的代碼。這樣做的Presenter層有點像Model跟Presenter結合起來,反正我是覺得MVPPlugin這樣搞會比較爽一些。。。。當然了。。有點牽強。希望有人能補充一下。。哪裏說的不對請指正