Mvp實戰心得(二)---Base基類的封裝
阿新 • • 發佈:2019-01-31
基類:
在開發中有著很重要的地位,基類設計封裝的好,不管是對app的效能,還是對開發的效率都有著很重要的作用
基類可以簡單幾個字概況,一個良好的父類.
結構:
不管你的app是多個acitivity,還是1個activity+n個fragment,還是多個acitivity多個fragment.
始終都是用的acitivity和fragment.
根據專案的不同,基類不可能完全相同,但很多還是可以通用的.
抽取:
既然是mvp,那麼不管是acitivity還是fragment.都歸於v 既然是v,那麼就應該有相對應的presenter,view 那麼基類應該有: BaseActivityView BaseFragmentView BaseView BasePresenter
具體程式碼:
BaseActivity
public abstract class BaseActivity<T extends BasePresenter> extends AppCompatActivity implements BaseActivityView { protected T mPresenter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //建立Presenter mPresenter = initPresenter(); //類似fragment的繫結.拿到引用 mPresenter.onAttch(this); //初始化acitivity, onCreateActivity(savedInstanceState); //初始化Presenter mPresenter.onCreate(); } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); mPresenter.onSaveInstanceState(outState); } @Override protected void onDestroy() { mPresenter.onDestroy(); mPresenter.onDetach(); super.onDestroy(); } @Override public BaseActivity getActivity() { return this; } /** * 建立prensenter * @return <T extends BasePresenter> 必須是BasePresenter的子類 */ protected abstract T initPresenter(); /** * 子類必須實現,並初始化Activity,比如setContentView() */ protected abstract void onCreateActivity(Bundle savedInstanceState); @Override public void isNightMode(boolean isNight) { } }
BaseFragment
稍微複雜一點.
public abstract class BaseFragment<T extends BasePresenter> extends Fragment implements BaseFragmentView { protected T mPresenter; protected Context mContext;//activity的上下文物件 protected Bundle mBundle; @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (mBundle != null) { outState.putBundle("bundle", mBundle); } } /** * 繫結activity * * @param context */ @Override public void onAttach(Context context) { super.onAttach(context); mContext = context; } /** * 執行在onAttach之後 * 可以接受別人傳遞過來的引數,例項化物件. * * @param savedInstanceState */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //獲取bundle,並儲存起來 if (savedInstanceState != null) { mBundle = savedInstanceState.getBundle("bundle"); } else { mBundle = getArguments() == null ? new Bundle() : getArguments(); } //建立presenter mPresenter = initPresenter(); } /** * 執行在onCreate之後 * 生成view檢視 */ @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return initView(inflater, container, savedInstanceState); } /** * 執行在onCreateView之後 * 載入資料 */ @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); //由於fragment生命週期比較複雜,所以Presenter在onCreateView建立檢視之後再進行繫結,不然會報空指標異常 mPresenter.onAttch(this); mPresenter.onCreate(); } @Override public void onDestroyView() { mPresenter.onDestroy(); super.onDestroyView(); } @Override public void onDetach() { mPresenter.onDetach(); super.onDestroyView(); } /** * 跳轉fragment * * @param tofragment */ @Override public void startFragment(Fragment tofragment) { startFragment(tofragment, null); } /** * @param tofragment 跳轉的fragment * @param tag fragment的標籤 */ @Override public void startFragment(Fragment tofragment, String tag) { FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction(); fragmentTransaction.hide(this).add(android.R.id.content, tofragment, tag); fragmentTransaction.addToBackStack(tag); fragmentTransaction.commitAllowingStateLoss(); } /** * 類似Activity的OnBackgress * fragment進行回退 */ public void onBack() { getFragmentManager().popBackStack(); } /** * 初始化Fragment應有的檢視 * * @return */ public abstract View initView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState); /** * 建立prensenter * * @return <T extends BasePresenter> 必須是BasePresenter的子類 */ public abstract T initPresenter(); @Override public Context getContext() { return mContext; } @Override public Bundle getBundle() { return mBundle; } @Override public BaseFragment getFragment() { return this; } }
再看看BaseView
public interface BaseView {
/**
* 切換夜間模式
* @param isNight 是否切換為夜間模式
*/
void isNightMode(boolean isNight);
}
BaseView得想好做什麼事,必須是你的專案裡所有view都有的共性
不僅是acitivity和fragment,還有控制元件
-----------------------------------------------------------------------------------------------------
關鍵的BasePresenter來了
/**
* @author jlanglang 2016/11/11 15:10
*/
public abstract class BasePresenter<T extends BaseView> {
protected T mView;
/**
* 繫結View
*/
public void onAttch(T view) {
this.mView = view;
}
/**
* 做初始化的操作,需要在V的檢視初始化完成之後才能呼叫
* presenter進行初始化.
*/
public abstract void onCreate();
/**
* 在這裡結束非同步操作
*/
public void onDestroy(){
}
/**
* 在V銷燬的時候呼叫,解除繫結
*/
public void onDetach() {
mView = null;
}
/**
* 容易被回收掉時儲存資料
*/
public abstract void onSaveInstanceState(Bundle outState);
}
看看Acitivity的使用:
//建立的時候寫好泛型實現好抽象方法就行,多麼簡單.
public class MainActivity extends BaseActivity<MainActivityPresenterImpl> implements MainActivityContract.View {
@Override
protected MainActivityPresenterImpl initPresenter() {
return new MainActivityPresenterImpl();
}
@Override
protected void onCreateActivity(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
}
}
最後是對應的MainActivityPresenterImpl以及MainActivityContract
public class MainActivityPresenterImpl extends BasePresenter<MainActivityContract.View>
implements MainActivityContract.Presenter {
@Override
public void onCreate() {
}
@Override
public void onSaveInstanceState(Bundle outState) {
}
}
public class MainActivityContract {
public interface View extends BaseActivityView {
}
public interface Presenter{
}
public interface Model {
}
}
總結:
對於BasePresenter一開始我是寫成介面形式的,
後來使用過程中,發現很麻煩,每次繫結View,釋放View都需要重複造輪子.
仔細想想,抽象類更合適,
每個Presenter繼承BasePresenter,實現Contract中的介面為其補充
最後會發現,view和presenter的結構一樣.基類作為複用,介面作為補充.