Android开发-浅谈架构(二)
写在前面的话
我记得有一期罗胖的《罗辑思维》中他提到 我们在这个碎片化 充满焦虑的时代该怎么学习--用30%的时间 了解70%该领域的知识然后迅速转移芳草鲜美的地方 像游牧民族那样。原话应该不是这样,但是我想说的是 自从我想写一些笔记记录知识的时候 为了不误导其他人 我不得不参考github 一些比较知名大牛的代码。在这个过程中 我下载过很多demo.一点一点的啃 汲取精华的部分 当然也充满疑惑。后来觉得标题取得有点大了 我应该取"学习"类的标题才对。但是另一方面我也只能就我目前的认知来记录我这个阶段的水平 也就是所谓的"浅聊"。也许你看到我github上面的demo 会说 这TM写的真垃圾。 我相信过段时间当我在github上不经意的搜到自己的demo的时候我肯定会说 “这是哪个傻逼写的代码。。。” 后来一看是我自己写的。 如果我不这么觉得 那才真是不幸。
MVP
为了学习MVP 我利用业余时间搭建了 仿照 ONE 一个 app 来练手。用到 Dagger2+RxJava+Retrofit+Databinding.细节还有待完善。
在Android开发-浅谈架构(一)中 我当时参考写了MVP fragment切换presenter.但是经过一个星期的学习 我转眼推翻了 前面的写法。这里 我觉得有必要说一下我这段时间学习其他人写的MVP模式demo. 有建议把view层当做presenter一样(github上面一个外国哥们 这里就不给记录了) 后来参考 google todoapp MVP+RxJava以及国内大牛的一些博客及时更正了github上面的代码。仿 ONE一个
下面贴出具体模块 欢迎批评和讨论。
HomeActivity 中切换fragment:
<code>
/** * tab标签页面切换*/
public class HomeActivity extends BaseActivity<HomeActBinding> implements MainTabContract.View {
/** * 绑定布局文件* @return*/
@Override
protected int getLayoutId() {
return R.layout.home_act;
}
/*** 创建Presenter*/
@Override
protected void setupView() {
new MainTabPresenter(this,this,mBinding.radio);
}
/** view 层接口*/
@NonNull
private MainTabContract.Presenter mainTabPresenter;
@Override
public void setPresenter(MainTabContract.Presenter presenter) {
mainTabPresenter = checkNotNull(presenter);
}
@Override
protected void onResume() {
super.onResume();
mainTabPresenter.subscribe();
}
@Override
protected void onPause() {
super.onPause();
mainTabPresenter.unsubscribe();
}
@Override
protected void onDestroy() {
super.onDestroy();
mainTabPresenter.unsubscribe();
}
/*** 返回处理 */
private long beforeTime = 0L;
@Override
public void onBackPressed() {// thanks.==> by JohnTsai(mailto:johntsai.work@gmail.com) on 16/7/27.
if(System.currentTimeMillis()-beforeTime<1000L) {
finish();
super.onBackPressed();
}else{
beforeTime = System.currentTimeMillis();
Toast.makeText(this, "再按一次退出一个", Toast.LENGTH_SHORT).show();
}
}
}
</code>
MainTabPresenter
<code>
public class MainTabPresenter implements MainTabContract.Presenter {
@NonNull
private final RadioGroup radioGroup;
@NonNull
private final MainTabContract.View mMainTabContractView;
@NonNull
private final FragmentActivity mContext;
@NonNull
private CompositeSubscription mSubscriptions;
public MainTabPresenter(@NonNull FragmentActivity mActivity, @NonNull MainTabContract.View view,@NonNull RadioGroup group) {//
mContext = checkNotNull(mActivity, "FragmentActivity cannot be null!");
mMainTabContractView = checkNotNull(view);
radioGroup = checkNotNull(group, "RadioGroup cannot be null!");
mSubscriptions = new CompositeSubscription();
mMainTabContractView.setPresenter(this);
}
private void switchTo() {
FragmentUtils fragmentUtil = new FragmentUtils(mContext, R.id.view_container);
Subscription subscription = RxRadioGroup.checkedChanges(radioGroup).subscribe(integer -> {
fragmentUtil.switchTo(switchTo(integer));
});
mSubscriptions.add(subscription);
}
private Class switchTo(@IdRes Integer i) {
Integer integer = checkNotNull(i, "switchTo IdRes cannot be null");
switch (integer) {
case R.id.home_one:
return OneFragment.class;
case R.id.home_reading:
return ReadingFragment.class;
case R.id.home_music:
return MusicFragment.class;
case R.id.home_movie:
return MovieFragment.class;
default:
break;
}
return null;
}
@Override
public void subscribe() {
switchTo();
}
@Override
public void unsubscribe() {
mSubscriptions.clear();
}
}
</code>
OneFragment 中请求首页数据
<code>
/*** 一个 首页* */
public class OneFragment extends BaseFragment<MainFragmentOneBinding> implements ViewPagerContract.View{
@NonNull
private ViewPagerContract.Presenter mPresenter;
@Override
protected int getLayoutId() {
return R.layout.main_fragment_one;
}
@Override
protected void setupView() {
new ViewPagerPresenter(getActivity(),this);
}
@Override
public void setPagerAdapter(@NonNull OneFragmentAdapter oneFragmentAdapter) {
inflate.viewPager.setAdapter(checkNotNull(oneFragmentAdapter));
}
@Override
public void onResume() {
super.onResume();
mPresenter.subscribe();
}
@Override
public void onPause() {
super.onPause();
mPresenter.unsubscribe();
}
@Override
public void setPresenter(ViewPagerContract.Presenter presenter) {
mPresenter = checkNotNull(presenter);
}
}
</code>
ViewPagerPresenter
<code>
public class ViewPagerPresenter implements ViewPagerContract.Presenter {
@NonNull
private final CompositeSubscription mSubscriptions;
@NonNull
private final ViewPagerContract.View mViewPagerContractView;
@NonNull
private final ApiInteractor api;
@Nullable
private final FragmentActivity mActivity;
public ViewPagerPresenter(@NonNull FragmentActivity context, @NonNull ViewPagerContract.View mView){
mActivity = checkNotNull(context);
api = checkNotNull(App.getAppComponent().getApiInteractor());
mViewPagerContractView = checkNotNull(mView);
mSubscriptions = new CompositeSubscription();
mViewPagerContractView.setPresenter(this);
}
@Override
public void subscribe() {
Subscription apiOneHome = api.getOneHome(ConstantApi.OneFragmentApi, new BaseSubscribe<String>() {
@Override
public void onSuccess(String result) {
Log.d("首页接口", "onSuccess: " + result);
if(result!=null){
OneFragmentEntity entity = new Gson().fromJson(result, OneFragmentEntity.class);
mViewPagerContractView.setPagerAdapter(new OneFragmentAdapter(mActivity,entity.getData()));
}
}
});
mSubscriptions.add(apiOneHome);
}
@Override
public void unsubscribe() {
mSubscriptions.clear();
}
}
</code>
最后
这里也有人说接口请求数据不应该写在Presenter里面。。。总之 好的架构一定是:1 适合自己的项目 2 多写注释文档 3 业务逻辑分包 4 不断学习。
欢迎加群:
QQ 群 521039620
原文博客地址