1,其实早就想把这些东西给封装封装的,一直没有时间,今天刚好项目进入到测试阶段了,Bug同事在哪儿测试的飞起,但发现提bug的尽然是我(得意脸),然后上午把ios的包测试了一下,顺便把服务器给测挂了(别问我是怎么做到的),现在服务器的同事还在拿着刀满街找我呐。好了不扯了,就想标题写了,一直想把这一块揉在一起写写,那就趁这个机会吧。

先看看今天我们要实现的效果:

2,有些童鞋就很气愤了,麻蛋,裤子都脱了,你给我看这个!!!!

   其实我也想多写点的啊,还想把App下载写上呢,没事,我们慢慢一点点的来,,先来看一下我们接口的数据吧

  1. {
  2. "code": 200,
  3. "message": "",
  4. "data": {
  5. "code": "1.1.0",
  6. "size": "8.6M",
  7. "des": "1.【新增】自动更新\\r\\n2.【修改】部分ProgressBar替换为SVG\\r\\n3.【修改】Gank板块部分改动\\r\\n"
  8. }
  9. }

  可以看到,这是一个标准的接口数据,外部包含 code、message、data三大门神,这样我们封装Response就很好解决了。

  看一下我们的BaseResponse类,很简单,没有什么讲的

  BaseResponse.java

  1. package com.qianmo.myview2.response;
  2.  
  3. /**
  4. * Created by wangjitao on 2016/11/8 0008.
  5. * 数据返回类类
  6. */
  7. public class BaseResponse<T> {
  8. private int code;
  9. private String message;
  10. private T data;
  11.  
  12. public T getData() {
  13. return data;
  14. }
  15.  
  16. public void setData(T data) {
  17. this.data = data;
  18. }
  19.  
  20. public String getMessage() {
  21. return message;
  22. }
  23.  
  24. public void setMessage(String message) {
  25. this.message = message;
  26. }
  27.  
  28. public int getCode() {
  29. return code;
  30. }
  31.  
  32. public void setCode(int code) {
  33. this.code = code;
  34. }
  35. }

  再看一下我们这次的功能,就是一个简单的网络请求,判断当前app版本和服务器上的版本,从而判断是否是最新的,看到这里的同学可能就很疑惑了,麻蛋,不是说好了是封装封装嘛,为什么到现在还在说功能,嗯,阿呆哥哥只是想从本质上对比一下如果我们使用传统的MVC去写的话该是怎么写的啊,相信现在很多同学已经在脑海中已经有了代码了,不过我猜你们的Activity中的代码会很多(奸笑脸),好吧,我前面的博客也介绍了MVP模式,现在我们是要把MVP运用在项目里面,所以,我们就要开始封装基类了!!

3 ,封装

①BaseView

我们知道在MVP模式中我们的V是和我们用户界面的UI有关的,不管是控件的隐藏和显示,还是控件大小的改变都是我们的V来处理的,所以这里我们只是写了个简单的夜间模式的UI改变的方法、还有展示错误信息的方法,很简单

  1. package com.qianmo.myview2.base;
  2.  
  3. import android.view.View;
  4.  
  5. /**
  6. * Created by wangjitao on 2016/11/8 0008.
  7. * 一般的Activity中要用到View操作无非是显示加载框、影藏加载框、显示出错信息、显示当数据为空的时候的view之类的
  8. */
  9. public interface BaseView {
  10.  
  11. void showError(String msg);
  12.  
  13. void useNightMode(boolean isNight);
  14.  
  15. }

  

②BasePresenter

P在MVP架构中是主要用于逻辑处理的,所以一是我们最经常要写的,看一下代码,就是AttachView和DetachView(这也没什么好解释的)

  1. package com.qianmo.myview2.base;
  2.  
  3. /**
  4. * Created by wangjitao on 2016/11/8 0008.
  5. * MVP框架的简单封装 P处理层
  6. */
  7. public interface BasePresenter<T extends BaseView> {
  8.  
  9. void attachView(T view);
  10.  
  11. void detachView();
  12. }

③App

这个类一般用于初始化一些数据,如屏幕的信息之类的和Activity的简单的管理啊,还有一些第三方SDK的初始化

  1. package com.qianmo.myview2;
  2.  
  3. import android.app.Activity;
  4. import android.app.Application;
  5. import android.content.Context;
  6. import android.util.DisplayMetrics;
  7. import android.view.Display;
  8. import android.view.WindowManager;
  9.  
  10. import java.util.HashSet;
  11. import java.util.Set;
  12.  
  13. /**
  14. * Created by wangjitao on 2016/11/8 0008.
  15. */
  16. public class App extends Application {
  17.  
  18. private static App instance;
  19. private Set<Activity> allActivities;
  20.  
  21. public static int SCREEN_WIDTH = -1;
  22. public static int SCREEN_HEIGHT = -1;
  23. public static float DIMEN_RATE = -1.0F;
  24. public static int DIMEN_DPI = -1;
  25.  
  26. public static synchronized App getInstance() {
  27. return instance;
  28. }
  29.  
  30. @Override
  31. public void onCreate() {
  32. super.onCreate();
  33.  
  34. instance = this;
  35.  
  36. getScreenSize();
  37. }
  38.  
  39. /**
  40. * 初始化屏幕宽高
  41. */
  42. public void getScreenSize() {
  43. WindowManager windowManager = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
  44. DisplayMetrics dm = new DisplayMetrics();
  45. Display display = windowManager.getDefaultDisplay();
  46. display.getMetrics(dm);
  47. DIMEN_RATE = dm.density / 1.0F;
  48. DIMEN_DPI = dm.densityDpi;
  49. SCREEN_WIDTH = dm.widthPixels;
  50. SCREEN_HEIGHT = dm.heightPixels;
  51. if (SCREEN_WIDTH > SCREEN_HEIGHT) {
  52. int t = SCREEN_HEIGHT;
  53. SCREEN_HEIGHT = SCREEN_WIDTH;
  54. SCREEN_WIDTH = t;
  55. }
  56. }
  57.  
  58. /**
  59. * 添加activity
  60. */
  61. public void addActivity(Activity act) {
  62. if (allActivities == null) {
  63. allActivities = new HashSet<>();
  64. }
  65. allActivities.add(act);
  66. }
  67.  
  68. /**
  69. * 移除activity
  70. */
  71. public void removeActivity(Activity act) {
  72. if (allActivities != null) {
  73. allActivities.remove(act);
  74. }
  75. }
  76.  
  77. /**
  78. * 退出app
  79. */
  80. public void exitApp() {
  81. if (allActivities != null) {
  82. synchronized (allActivities) {
  83. for (Activity act : allActivities) {
  84. act.finish();
  85. }
  86. }
  87. }
  88. android.os.Process.killProcess(android.os.Process.myPid());
  89. System.exit(0);
  90. }
  91.  
  92. /**
  93. * 这还有一系列的第三方SDK的初始化
  94. */
  95. }

④BaseActivity

这个貌似是最重要的,这里我们考虑到5.0一下的机器切换Activity比较丑,所以写了下切换的动画,,然后就是一系列的初始化,直接贴出来吧

  1. package com.qianmo.myview2.base;
  2.  
  3. import android.app.Activity;
  4. import android.os.Bundle;
  5. import android.support.annotation.Nullable;
  6. import android.support.v7.app.AppCompatActivity;
  7. import android.support.v7.widget.Toolbar;
  8. import android.view.View;
  9.  
  10. import com.qianmo.myview2.App;
  11. import com.qianmo.myview2.R;
  12.  
  13. import butterknife.Unbinder;
  14. import butterknife.ButterKnife;
  15.  
  16. /**
  17. * Created by wangjitao on 2016/11/8 0008.
  18. * 基类Activity的封装
  19. * 一般使用mvp模式的话会在BaseActivity中进行P和V的初始化绑定
  20. */
  21. public abstract class BaseActivity<T extends BasePresenter> extends AppCompatActivity implements BaseView {
  22. protected T mPresenter;
  23. protected Activity mContext;
  24. private Unbinder mUnbinder;
  25.  
  26. public enum TransitionMode {
  27. LEFT, RIGHT, TOP, BOTTOM, SCALE, FADE
  28. }
  29.  
  30. protected void onCreate(@Nullable Bundle savedInstanceState) {
  31. if (toggleOverridePendingTransition()) {
  32. switch (getOverridePendingTransitionMode()) {
  33. case LEFT:
  34. overridePendingTransition(R.anim.left_in, R.anim.left_out);
  35. break;
  36. case RIGHT:
  37. overridePendingTransition(R.anim.right_in, R.anim.right_out);
  38. break;
  39. case TOP:
  40. overridePendingTransition(R.anim.top_in, R.anim.top_out);
  41. break;
  42. case BOTTOM:
  43. overridePendingTransition(R.anim.bottom_in, R.anim.bottom_out);
  44. break;
  45. case SCALE:
  46. overridePendingTransition(R.anim.scale_in, R.anim.scale_out);
  47. break;
  48. case FADE:
  49. overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
  50. break;
  51. }
  52. }
  53.  
  54. super.onCreate(savedInstanceState);
  55. setContentView(getLayout());
  56.  
  57. mUnbinder = ButterKnife.bind(this);
  58. mContext = this;
  59.  
  60. createPresenter();
  61.  
  62. if (mPresenter != null)
  63. mPresenter.attachView(this);
  64. App.getInstance().addActivity(this);
  65. initEventAndData();
  66. }
  67.  
  68. @Override
  69. protected void onStart() {
  70. super.onStart();
  71.  
  72. }
  73.  
  74. @Override
  75. protected void onDestroy() {
  76. super.onDestroy();
  77. if (mPresenter != null)
  78. mPresenter.detachView();
  79. mUnbinder.unbind();
  80. App.getInstance().removeActivity(this);
  81. }
  82.  
  83. protected void setToolBar(Toolbar toolbar, String title) {
  84. toolbar.setTitle(title);
  85. setSupportActionBar(toolbar);
  86. getSupportActionBar().setDisplayHomeAsUpEnabled(true);
  87. getSupportActionBar().setDisplayShowHomeEnabled(true);
  88. toolbar.setNavigationOnClickListener(new View.OnClickListener() {
  89. @Override
  90. public void onClick(View view) {
  91. onBackPressed();
  92. }
  93. });
  94. }
  95.  
  96. protected abstract int getLayout();
  97.  
  98. protected abstract void initEventAndData();
  99.  
  100. protected abstract boolean toggleOverridePendingTransition();
  101.  
  102. protected abstract TransitionMode getOverridePendingTransitionMode();
  103.  
  104. protected abstract void createPresenter();
  105. }

⑤ BaseRecyclerViewAdapter

  1. package com.qianmo.myview2.base;
  2.  
  3. import android.content.Context;
  4. import android.support.v7.widget.RecyclerView;
  5. import android.view.LayoutInflater;
  6. import android.view.View;
  7. import android.view.ViewGroup;
  8.  
  9. import com.balysv.materialripple.MaterialRippleLayout;
  10. import com.qianmo.myview2.R;
  11.  
  12. import java.util.List;
  13.  
  14. /**
  15. * Created by wangjitao on 2016/11/7 0007.
  16. * 对简单的recycleview进行简单的封装
  17. */
  18. public abstract class BaseRecyclerViewAdapter<T> extends RecyclerView.Adapter<BaseViewHolder> {
  19. private Context context;
  20. private LayoutInflater inflater;
  21. private List<T> datas;
  22. private int layoutId;
  23. protected OnItemClickListner onItemClickListner;//单击事件
  24. protected OnItemLongClickListner onItemLongClickListner;//长按单击事件
  25. private boolean clickFlag = true;//单击事件和长单击事件的屏蔽标识
  26.  
  27. public BaseRecyclerViewAdapter(Context context, List<T> datas, int layoutId) {
  28. this.context = context;
  29. this.datas = datas;
  30. this.layoutId = layoutId;
  31. this.inflater = LayoutInflater.from(context);
  32. }
  33.  
  34. @Override
  35. public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  36. BaseViewHolder holder = new BaseViewHolder(inflater.inflate(layoutId, parent, false));
  37. MaterialRippleLayout.on(holder.getView(R.id.ll_all))
  38. .rippleOverlay(true)
  39. .rippleAlpha(0.2f)
  40. .rippleColor(context.getResources().getColor(R.color.colorAccent))
  41. .rippleHover(true)
  42. .create();
  43. return holder;
  44. }
  45.  
  46. @Override
  47. public void onBindViewHolder(BaseViewHolder holder, int position) {
  48. bindData(holder, datas.get(position), position);
  49. }
  50.  
  51. @Override
  52. public int getItemCount() {
  53. return datas == null ? 0 : datas.size();
  54. }
  55.  
  56. protected abstract void bindData(BaseViewHolder holder, T data, int position);
  57.  
  58. public void setOnItemClickListner(OnItemClickListner onItemClickListner) {
  59. this.onItemClickListner = onItemClickListner;
  60. }
  61.  
  62. public void setOnItemLongClickListner(OnItemLongClickListner onItemLongClickListner) {
  63. this.onItemLongClickListner = onItemLongClickListner;
  64. }
  65.  
  66. public interface OnItemClickListner {
  67. void onItemClickListner(View v, int position);
  68. }
  69.  
  70. public interface OnItemLongClickListner {
  71. void onItemLongClickListner(View v, int position);
  72. }
  73. }

⑥ BaseViewHolder

  1. package com.qianmo.myview2.base;
  2.  
  3. import android.support.v7.widget.RecyclerView;
  4. import android.util.SparseArray;
  5. import android.view.View;
  6.  
  7. /**
  8. * Created by wangjitao on 2016/11/7 0007.
  9. * 万能的Viewholder
  10. */
  11. public class BaseViewHolder extends RecyclerView.ViewHolder {
  12.  
  13. private SparseArray<View> views;
  14.  
  15. public BaseViewHolder(View view) {
  16. super(view);
  17. this.views = new SparseArray<>();
  18. }
  19.  
  20. public <T extends View> T getView(int viewId) {
  21. View view = views.get(viewId);
  22. if (view == null) {
  23. view = itemView.findViewById(viewId);
  24. views.put(viewId, view);
  25. }
  26. return (T) view;
  27. }
  28.  
  29. public View getRootView() {
  30. return itemView;
  31. }
  32. }

由于上一篇介绍了怎么封装RecycleView的Adapter,在这里就不在废话了  

4,好了东西都封装好了,看一下我们在实际功能中怎么写吧,由于我们上面的功能,我们要实现一个简单的版本判断,由于要使用网络,这里我打算使用Retrofit+RxJava,但是还没有封装好,就直接拿没封装的直接用了,这里创建mvp模式的话要创建好多个接口啊 ,所以推荐是用MVPHelper这个插件,挺好用的  ,好了,先看一下我们的MainContract

  1. package com.qianmo.myview2.contract;
  2.  
  3. import com.qianmo.myview2.base.BasePresenter;
  4. import com.qianmo.myview2.base.BaseView;
  5. import com.qianmo.myview2.bean.VersionBean;
  6.  
  7. /**
  8. * Created by wangjitao on 2016/11/8 0008.
  9. * 首页逻辑处理
  10. */
  11. public class MainContract {
  12.  
  13. public interface View extends BaseView {
  14. //View效果就是展示下载进度框
  15. void showUpdateDialog(VersionBean bean);
  16.  
  17. void showProgressDialog();
  18.  
  19. void DissProgressDialog();
  20.  
  21. void ShowToast(String message);
  22. }
  23.  
  24. public interface Presenter extends BasePresenter<View> {
  25. //一般在首页我们会进行一个版本的更新(功能)
  26. void checkVersion(String currentVersion);
  27. }
  28.  
  29. }

就只是接口的常见,并把这次功能要用到的方法全部抽象出来,

看一下我们Presenter的实现类

MainPresenterImpl.java

  1. package com.qianmo.myview2.presenter;
  2.  
  3. import android.widget.Toast;
  4.  
  5. import com.qianmo.myview2.CheckVersionActivity;
  6. import com.qianmo.myview2.MainActivity;
  7. import com.qianmo.myview2.api.AppVersionService;
  8. import com.qianmo.myview2.bean.VersionBean;
  9. import com.qianmo.myview2.contract.MainContract;
  10. import com.qianmo.myview2.response.BaseResponse;
  11. import com.qianmo.myview2.utils.Constant;
  12.  
  13. import retrofit2.Retrofit;
  14. import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
  15. import retrofit2.converter.gson.GsonConverterFactory;
  16. import rx.Subscriber;
  17. import rx.android.schedulers.AndroidSchedulers;
  18. import rx.schedulers.Schedulers;
  19.  
  20. /**
  21. * Created by MVPHelper on 2016/11/08
  22. */
  23.  
  24. public class MainPresenterImpl implements MainContract.Presenter {
  25.  
  26. private MainContract.View mView;
  27.  
  28. @Override
  29. public void checkVersion(final String currentVersion) {
  30. Retrofit retrofit = new Retrofit.Builder()
  31. .baseUrl(Constant.BASE_URL)
  32. .addConverterFactory(GsonConverterFactory.create())
  33. .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
  34. .build();
  35. AppVersionService movieService = retrofit.create(AppVersionService.class);
  36.  
  37. movieService.getVersion()
  38. .subscribeOn(Schedulers.io())
  39. .observeOn(AndroidSchedulers.mainThread())
  40. .subscribe(new Subscriber<BaseResponse<VersionBean>>() {
  41. @Override
  42. public void onStart() {
  43. mView.showProgressDialog();
  44. }
  45.  
  46. @Override
  47. public void onCompleted() {
  48. mView.DissProgressDialog();
  49. }
  50.  
  51. @Override
  52. public void onError(Throwable e) {
  53. mView.DissProgressDialog();
  54. mView.ShowToast("请求出错");
  55. }
  56.  
  57. @Override
  58. public void onNext(BaseResponse<VersionBean> versionBeanBaseResponse) {
  59. if (Integer.valueOf(currentVersion.replace(".", "")) < Integer.valueOf(versionBeanBaseResponse.getData().getCode().replace(".", ""))) {
  60. // mView.showUpdateDialog(versionBean);
  61. //这里表示发现新版本
  62. mView.ShowToast("发现最新版本");
  63. } else {
  64. //表示这就是最新版本
  65. mView.ShowToast("已经是最新版本");
  66. }
  67. }
  68. });
  69. }
  70.  
  71. @Override
  72. public void attachView(MainContract.View view) {
  73. mView = view;
  74. }
  75.  
  76. @Override
  77. public void detachView() {
  78. mView = null;
  79. }
  80.  
  81. }

没有什么好讲解的,其实还可以把presenter层封装一下的,可以在封装成这样的

  1. public class BasePresenter<T extends MvpView> implements Presenter<T> {
  2.  
  3. private T mMvpView;
  4.  
  5. @Override
  6. public void attachView(T mvpView) {
  7. mMvpView = mvpView;
  8. }
  9.  
  10. @Override
  11. public void detachView() {
  12. mMvpView = null;
  13. }
  14.  
  15. public boolean isViewAttached() {
  16. return mMvpView != null;
  17. }
  18.  
  19. public T getMvpView() {
  20. return mMvpView;
  21. }
  22.  
  23. public void checkViewAttached() {
  24. if (!isViewAttached()) throw new MvpViewNotAttachedException();
  25. }
  26.  
  27. public static class MvpViewNotAttachedException extends RuntimeException {
  28. public MvpViewNotAttachedException() {
  29. super("Please call Presenter.attachView(MvpView) before" +
  30. " requesting data to the Presenter");
  31. }
  32. }
  33. }

  ok,最后看一下我们的Activity

  1. package com.qianmo.myview2;
  2.  
  3. import android.content.pm.PackageInfo;
  4. import android.content.pm.PackageManager;
  5. import android.os.Bundle;
  6. import android.view.View;
  7. import android.widget.Button;
  8. import android.widget.ProgressBar;
  9. import android.widget.Toast;
  10.  
  11. import com.qianmo.myview2.base.BaseActivity;
  12. import com.qianmo.myview2.bean.VersionBean;
  13. import com.qianmo.myview2.contract.MainContract;
  14. import com.qianmo.myview2.presenter.MainPresenterImpl;
  15.  
  16. import butterknife.BindView;
  17.  
  18. public class CheckVersionActivity extends BaseActivity<MainPresenterImpl> implements MainContract.View, View.OnClickListener {
  19. @BindView(R.id.btn_getVersion)
  20. Button btnGetVersion;
  21. @BindView(R.id.progressBar)
  22. ProgressBar progressBar;
  23.  
  24. @Override
  25. protected void onCreate(Bundle savedInstanceState) {
  26. super.onCreate(savedInstanceState);
  27. }
  28.  
  29. @Override
  30. protected int getLayout() {
  31. return R.layout.activity_main;
  32. }
  33.  
  34. @Override
  35. protected void initEventAndData() {
  36. btnGetVersion.setOnClickListener(this);
  37.  
  38. }
  39.  
  40. @Override
  41. protected boolean toggleOverridePendingTransition() {
  42. return false;
  43. }
  44.  
  45. @Override
  46. protected TransitionMode getOverridePendingTransitionMode() {
  47. return null;
  48. }
  49.  
  50. @Override
  51. protected void createPresenter() {
  52. mPresenter = new MainPresenterImpl();
  53. }
  54.  
  55. @Override
  56. public void showError(String msg) {
  57.  
  58. }
  59.  
  60. @Override
  61. public void useNightMode(boolean isNight) {
  62.  
  63. }
  64.  
  65. @Override
  66. public void showUpdateDialog(VersionBean bean) {
  67.  
  68. }
  69.  
  70. @Override
  71. public void showProgressDialog() {
  72. progressBar.setVisibility(View.VISIBLE);
  73. }
  74.  
  75. @Override
  76. public void DissProgressDialog() {
  77. progressBar.setVisibility(View.GONE);
  78. }
  79.  
  80. @Override
  81. public void ShowToast(String message) {
  82. Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
  83. }
  84.  
  85. @Override
  86. public void onClick(View view) {
  87. try {
  88. PackageManager pm = getPackageManager();
  89. PackageInfo pi = pm.getPackageInfo(getPackageName(), PackageManager.GET_ACTIVITIES);
  90. String versionName = pi.versionName;
  91. mPresenter.checkVersion(versionName);
  92. } catch (PackageManager.NameNotFoundException e) {
  93. e.printStackTrace();
  94. }
  95. }
  96. }

  再贴一下布局文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="#ffffff"
  6. >
  7.  
  8. <include
  9. android:id="@+id/toolbar"
  10. layout="@layout/view_toolbar"/>
  11.  
  12. <android.support.v7.widget.RecyclerView
  13. android:id="@+id/recycleView"
  14. android:layout_width="match_parent"
  15. android:layout_height="match_parent"
  16. android:layout_below="@+id/toolbar"
  17. android:visibility="gone"
  18. >
  19.  
  20. </android.support.v7.widget.RecyclerView>
  21.  
  22. <Button
  23. android:id="@+id/btn_getVersion"
  24. android:layout_width="wrap_content"
  25. android:layout_height="wrap_content"
  26. android:layout_centerHorizontal="true"
  27. android:layout_marginTop="400dp"
  28. android:text="检查版本"
  29. />
  30.  
  31. <ProgressBar
  32. android:id="@+id/progressBar"
  33. android:layout_width="wrap_content"
  34. android:layout_height="wrap_content"
  35. android:layout_centerInParent="true"
  36. android:visibility="gone"
  37. />
  38. </RelativeLayout>

  build.gradle

  1. apply plugin: 'com.android.application'
  2. apply plugin: 'com.neenbedankt.android-apt'
  3. android {
  4. compileSdkVersion 25
  5. buildToolsVersion "25.0.0"
  6.  
  7. defaultConfig {
  8. applicationId "com.qianmo.myview2"
  9. minSdkVersion 15
  10. targetSdkVersion 25
  11. versionCode 1
  12. versionName "1.0"
  13. }
  14. buildTypes {
  15. release {
  16. minifyEnabled false
  17. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  18. }
  19. }
  20. }
  21.  
  22. dependencies {
  23. compile fileTree(dir: 'libs', include: ['*.jar'])
  24. testCompile 'junit:junit:4.12'
  25. compile 'com.android.support:appcompat-v7:25.0.0'
  26. compile 'com.android.support:design:25.+'
  27. compile 'com.android.support:recyclerview-v7:25.+'
  28. compile 'com.android.support:cardview-v7:25.+'
  29. compile 'com.balysv:material-ripple:1.0.2'
  30. compile 'com.jakewharton:butterknife:8.2.1'
  31. apt 'com.jakewharton:butterknife-compiler:8.2.1'
  32. compile 'io.reactivex:rxjava:1.1.0'
  33. compile 'io.reactivex:rxandroid:1.1.0'
  34. compile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
  35. compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
  36. compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'
  37. compile 'com.google.code.gson:gson:2.6.2'
  38. }

  好了,这样我们就把MVP简单的封装了,有没有很简单啊,下一篇接着封装Retrofit+Rxjava+Dagger。

see you next time·······

Android--带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava(一)的更多相关文章

  1. Android--带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava(二)

    1,昨天我们基本上把MVP给封装起来了,今天接着昨天的东西来结合RxJava把Retrofit把网络框架简单的封装一下,先看一下我们今天实现的效果: 哈哈 ,还是昨天的效果,好吧 ,我认错. 2,由于 ...

  2. Android--带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava(三)

    1,这一篇博客是和大家一起来封装我们最后的Dagger2,其实之前也写过关于简单的Dagger2,这里是地址,完全没了解的同学可以先去看一下这篇,感谢很多小伙伴一直在耐心的等待这一篇 2,Dagger ...

  3. Android App的设计架构:MVC,MVP,MVVM与架构经验谈

    相关:http://www.cnblogs.com/wytiger/p/5996876.html 和MVC框架模式一样,Model模型处理数据代码不变在Android的App开发中,很多人经常会头疼于 ...

  4. Android App的设计架构:MVC,MVP,MVVM与架构AAAAA

    1. 架构设计的目的1.1 通过设计使程序模块化,做到模块内部的高聚合和模块之间的低耦合.1.2 这样做的好处是使得程序在开发的过程中,开发人员只需要专注于一点,提高程序开发的效率,并且更容易进行后续 ...

  5. Android -- 带你从源码角度领悟Dagger2入门到放弃(二)

    1,接着我们上一篇继续介绍,在上一篇我们介绍了简单的@Inject和@Component的结合使用,现在我们继续以老师和学生的例子,我们知道学生上课的时候都会有书籍来辅助听课,先来看看我们之前的Stu ...

  6. okhttputils【 Android 一个改善的okHttp封装库】使用(一)

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本文使用的OKHttp封装库是张鸿洋(鸿神)写的,因为在项目中一直使用这个库,所以对于一些常用的请求方式都验证过,所以特此整理下. ...

  7. okhttputils【 Android 一个改善的okHttp封装库】使用(三)

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这一篇主要讲一下将OkHttpUtils运用到mvp模式中. 数据请求地址:http://www.wanandroid.com/to ...

  8. Android二维码识别 开源项目ZXing的编译

    Android二维码识别 开源项目ZXing的编译 Android端的条形码/二维码识别功能 因为手机端的输入不是很方便,所以条形码/二维码的扫描是一种很有效的解决手段. 比较流行的手机应用中,常用的 ...

  9. Android -- 带你从源码角度领悟Dagger2入门到放弃

    1,以前的博客也写了两篇关于Dagger2,但是感觉自己使用的时候还是云里雾里的,更不谈各位来看博客的同学了,所以今天打算和大家再一次的入坑试试,最后一次了,保证最后一次了. 2,接入项目 在项目的G ...

随机推荐

  1. 解决 卸载Mysql后,服务还在的问题

    HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Eventlog\Application\MySQL文件夹:删除HKEY_LOCAL_MACHINE\ ...

  2. include、require、include_once和require_once理解

    都是在当前文件中包含引入并运行指定文件,include和require的不通之处仅仅在于发生错误时include产生一个警告脚本继续执行,而require产生一个致命的错误,脚本停止运行.有了once ...

  3. USACO翻译:USACO 2014 JAN三题(2)

    USACO 2014 JAN 一.题目概览 中文题目名称 队伍平衡 滑雪录像 滑雪场建设 英文题目名称 bteams recording skicourse 可执行文件名 bteams recordi ...

  4. Zxing库

    一.介绍 Zxing是一个开放的源码,用java实现的多种样式的1D/2D条码处理库,它包含了联系到其他语言的端口.Zxing可以实现手机的内置摄像头完成条码的扫描及解码.目前支持:UPC-A ,UP ...

  5. Yii源码阅读笔记(三十一)

    Widget类中开始,获取视图对象,获取widget ID,渲染视图,获取路径方法注释: private $_id; /** * Returns the ID of the widget. * 返回插 ...

  6. 算法系列(1):Google方程式

    有一个字符组成的等式:WWWDOT – GOOGLE = DOTCOM,每个字符代表一个0-9之间的数字,WWWDOT.GOOGLE和DOTCOM都是合法的数字,不能以0开头.请找出一组字符和数字的对 ...

  7. python学习道路(day7note)(subprocess模块,面向对象)

    1.subprocess模块   因为方法较多我就写在code里面了,后面有注释 #!/usr/bin/env python #_*_coding:utf-8_*_ #linux 上调用python脚 ...

  8. OpenGL函数思考-glLoadIdentity

    函数原型: void glLoadIdentity(void) 函数说明: OpenGL为我们提供了一个非常简单的恢复初始坐标系的手段,那就是调用glLoadIdentity()命令.该命令是一个无参 ...

  9. Xamarin.Android 应用程序配置

    * 在 Xamarin 中 Android 清单文件的内容一般不通过手动编辑,而是由编译器根据 项目属性设置 和 一系列 特性类 自动生成 1. 应用程序在android启动器中显示的名称设置: 主活 ...

  10. 带你玩转JavaWeb开发之六-mysql基本语法详解及实例(3)

    [语法] update 表名 set 列名=列值,列名=列值 -[条件]; [注意事项] * 修改的列的值需要与列的类型一致. * 修改的列的值的长度不能超过列的类型的最大长度. * 字符串类型和日期 ...