對于MVP架構(gòu)我想大家都不陌生吧,對于現(xiàn)在的主流框架非MVP + RxJava + Retrofit莫屬了倡勇,GitHub上也有很多優(yōu)秀的開源項目對其進行了很好的封裝锭吨。有時候看一些優(yōu)秀的開源項目是一種享受纹冤,但自己如果能從這里學(xué)到并實現(xiàn)一些自己想實現(xiàn)的需求我想那更是一種享受雄可。這里很簡單的去實現(xiàn)一個MVP的基類,其它擴展功能可以自行添加蕴侣。
Model
public abstract class BaseModel {
}
Presenter
public abstract class BasePresenter<M,V> {
public M mIModle;
public V mIView;
public void attachV(V v){
this.mIView = v;
if (mIModle == null) {
mIModle = createModel();
}
}
//當View被銷毀掉時刪除Presenter層對View層的引用
public void detachV(){
mIView = null;
}
public abstract M createModel();
}
View
public interface IBaseView {
}
@SuppressLint("Registered")
public abstract class BaseMvpActivity<P extends BasePresenter> extends AppCompatActivity implements IBaseView{
public P mPresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (mPresenter == null) {
mPresenter = createPresenter();
}
mPresenter.attachV(this);
}
//當View被銷毀掉時刪除Presenter層對View層的引用
@Override
protected void onDestroy() {
super.onDestroy();
mPresenter.detachV();
}
public abstract P createPresenter();
}
這里Mode和View的基類里什么都沒有焰轻,其實我們知道一般封裝基類的目錄是為了簡化項目代碼,提高開發(fā)效率昆雀。所以這里兩個基類里面一般根據(jù)我們自己需求去實現(xiàn)辱志。
Example
public interface ExampleDataSource {
interface OnExampleFinishListener{
void loading();
void onSuccess();
void onError();
}
void load(OnExampleFinishListener listener);
}
ExampleDataSource接口實現(xiàn)的是ExampleModel,而在它的內(nèi)部接口OnExampleFinishListener是Model層的回調(diào)接口,它們真正實現(xiàn)是在Presenter層狞膘。對于獲取到數(shù)據(jù)后(成功或失斂痢)就是通過這個回調(diào)接口將數(shù)據(jù)傳遞Presenter層。
public class ExampleModel extends BaseModel implements ExampleDataSource {
/**
* model層主要用來進行數(shù)據(jù)存儲操作挽封,例如:數(shù)據(jù)讀寫和網(wǎng)絡(luò)請求已球。
* 這里進行下模擬耗時操作
* @param listener
*/
@Override
public void load(final OnExampleFinishListener listener) {
//加載中狀態(tài)
listener.loading();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//獲取成功后進行回調(diào)
listener.onSuccess();
}
},2000);
}
}
這里我們在Model層模擬下耗時操作(例如:網(wǎng)絡(luò)請求),然后將得到的數(shù)據(jù)結(jié)果通過回調(diào)方法傳遞到Presenter層辅愿。
public interface ExampleContract extends IBaseView {
interface ExamplePresent {
void loadData();
}
interface ExampleView {
void loadResult(String result);
void showLoading();
void loadFinish();
}
}
這里我們將Presenter接口和View接口放在一個類中智亮,這樣可以使我們能夠清晰的看到在Presenter層和View層中有哪些功能,方便我們以后維護渠缕。
public class ExamplePresenter extends BasePresenter<ExampleModel,ExampleContract.ExampleView> implements ExampleContract.ExamplePresent,ExampleDataSource.OnExampleFinishListener{
@Override
public void loadData() {
mIModle.load(this);
}
@Override
public void loading() {
mIView.showLoading();
}
@Override
public void onSuccess() {
mIView.loadResult("成功");
mIView.loadFinish();
}
@Override
public void onError() {
}
@Override
public ExampleModel createModel() {
return new ExampleModel();
}
}
從Presenter層我們可以看出鸽素,首先調(diào)用Model層的接口獲取數(shù)據(jù)進行一些邏輯操作然后通過View層接口實現(xiàn)數(shù)據(jù)的展示。
public class MainActivity extends BaseMvpActivity<ExamplePresenter> implements ExampleContract.ExampleView {
private TextView tvName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvName = findViewById(R.id.tv_name);
//加載數(shù)據(jù)
mPresenter.loadData();
}
@Override
public ExamplePresenter createPresenter() {
return new ExamplePresenter();
}
//返會數(shù)據(jù)結(jié)果
@Override
public void loadResult(String result) {
tvName.setText(result);
}
//加載過程
@Override
public void showLoading() {
tvName.setText("正在加載亦鳞,請稍等馍忽。。燕差。");
}
//加載結(jié)束
@Override
public void loadFinish() {
}
}
嗯遭笋,好了!一個很簡單的MVP基類就實現(xiàn)了徒探,對于使用輪子來說瓦呼,我們更應(yīng)該試著一點點自己去實現(xiàn)它,從簡單到復(fù)雜测暗。慢慢就會更加的了解它央串。貼上項目源碼更參考。