上次编写了浅谈MVP模式 一 ,其实“二”只是对“一”的另一种写法或者是说是一种延伸,我会像“一”一样直接在代码中对MVP模式进行注释,好了,直接上代码(也是我实际项目中封装的)
-
MVP封装
1.view及接口
public interface BaseMvp {
interface BaseViewInterface{
Context getContext();
void showBanUserDialog();
void dismissBanUserDialog();
void showLoadingDialog();
void dismissLoadingDialog();
}
interface BasePresenterInterface<T extends BaseViewInterface>{
void attachView(T view);
void detachView();
void setCompositeDisposable(CompositeDisposable compositeDisposable);
void addDisposable(Disposable disposable);
}
}
2. 实现类
public class BaseViewImpl implements BaseMvp.BaseViewInterface {
private Context mContext;
private BanUserDialog dialog;
private ProgressDialog mProgressDialog;
public BaseViewImpl(Context context) {
this.mContext = context;
}
@Override
public Context getContext() {
return this.mContext;
}
@Override
public void showBanUserDialog() {
if (dialog == null) {
dialog = new BanUserDialog(mContext);
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
}
if (!dialog.isShowing()) {
dialog.show();
}
}
@Override
public void dismissBanUserDialog() {
if (dialog != null) {
if (dialog.isShowing())
dialog.dismiss();
}
}
@Override
public void showLoadingDialog() {
if (mProgressDialog == null) {
mProgressDialog = ProgressDialog.show(mContext, null, "加载中...", false, true);
} else {
if (!mProgressDialog.isShowing()) {
mProgressDialog.show();
}
}
}
@Override
public void dismissLoadingDialog() {
if (mProgressDialog != null) {
if (mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
}
}
}
P:
public class BasePresenterImpl <T extends BaseMvp.BaseViewInterface> implements BaseMvp.BasePresenterInterface<T> {
protected T view;
protected CompositeDisposable mCompositeDisposable;
@Override
public void attachView(T view) {
this.view = view;
}
@Override
public void detachView() {
if( this.mCompositeDisposable!=null){
this.mCompositeDisposable.clear();
//this.mCompositeDisposable=null;
}
// this.view=null;
}
@Override
public void setCompositeDisposable(CompositeDisposable compositeDisposable) {
mCompositeDisposable=compositeDisposable;
}
@Override
public void addDisposable(Disposable disposable) {
if (mCompositeDisposable == null) {
mCompositeDisposable = new CompositeDisposable();
}
mCompositeDisposable.add(disposable);
}
}
-
Activity/Fragment的基类封装
1.Activity封装
public abstract class BaseMvpActivity<T extends BaseMvp.BasePresenterInterface> extends BaseActivity implements BaseMvp.BaseViewInterface {
protected T mPresenter;
@Override
public void initView() {
/**
* there is no mPresenter
* 不可有任何presenter 对象的引用
*/
}
@Override
protected void mvpInit() {
mPresenter = setPresenter();
if (mPresenter != null) {
mPresenter.setCompositeDisposable(mCompositeDisposable);
mPresenter.attachView(this);
} else throw new UnsupportedOperationException("must have a presenter");
}
public abstract T setPresenter();
@Override
protected void onDestroy() {
super.onDestroy();
if (mPresenter != null) {
mPresenter.detachView();
// mPresenter = null;
}
}
}
2.Fragment封装
public abstract class BaseMvpFragment <T extends BaseMvp.BasePresenterInterface> extends BaseFragment implements BaseMvp.BaseViewInterface {
protected T mPresenter;
@Override
public abstract int getLayout() ;
@Override
protected void mvpInit() {
mPresenter= setPresenter();
if (mPresenter != null) {
mPresenter.attachView(this);
mPresenter.setCompositeDisposable(mCompositeDisposable);
} else throw new UnsupportedOperationException("must have a presenter");
}
public abstract T setPresenter();
@Override
public void onDestroy() {
if (mPresenter != null) {
mPresenter.detachView();
/* mPresenter = null;*/
}
super.onDestroy();
}
}
- 实际应用中的操作(包含释义)
/**
* Created by LiJinWei on 2018/9/10 0010.
* Des:
*/
public interface ExploreInterface {
/**
* (MVP中Activity/fragment属于View ,因此要有一个View的接口,然后Activity/fragment实现View接口)
* 与View层的交互 定义功能接口
*/
interface ExploreViewInterface extends BaseMvp.BaseViewInterface {
//获得数据
void updataData(BannerBeanR bannerBeanR);
//获得轮播数据
void updatabanner(List<String> bannerImgList);
//跳转至轮播H5
void go2LunBoImgActivity(Intent intent, int realPosition);
void enterShop(EnterShopBean enterShopData);
}
/**
* ( P 中创建业务层 Presenter中定义功能,实现类PresenterImpl中操作功能/逻辑
* 在Activity/fragment中 声明初始化 p ,只能new SplashPresenter 的实现 不能new SplashPresenter接口,)
* ( P中一般要回调Activity/fragment 中的方法,所以要传入“this”,(PresenterImpl 是 Presenter的实现类)
* 在 p 中生成构造函数,xxView(因为是面向接口,生成的是xxView构造函数,而不是xxActivity构造函数))
* 与 p 层的交互 定义功能接口
*/
interface ExplorePresenterInterface extends BaseMvp.BasePresenterInterface<ExploreInterface.ExploreViewInterface> {
void clickAdvertisement(int realPosition);
void refreshLunboData();
void enterShop();
}
}
/**
* Created by LiJinWei on 2018/9/10 0010.
* Des: P层的实现类
* <p>
* (P 中创建业务层 Presenter中定义功能,实现类PresenterImpl中操作功能/逻辑
* 在Activity/fragment中 声明初始化 p ,只能new SplashPresenter 的实现 不能new SplashPresenter接口,
* <p>
* P中一般要回调Activity/fragment 中的方法,所以要传入“this”,(PresenterImpl 是 Presenter的实现类)
* 在 p 中生成构造函数,xxView(因为是面向接口,生成的是xxView构造函数,而不是xxActivity构造函数)
* Activity/fragment 中的回调方法一般都添加到View中去,而真正调用的是在PresenterImpl中,在Activity/fragment实现逻辑操作)
*/
public class ExplorePresenter extends BasePresenterImpl<ExploreViewInterface> implements ExploreInterface.ExplorePresenterInterface {
private List<BannerBeanR.BannerBean> banner;
private List<String> bannerImgList = new ArrayList<>();//轮播图图片地址集合
private BannerBeanR bannerBeanR;
private ExploreApiImpl exploreApi;
public ExplorePresenter() {
exploreApi = new ExploreApiImpl();
}
/**
* P中一般要回调Activity/fragment 中的方法,所以要传入“this”
* mPresenter= setPresenter();
* if (mPresenter != null) {
* mPresenter.attachView(this);
* mPresenter.setCompositeDisposable(mCompositeDisposable);
* } else throw new UnsupportedOperationException("must have a presenter");
*/
@Override
public void attachView(ExploreViewInterface view) {
super.attachView(view);
//获取轮播图图片
getBanner();
//商城入口
enterShop();
}
@Override
public void detachView() {
super.detachView();
}
public void enterShop() {
HashMap<String, Object> hashMap = new HashMap();
addDisposable(exploreApi.getEnterShop(hashMap)
.subscribe(new HttpNextConsumer<EnterShopBean>(view, false) {
@Override
public void accept(BaseEntity<EnterShopBean> enterShopBeanBaseEntity) throws Exception {
super.accept(enterShopBeanBaseEntity);
if (!dataIntegrity) return;
EnterShopBean enterShopData = enterShopBeanBaseEntity.data;
if (enterShopData != null) {
view.enterShop(enterShopData);
}
}
}, new HttpDefaultErrConsumer(false) {
@Override
public void accept(Throwable exception) throws Exception {
super.accept(exception);
}
}));
}
private void getBanner() {
HashMap<String, Object> hashMap = new HashMap();
hashMap.put("user_id", SPUtil.get(view.getContext(), SPUtil.USERID, ""));
hashMap.put("lon", SPUtil.get(view.getContext(), SPUtil.LON, ""));
hashMap.put("lat", SPUtil.get(view.getContext(), SPUtil.LAT, ""));
addDisposable(exploreApi.getLunboList(hashMap)
.subscribe(new HttpNextConsumer<BannerBeanR>(view, false) {
@Override
public void accept(BaseEntity<BannerBeanR> bannerBeanRBaseEntity) throws Exception {
super.accept(bannerBeanRBaseEntity);
if (!dataIntegrity) return;
bannerBeanR = bannerBeanRBaseEntity.data;
if (bannerBeanR == null)
bannerBeanR = new BannerBeanR();
//回传到View层
view.updataData(bannerBeanR);
//获取Banner
banner = bannerBeanR.banner;
if (banner != null) {
bannerImgList.clear();
for (int i = 0; i < banner.size(); i++) {
String img_url = banner.get(i).img_url;
if (StringUtils.isString(img_url)) {
bannerImgList.add(img_url);
} else {
if (i == 0) {
bannerImgList.add("default0");
} else if (i == 1) {
bannerImgList.add("default1");
} else if (i == 2) {
bannerImgList.add("default2");
} else if (i == 3) {
bannerImgList.add("default3");
} else if (i == 4) {
bannerImgList.add("default4");
}
}
}
view.updatabanner(bannerImgList);
}
}
}, new HttpDefaultErrConsumer(false) {
@Override
public void accept(Throwable exception) throws Exception {
super.accept(exception);
}
}));
}
@Override
public void clickAdvertisement(int realPosition) {
if (banner != null && banner.size() > realPosition) {
HashMap<String, Object> hashMap = new HashMap<>();
hashMap.put("id", banner.get(realPosition).id);
hashMap.put("lon", SPUtil.get(view.getContext(), SPUtil.LON, ""));
hashMap.put("lat", SPUtil.get(view.getContext(), SPUtil.LAT, ""));
addDisposable(exploreApi.clickAdvertisement(hashMap)
.subscribe(new HttpNextConsumer(view, false) {
@Override
public void accept(BaseEntity baseEntity) throws Exception {
super.accept(baseEntity);
}
}, new HttpDefaultErrConsumer(false) {
@Override
public void accept(Throwable exception) throws Exception {
super.accept(exception);
}
}));
Intent intent = new Intent(view.getContext(), LunBoImgActivity.class);
Bundle bundle = new Bundle();
String url = banner.get(realPosition).url;
if (StringUtils.isString(url)) {
bundle.putString("articleUrl", url);
} else {
if (realPosition == 0) {
bundle.putString("articleUrl", "http://www.hnhbcy.org/m/1.png");
} else if (realPosition == 1) {
bundle.putString("articleUrl", "http://www.hnhbcy.org/m/2.png");
} else if (realPosition == 2) {
bundle.putString("articleUrl", "http://www.hnhbcy.org/m/3.png");
} else if (realPosition == 3) {
bundle.putString("articleUrl", "http://www.hnhbcy.org/m/4.png");
} else if (realPosition == 4) {
bundle.putString("articleUrl", "http://www.hnhbcy.org/m/5.png");
}
}
bundle.putString("articleTitle", banner.get(realPosition).title);
bundle.putString("img", banner.get(realPosition).img_url);
intent.putExtras(bundle);
view.go2LunBoImgActivity(intent, realPosition);
}
}
@Override
public void refreshLunboData() {
getBanner();
}
/**
* Created by LiJinWei on 2018/9/10 0010.
* Des:MVP 探索
* MVP中Activity/fragment属于View ,因此要有一个View的接口,然后Activity/fragment实现View接口
* implements ExploreInterface.ExploreViewInterface
*/
public class ExploreFragment extends BaseMvpFragment<ExploreInterface.ExplorePresenterInterface> implements ExploreInterface.ExploreViewInterface {
@BindView(R.id.viewPager)
ViewPagerSlide viewPager;
@BindView(R.id.slidingTabLayout)
SlidingTabLayout slidingTabLayout;
@BindView(R.id.appBarLayout)
AppBarLayout appBarLayout;
@BindView(R.id.swipe_refresh)
VpSwipeRefreshLayout swipeRefresh;
@BindView(R.id.rcy_explore_banner)
BannerRecyclerView bannerRecyclerView;
@BindView(R.id.iv_shop)
ImageView ivShop;
private List<Object> bannerImgList = new ArrayList<>();//轮播图图片地址集合
private String[] titles = new String[]{"最新", "热门"};
private List<Fragment> fragmentList = new ArrayList<>();
private String switch_flag;
@Override
public int getLayout() {
return R.layout.fragment_new_explore1;
}
@Override
public ExploreInterface.ExplorePresenterInterface setPresenter() {
/**
* 在Activity/fragment中 声明初始化 p ,只能new SplashPresenter 的实现 不能new SplashPresenter接口,
*/
return new ExplorePresenter();
}
private BannerScaleHelper mBannerScaleHelper = null;
private CardAdapter mAdapter;
@Override
public void initView() {
initFragment();
viewPager.setAdapter(new MyFragmentPagerAdapter(getActivity().getSupportFragmentManager(), fragmentList));
slidingTabLayout.setViewPager(viewPager, titles);
viewPager.setSlide(false);//禁止左右滑动
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
bannerRecyclerView.setLayoutManager(linearLayoutManager);
mAdapter = new CardAdapter(getActivity(), bannerImgList);
bannerRecyclerView.setAdapter(mAdapter);
// mRecyclerView绑定scale效果
mBannerScaleHelper = new BannerScaleHelper();
mBannerScaleHelper.setFirstItemPos(1000);
mBannerScaleHelper.attachToRecyclerView(bannerRecyclerView);
initListener();
}
@Override
public void initData() {
}
private void initFragment() {
fragmentList.add(new NewestFragment());
fragmentList.add(new PopularFragment());
}
private void initListener() {
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
//获取轮播图图片
// getBanner();
// mPresenter.refreshLunboData();
//获取列表数据
mPresenter.enterShop();
RxBus.getDefault().send(Constant.RXBUS_CODE_UPDATA_TOP);
swipeRefresh.setRefreshing(false);
}
});
appBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout1, int verticalOffset) {
if (verticalOffset == 0) {
swipeRefresh.setEnabled(true);
} else {
swipeRefresh.setEnabled(false);
}
}
});
slidingTabLayout.setOnTabSelectListener(new OnTabSelectListener() {
@Override
public void onTabSelect(int position) {
if (position == 0) {
StatisticsHelper.addClickStatisticsEvent(ClickEventId.TS_NEW);
} else if (position == 1) {
StatisticsHelper.addClickStatisticsEvent(ClickEventId.TS_RM);
}
}
@Override
public void onTabReselect(int position) {
}
});
}
@OnClick({R.id.iv_shop})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.iv_shop:
if ("1".equals(switch_flag)) {
startActivity(new Intent(mBaseView.getContext(), ShopHomeActivity.class));
} else {
ToastUtil.showLong("商品正在更新调整,请稍后再来哦");
}
break;
}
}
@Override
public void updataData(BannerBeanR bannerBeanR) {
if (bannerBeanR.look >= 1000) {
String s = UIutils.doubleToStringPoint1(Double.valueOf(String.valueOf((bannerBeanR.look / 10000))));
// tvExploreReadNum.setText(s + "万阅读");
} else {
// tvExploreReadNum.setText(String.valueOf(bannerBeanR.look) + "阅读");
}
if (bannerBeanR.yue >= 10000) {
String s = UIutils.doubleToStringPoint1(Double.valueOf(String.valueOf((bannerBeanR.yue / 10000))));
// tvExploreZanNum.setText(s + "万人赞了你");
} else {
// tvExploreZanNum.setText(String.valueOf(bannerBeanR.yue) + "人赞了你");
}
}
@Override
public void updatabanner(List<String> mbannerImgList) {
bannerImgList.clear();
bannerImgList.addAll(mbannerImgList);
for (int i = 0; i < mbannerImgList.size(); i++) {
if ("default0".equals(bannerImgList.get(i)) && i == 0) {
bannerImgList.set(i, R.drawable.defaultbanner0);
} else if ("default1".equals(bannerImgList.get(i)) && i == 1) {
bannerImgList.set(i, R.drawable.defaultbanner1);
} else if ("default2".equals(bannerImgList.get(i)) && i == 2) {
bannerImgList.set(i, R.drawable.defaultbanner2);
} else if ("default3".equals(bannerImgList.get(i)) && i == 3) {
bannerImgList.set(i, R.drawable.defaultbanner3);
} else if ("default4".equals(bannerImgList.get(i)) && i == 4) {
bannerImgList.set(i, R.drawable.defaultbanner4);
}
}
mAdapter.notifyDataSetChanged();
mAdapter.setOnCardItemClick(new CardAdapter.OnCardItemClick() {
@Override
public void click(int position, int readPosition) {
if (mBannerScaleHelper != null) {
if (readPosition == mBannerScaleHelper.getCurrentItem()) {
mPresenter.clickAdvertisement(position);
}
}
}
});
handler.removeMessages(1);
handler.sendEmptyMessageDelayed(1, 5000);
}
@Override
public void go2LunBoImgActivity(Intent intent, int realPosition) {
startActivity(intent);
if (realPosition == 0) {
StatisticsHelper.addClickStatisticsEvent(ClickEventId.TS_LBT1);
} else if (realPosition == 1) {
StatisticsHelper.addClickStatisticsEvent(ClickEventId.TS_LBT2);
} else if (realPosition == 2) {
StatisticsHelper.addClickStatisticsEvent(ClickEventId.TS_LBT3);
} else if (realPosition == 3) {
StatisticsHelper.addClickStatisticsEvent(ClickEventId.TS_LBT4);
} else if (realPosition == 4) {
StatisticsHelper.addClickStatisticsEvent(ClickEventId.TS_LBT5);
}
}
@Override
public void enterShop(EnterShopBean enterShopData) {
switch_flag = enterShopData.getSwitch_flag();
Glide.with(mBaseView.getContext()).load(enterShopData.getUrl())
.apply(new RequestOptions().placeholder(R.drawable.defauld_img).error(R.drawable.defauld_img).centerCrop()
.diskCacheStrategy(DiskCacheStrategy.ALL)).into(ivShop);
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (swipeRefresh != null) {
if (!swipeRefresh.isRefreshing()) {
if (mBannerScaleHelper != null) {
mBannerScaleHelper.setCurrentItem(mBannerScaleHelper.getCurrentItem() + 1, true);
handler.sendEmptyMessageDelayed(1, 5000);
}
}
}
}
};
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (!hidden) {
mPresenter.enterShop();
}
}
}
这是在Fragment中的应用而Activity中与之一样就不在描述,其实本篇文章最主要的是我本人想做一下记录,与“一”做一下对比,希望多多指正