开源项目GankIo 仿写(MVP+Retrofit+butterKnife + MaterialDesign)
2017-04-11 16:00
495 查看
前言
最近在一论坛发现一个不错的开源项目本着学习的目的。就比这原著仿写了一遍。在此先感谢原著。
修改:
1,项目相比原著 结构更加清晰,对mvp的 vp的 关联进行了拆分。更适合初级学习者学习。2,使用了沉浸式状态栏。使得app更加一体化。
上图:
项目 目录结构:
项目介绍:
1,主要类:retrofit使用:
ApiService.java:
public class ApiService { private static GankApiServerMethod sGankApi; //初始化 Retrofit 请求 public static void init() { // TODO ------------------------------- Retrofit sRetrofit = new Retrofit.Builder() .baseUrl(Constant.URL) .addConverterFactory(GsonConverterFactory.create()) .addConverterFactory(ScalarsConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); sGankApi = sRetrofit.create(GankApiServerMethod.class); } public static GankApiServerMethod getGankApi() { return sGankApi; } }
GankApiServerMethod.java 封装retrofit的 请求方法:
/** * Package_name:com.hero.zhaoq.mygankiodemo * Author:zhaoqiang * Email:zhaoq_hero@163.com * Date:2017/04/05 13/54 */ public interface GankApiServerMethod { @GET("day/{date}") Observable<GankInfo<DayInfo>> getDayGank(@Path("date") String date); /** * 获取发布干货的日期 * @return */ @GET("day/history") Observable<GankInfo<List<String>>> getPublishDays(); /** * 获取分类数据 * @param type 数据类型: 福利 | Android | iOS | 休息视频 | 拓展资源 | 前端 | all * @param count 请求个数: 数字,大于0 * @param page 第几页:数字,大于0 * @return */ @GET("data/{type}/{count}/{page}") Observable<GankInfo<List<DataInfo>>> getData(@Path("type") String type, @Path("count") int count, @Path("page") int page); }
MVP使用: 原著将vp放到了一起 不变学习 我便拆开了。
MainPresenter.java:
public class MainPresenter implements ImainPres { private ImainView mView;//TODO 持有 View的 引用 private String[] mTitles; private List<Fragment> mFragmentList; //TODO 实现 view 和 presenter的交互: public MainPresenter(ImainView imainView) { this.mView = imainView; } @Override public void requestData(Intent intent) { //TODO 请求 数据 mTitles = StringUtils.getStringArray(R.array.tab_str_arr); initFragmentList();//TODO } /** * 初始化 fragment */ private void initFragmentList() { mFragmentList = new ArrayList<>(); // mFragmentList.add(DayPushFragment.newInstance()); for (int i = 0; i < mTitles.length; i++) { mFragmentList.add(CategoryFragment.newInstance(mTitles[i])); } } @Override public void process() { mView.setTab(mFragmentList, mTitles); mView.setSelectPage(0); } }
CategoryPresenter.java
public class CategoryPresenter implements ICateFragPresenter { private List<DataInfo> mDataList = new ArrayList<>(); private ICatagFragView catagFragView; //持有 view 的引用 private IModel mModel; //持有 modle的 引用 private String mCategory; private int mCurrentPage; public CategoryPresenter(ICatagFragView iCatagFragView) { this.catagFragView = iCatagFragView; } @Override public void onSaveInstanceState(Bundle outState) { outState.putParcelableArrayList("data", (ArrayList<DataInfo>) mDataList); outState.putInt("page", mCurrentPage); } @Override public void initData(Bundle bundle, Bundle savedInstanceState) { mCategory = catagFragView.getCategory(); //初始化 modle initModel(); mCurrentPage = getDefaultPage(); //恢复保存的数据 if (savedInstanceState != null) { mDataList = savedInstanceState.getParcelableArrayList("data"); //恢复之前 保存的请求页数 mCurrentPage = savedInstanceState.getInt("page", mCurrentPage); } } private void initModel() { if ("每日精选".equals(mCategory)) { mModel = new DayPublishModel(this); } else { mModel = new CategoryModel(this); } } private int getDefaultPage() { if (TextUtils.isEmpty(mCategory) || !"每日精选".equals(mCategory)) { return 1; } return 0; } /** * 数据 获取成功 开始适配 */ @Override public void getDataSuccess(List<DataInfo> dataList) { mDataList.addAll(dataList); //更新 view catagFragView.getDSucesUpdateUI(mDataList); } @Override public void bindData(Bundle savedInstanceState) { //处理 数据信息: if (mDataList != null && mDataList.size() != 0) { catagFragView.getDSucesUpdateUI(mDataList); } else { mModel.requestData(mCategory, mCurrentPage); } } @Override public void fail(String msg) { Log.i("info", "加载数据失败============"); } @Override public void pullToRefresh(boolean isLoadMore) { mModel.requestData(mCategory, ++mCurrentPage); } }
Design包主要使用了:NavigationView,CoordinatorLayout,AppBarLayout,TabLayout。以及v7包和v4包的CardView,DrawLayout。
沉浸式状态栏的实现:工具类:
public class StatusBarUtil { /** * 设置状态栏颜色 * @param activity 需要设置的 activity * @param color 状态栏颜色值 */ public static void setColor(Activity activity, @ColorInt int color) { setColor(activity, color, DEFAULT_STATUS_BAR_ALPHA); } /** * 设置状态栏颜色 * @param activity 需要设置的activity * @param color 状态栏颜色值 * @param statusBarAlpha 状态栏透明度 */ public static void setColor(Activity activity, @ColorInt int color, int statusBarAlpha) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); activity.getWindow().setStatusBarColor(calculateStatusColor(color, statusBarAlpha)); } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView(); View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID); if (fakeStatusBarView != null) { if (fakeStatusBarView.getVisibility() == View.GONE) { fakeStatusBarView.setVisibility(View.VISIBLE); } fakeStatusBarView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha)); } else { decorView.addView(createStatusBarView(activity, color, statusBarAlpha)); } setRootView(activity); } } /** * 为滑动返回界面设置状态栏颜色 * @param activity 需要设置的activity * @param color 状态栏颜色值 */ public static void setColorForSwipeBack(Activity activity, int color) { setColorForSwipeBack(activity, color, DEFAULT_STATUS_BAR_ALPHA); } /** * 为滑动返回界面设置状态栏颜色 * @param activity 需要设置的activity * @param color 状态栏颜色值 * @param statusBarAlpha 状态栏透明度 */ public static void setColorForSwipeBack(Activity activity, @ColorInt int color, int statusBarAlpha) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { ViewGroup contentView = ((ViewGroup) activity.findViewById(android.R.id.content)); View rootView = contentView.getChildAt(0); int statusBarHeight = getStatusBarHeight(activity); if (rootView != null && rootView instanceof CoordinatorLayout) { final CoordinatorLayout coordinatorLayout = (CoordinatorLayout) rootView; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { coordinatorLayout.setFitsSystemWindows(false); contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha)); boolean isNeedRequestLayout = contentView.getPaddingTop() < statusBarHeight; if (isNeedRequestLayout) { contentView.setPadding(0, statusBarHeight, 0, 0); coordinatorLayout.post(new Runnable() { @Override public void run() { coordinatorLayout.requestLayout(); } }); } } else { coordinatorLayout.setStatusBarBackgroundColor(calculateStatusColor(color, statusBarAlpha)); } } else { contentView.setPadding(0, statusBarHeight, 0, 0); contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha)); } setTransparentForWindow(activity); } } /** * 设置状态栏纯色 不加半透明效果 * @param activity 需要设置的 activity * @param color 状态栏颜色值 */ public static void setColorNoTranslucent(Activity activity, @ColorInt int color) { setColor(activity, color, 0); } /** * 使状态栏半透明 * 适用于图片作为背景的界面,此时需要图片填充到状态栏 * @param activity 需要设置的activity */ public static void setTranslucent(Activity activity) { setTranslucent(activity, DEFAULT_STATUS_BAR_ALPHA); } }
Github:https://github.com/zqHero/MyGankIoDemo
再次感谢一下作者:
http://www.open-open.com/lib/view/open1455584716230.html
http://jaeger.itscoder.com/android/2016/02/15/status-bar-demo.html
http://www.apkbus.com/thread-272535-1-1.html
https://github.com/MyLifeMyTravel/GankIO
仅供学习交流使用,若有侵犯,立马删除。
相关文章推荐
- Android Material Design + MVP + Rxjava + Retrofit + Okhttp + Glide一个小项目
- MVP+RxJava+Retrofit_Okhttp框架优秀开源项目推荐
- butterknife+dagger+otto+okhttp+picasso+retrofit+rxjava示例项目
- Android开源项目 MVP+MD+Retrofit+RxJava 看了你会上瘾的
- 一款纯粹的在线视频App,基于Material Design + MVP + RxJava + Retrofit + Realm
- 一款在线视频 App,基于 Material Design + MVP + RxJava + Retrofit + Realm + Glide
- Rxjava+RetrofitUtil +Mvp +butterKnife
- 重构(MVP+Retrofit+Okhttp+Gson+Butterknife)
- Android Retrofit+Rxjava+MVP+EventBus+ButterKnife实现接口登录(无正则表达式)
- MVP框架做的登陆注册,商品列表,商品详情,购物车功能 RxJava+Retrofit ijkplayer EventBus ButterKnife
- 开发 Material Design+RxJava+Retrofit+MVP App 参考资料
- 高仿知乎日报(Material Design + MVP + RxJava + Retrofit)
- Material Design+RxJava+Retrofit+MVP App
- 整合大量开源库温习基础项目(四)伸缩实现OverscrollScale以及MaterialLoadingProgressBar
- Android Studio 项目中加入Butterknife注入框架遇到的问题
- 推荐RxJava+MVP的开源项目——RxJoke
- Android Studio中ButterKnife换个项目就不能使用的问题
- Android Material-Design-Login 项目列子
- 手把手教你做开源项目MyMeiZi 一( RxJava + Retrofit)
- 深入解析开源项目之Retrofit(一)使用篇