v1.2.3-androidx 適配androixjava
v1.2.3 添加onPresenterCircle方法android
v1.2.2 Fragment懶加載數據,添加一些週期方法,修復一些buggit
v1.1.5 修復混淆後沒法建立presentergithub
v1.1.4 修復當前頁面的子類Activity因沒法建立presenter而崩潰的問題bash
v1.1.3 將Presenter中的star()方法放到了View的onInit()方法以後調用app
v1.1.2 XBasePresenter中添加判斷view是否還存在的方法框架
v1.1.1 添加擴展自v4包的Fragmentide
這是一個MVP框架,幫助項目快速的實現MVP結構。xmvp讓所寫的代碼更加簡潔,你無須在乎關係依賴問題,xmvp自動完成。這是繼《封了一個Android MVP框架,就叫XMVP吧!》後的一次大優化,因爲改動的比較多不便再次修改那篇文章,因此新開了這一篇。 使用xmvp能簡潔所寫代碼,使結構清晰,而且我也爲它開發了一套MVP管理插件,方便快速管理MVP代碼,在文章最後將稍做介紹。gradle
dependencies {
implementation 'com.github.xujiaji:xmvp:1.2.3-androidx'
}
複製代碼
使用androidx優化
dependencies {
implementation 'com.github.xujiaji:xmvp:1.2.3-androidx'
}
複製代碼
只須要四部簡簡單單實現MVP結構
你須要定義一個Contract接口類,來抽象View、Presenter、Model的方法,而且它們須要分別繼承XContract.View、XContract.Presenter、XContract.Model接口。
例子:HomeContract
public interface HomeContract {
interface Presenter extends XContract.Presenter{
void loadData(Activity activity);
}
interface View extends XContract.View{
void loadStart();
void loadEnd(List<FileEntity> fileEntities);
}
interface Model extends XContract.Model {
void scanFile(final Activity activity, final FileHelper.Listener<List<FileEntity>> listener);
}
}
複製代碼
例子:HomeModel
public class HomeModel implements HomeContract.Model {
@Override
public void scanFile(final Activity activity, final FileHelper.Listener<List<FileEntity>> listener) {
new Thread() {
@Override
public void run() {
final FileHelper fileHelper = new FileHelper();
fileHelper.unzip(activity, listener);
}
}.start();
}
}
複製代碼
XBasePresenter<T extends XContract.View, E extends XContract.Model>
注:
T
:View接口E
:Model實現類view
和model
變量對View和Model進行操做。例子: HomePresenter
public class HomePresenter extends XBasePresenter<HomeContract.View, HomeModel> implements HomeContract.Presenter {
@Override
public void loadData(Activity activity) {
view.loadStart();
model.scanFile(activity, new FileHelper.Listener<List<FileEntity>>() {
@Override
public void success(List<FileEntity> fileEntities) {
view.loadEnd(fileEntities);
}
});
}
}
複製代碼
XBaseActivity<T extends XBasePresenter>
或XBaseFragment<T extends XBasePresenter>
注:
T
:表示Presenter的實現類例子: HomeActivity
public class HomeActivity extends XBaseActivity<HomePresenter> implements HomeContract.View {
@BindView(R.id.toolbar)
Toolbar toolbar;
@BindView(R.id.rvFolder)
RecyclerView rvFolder;
@BindView(R.id.fragParentLayout)
FrameLayout fragParentLayout;
private ProgressDialog dialog;
private HomeAdapter adapter;
@BindView(R.id.appBarLayout)
AppBarLayout appBarLayout;
@Override
protected void onInit() {
super.onInit();
ButterKnife.bind(this);
toolbar.setTitle(R.string.xmvp_folder);
setSupportActionBar(toolbar);
rvFolder.setLayoutManager(new LinearLayoutManager(this));
adapter = new HomeAdapter(new ArrayList<FileEntity>());
rvFolder.setAdapter(adapter);
presenter.loadData(this);
}
@Override
protected void onListener() {
super.onListener();
adapter.setOpenLister(new HomeAdapter.OpenListener() {
@Override
public void open(File file) {
showCode(file);
}
});
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onBackPressed();
}
});
}
/** * 顯示代碼 * * @param file */
private void showCode(File file) {
FragmentTransaction ft = getFragmentManager().beginTransaction();
CodeFragment cf = CodeFragment.newInstance(file);
ft.replace(R.id.fragParentLayout, cf);
ft.addToBackStack(null);
ft.commit();
showBlack(file.getName());
// rvFolder.setVisibility(View.GONE);
fragParentLayout.setVisibility(View.VISIBLE);
}
/** * 顯示返回按鈕和標題,傳入null則隱藏返回按鈕 * @param title */
private void showBlack(String title) {
if (title != null) {
toolbar.setNavigationIcon(R.drawable.ic_navigate_before_black_24dp);
toolbar.setTitle(title);
appBarLayout.setExpanded(true, true);
} else {
toolbar.setNavigationIcon(null);
toolbar.setTitle(R.string.xmvp_folder);
fragParentLayout.setVisibility(View.GONE);
}
}
@Override
public void loadStart() {
dialog = new ProgressDialog(this);
dialog.setTitle("正在加載數據");
dialog.setCancelable(false);
dialog.show();
}
@Override
public void loadEnd(List<FileEntity> fileEntities) {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
adapter.getData().addAll(fileEntities);
adapter.notifyDataSetChanged();
}
@Override
protected int getContentId() {
return R.layout.activity_home;
}
@Override
public void onBackPressed() {
if (fragParentLayout.getVisibility() == View.VISIBLE) {
showBlack(null);
}
super.onBackPressed();
}
}
複製代碼
以上Home相關的類簡要關係圖
就這麼的,只管實現和繼承。去掉上面的邏輯代碼後,總共就只需下面展現的代碼那麼點。
public interface HomeContract {
interface Presenter extends XContract.Presenter{}
interface View extends XContract.View{}
interface Model extends XContract.Model {}
}
public class HomeModel implements HomeContract.Model {}
public class HomePresenter extends XBasePresenter<HomeContract.View, HomeModel> implements HomeContract.Presenter {}
public class HomeActivity extends XBaseActivity<HomePresenter> implements HomeContract.View {}
複製代碼
爲何不用手動添加依賴關係呢?由於在XBaseActivity中已經幫你實現了。 可是要確保3點:
XBasePresenter<T extends XContract.View, E extends XContract.Model>
爲父類,泛型T
爲View抽象接口,泛型E
爲Model實現類。XBaseActivity<T extends XBasePresenter>
或XBaseFragment<T extends XBasePresenter>
爲父類,泛型T
爲Presenter的實現類。提示:固然也能夠在如XBaseActivity這個類爲父類定義本身的BaseActivity,可參見:BaseActivity.java
據說你MVP代碼寫煩了?
告訴你一個好消息,有一個Android studio插件:它叫MVPManager,輕輕鬆鬆管理你的MVP代碼,讓你事半功倍。 簡單介紹一下MVPManager:
END
MVPManager:github.com/xujiaji/MVP…
Github:@xujiaji