欢迎掘金的小伙伴们访问我的博客网站,原文链接:wensibo.top/2017/05/15/… ,未经允许不得转载!

今天想要与大家一起分享的五月份的时候用一个星期开发的一个app——干货集中营客户端,因为已经获得了掘金的专栏所以就把之前的文章发不上来与大家一起分享。
其实网上已经有许多类似的项目,代码家也在他的干货集中营中推荐了几款优秀的作品,我也借鉴了其中的一些,自己开发出一款干货集中营客户端,目前项目已经发布到github,如果你想了解整个工程的具体内容,那么你可以fork或者clone,如果你觉得我做得还可以,那么请你赐给我一个star呗!你的支持会是我努力的动力。

前言

慢慢的已经养成了每篇文章都会来一个前言,也慢慢地将写文章潜移默化的转变成写故事,所以每个故事都会有前言,也都会有结果,这次也不例外。
距离上篇引起热烈反响的文章发布已经过去一个月了,承蒙广大网友对我的支持以及建议,当然作为一个90后,我也很虚心的接受来自各方的吐槽,毕竟我并不优秀,只是一直在优秀的路上努力的奔跑着。下面我想跟大家一起分享一下这一个月里我做了些什么事,以及接下来一段时间的计划和打算。

Have Done List

  • 持续22天在github上出现,看看下面这棵贡献树

    contributions
  • 博客浏览量突破35000
    blog
  • 看了1本好书——《网络是怎样连接的》
  • 研究Retrofit与RxJava的源码(待我葡萄成熟时再把文章放出来吧,现在太嫩了,不好意思让大家看到)
  • 2次担任演讲的主讲人(之后会写一篇文章讲述我的演讲技巧)
  • 看了锤子科技新品发布会(我是罗粉但也是加油,心疼老罗一秒)
  • 努力寻找实习(投了许多简历,但是无一幸免:sob: ,有同学可以推荐一波吗?没有的话我待会再问问)
  • 1个全新的干货集中营客户端app(也是写这篇文章的缘由)

Todo List

  • xposed插件开发(这个闪念是有一天夜里惊醒过来的想法)
  • 继续写好的文章与大家一起分享,不仅仅是技术方面的,还有许多我觉得有用的文章,都会为大家奉上,感谢老铁们的支持
  • 继续看书
  • 继续找实习(呜呜呜~~(>_<)~~,体会到工作难找了,尤其是互联网寒冬)
老铁别废话了

好啦,上面讲了一大堆废话终于可以进入正题了,我也很基动,开车咯!

项目介绍

logo

GankClient(又称干货集中营客户端)是一个全新的干货集中营客户端,它获取的是来自干货集中营API的数据,利用全新的Material Design的设计语言展示数据内容。整个项目采用MVP的设计架构,并且大量使用RxJava2,网络框架使用的是Retrofit。我用下面几个装逼的句子来形容一下这个APP:

  • 更快速的加载速度
  • 更流畅的页面体验
  • 更有趣的刷新效果
  • 更精美的网页浏览
  • 更美观的视觉享受

这个只是我的个人感受,大神请轻喷:joy: ,不过还是希望大家能够喜欢这个项目,并且积极的向我pull request以及反馈bug,希望大家多多支持。如果可以的话给个star咯。

预览

谁说不给图的

全部效果图来一发

screenshot
screenshot
screenshot
screenshot
screenshot
screenshot

没有gif图都不好意思说话了

gif

下载

酷安基佬群

如果你使用酷安的话,那就使劲点这里,或者在酷安搜索干货集中营,认准我的图标哦

干货集中营

fir.im

如果你没有安装酷安,那么你可以扫描下方的二维码进行下载

QRCode

测试

如果你想测试这个项目,那么请手动clone

功能&特色

√表示已经实现的功能,X表示的的是还没实现或者需要完善的功能。(吐槽一下,掘金的MarkDown编辑器还是没有实现一些基本的语法,例如打勾勾)

√实时获取服务器的最新数据,采用CardView的布局以更好的展现数据。
√刷新效果很好玩,真的很精致,感谢Phoenix。
√如果你装有Chrome浏览器,并将其设置为默认浏览器,那么你的网页浏览效果就会十分酷炫。感谢Custom-Tabs-Client ! 墙裂推荐Chrome,如果你没有安装Chrome,那也没关系,那就用传统的WebView吧!
√更加统一的过渡动画,相信你会爱上它。
√保存、分享图片与链接,也可以直接使用浏览器打开链接。
√更好看的Material Design设计风格。
√妹子很漂亮哟!


X优化webview的视频播放。
X增加使用系统浏览器的选项。
X修复在主界面中加载数据到2016/4/20左右时数据显示错乱的问题。
X增强分享功能。

分解

终于到了这个纯干货步骤了,别说话先看东西!

如何使用MVP的设计架构

我先展示以下这个项目的结构图,让大家心里有个底

  • http

    • GankRetrofit.java
    • GankRetrofitClient.java
  • mvp
    • model

      • BaseModel.java
    • presenter
      • BasePresenter.java
    • view
      • IBaseView.java
  • ui
    • activity
    • adapter
    • base
    • chromeviews
    • fragment
    • widget

可以看到,整个项目的结构还算比较清晰,整体的架构都是在mvp目录中定下来的,mvp架构分三层,model模型层,用于定义一些数据的类型;presenter呈现者层,用于处理view层的逻辑;view显示层,这里定义的都是接口,真正实现他们的是activity,这些activity只要实现相应的接口,就能够自己复写其中的方法。
当然我这么说你肯定还是一脸懵逼,而且我还必须跟你说,我这个不算最纯粹的MVP模式,最纯粹的写法应该都是面向接口编程的,就是在model,presenter,以及view下都是定义接口,而到了具体的运用场景,就定义出具体的类去实现这些接口。当然了,为了让大家能够更清楚MVP是怎么实现的,下面我会用代码的形式为大家展示,例如我要编写MainActivity的代码,首先已经知道在这个Activity中需要做如下这些事:

  • 初始化组件
  • 加载Fragment
  • FloatingActionButton的点击事件——去到DailyActivity
  • drawer menu的点击事件——去到AboutActivity

为了让Activity专注于界面的工作,而不用去考虑逻辑处理的操作,这个就是所谓的解耦,那么我们可以将逻辑的操作放到presenter中去,而与界面有关的操作就放在view下,于是我们就可以这样写(为了便于大家理解,我将项目中的代码做了适当的修改,如果你想了解更加具体的逻辑,可以仔细看看代码):

  • IBaseView
public interface IBaseView {//界面初始化操作void init();
}复制代码
  • BasePresenter&MainPresenter
/**
* 将presenter的公共操作集成为BasePresenter
*/
public abstract class BasePresenter <T extends IBaseView>{protected Disposable disposable;protected Context context;protected T iView;      //获取到view的对象public BasePresenter(Context context, T iView) {this.context = context;this.iView = iView;}public void init() {iView.init();}public abstract void release();public abstract void initPresenter();
}/**
* 每一个界面都可以编写自己的Presenter,并指定View的泛型
*/
public class MainPresenter extends BasePresenter<IBaseView> {public MainPresenter(Context context, IBaseView iView) {super(context, iView);}@Overridepublic void release() {}public void toDailyActivity() {Intent intent = new Intent(context, DailyActivity.class);context.startActivity(intent);}public void toAboutActivity() {Intent intent = new Intent(context, AboutActivity.class);context.startActivity(intent);}public void toSettingActivity() {Intent intent = new Intent(context, SettingActivity.class);context.startActivity(intent);}复制代码
  • MainActivity
public class MainActivity <MainPresenter> extends AppCompatActivity implements IBaseView{@OnClick(R.id.fab_main)void fabClick() {presenter.toDailyActivity();}@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}@Overrideprotected void initPresenter() {presenter = new MainPresenter(this, this);presenter.init();}@Overridepublic void init() {//所有的初始化操作}@Overrideprotected void onDestroy() {super.onDestroy();presenter.release();}}复制代码

大概就是这样一个套路,讲真我这样讲你肯定迷糊,我当初在学这个的时候也是十分凌乱,后来才发现只有自己动手亲自敲代码才能了解整个思路,另外大家在学习MVP的过程中应该擅于画图,不管是在纸上画还是使用思维导图都行,这样可以让你更加宏观的了解整个调用的顺序以及各个类之间的关系,这绝不是你看了一篇文章就能懂的。

你真的用好RxJava了吗

当我问这个问题的时候,其实我想说的是RxJava的用处很广,我们想当然的认为只要RxJava与Retrofit相配合就算是完成任务了,但实际上只要涉及到耗时操作、线程切换:网络请求、图片解析、数据库读取等等需要用多个线程一起完成的工作时,你都可以用到RxJava,并且如果你还一直用RxJava1的话,那么你也OUT啦,当你认识RxJava2.x的时候你会发现他更强大了。关于RxJava,我后续会写相关的文章与大家一起分享,这里我举项目中遇到的一个例子,看看RxJava的用武之地是多么的广:

/**
* 将图片保存在本地
*/
public void openWebView(final Gank gank) {disposable=Observable.create(new ObservableOnSubscribe() {@Overridepublic void subscribe(@NonNull ObservableEmitter e) throws Exception {e.onNext(android.R.drawable.ic_menu_share);}}).subscribeOn(Schedulers.newThread())//开启一个新线程来进行耗时操作.map(new Function<Integer, Bitmap>() {@Overridepublic Bitmap apply(@NonNull Integer integer) throws Exception {//将资源id解析为bitmap是一个耗时操作return BitmapFactory.decodeResource(activity.getResources(), integer);}}).observeOn(AndroidSchedulers.mainThread())//回到主线程操作bitmap.subscribe(new Consumer<Bitmap>() {@Overridepublic void accept(@NonNull Bitmap bitmap) throws Exception {//拿到bitmap之后做的界面更新}});
}//释放资源
public void release() {if (disposable != null&&!disposable.isDisposed()) {disposable.dispose();}}复制代码

爽快的Retrofit

还记得之前我写过Volley的一系列文章,虽然觉得这个开源框架已经不错了,但毕竟长江后浪推前浪,在Retrofit的面前,Volley简直就是小巫见大巫,看看我们应该如何在项目中使用:

  • 1、新建一个接口,用注解的形式在里面定义网络请求的方法:
public interface GankRetrofit {//获取MainActivity界面的数据,具体的请求路径应该详细看官方的API说明,// Retrofit与RxJava配合之后才能显示出更强的威力@GET("data/{type}/40/{page}")Observable<MainData> getMainData(@Path("type") String type, @Path("page") int page);
}复制代码
  • 2、获得实例:
Gson date_gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").create();
Retrofit retrofit = new Retrofit.Builder().baseUrl("http://gank.io/api/")         //指定服务器地址.addConverterFactory(GsonConverterFactory.create(date_gson))    //添加一个gson的解析器.addCallAdapterFactory(RxJava2CallAdapterFactory.create())          // 如果想使用RxJava那就需要添加这个适配器  .build();
GankRetrofit gankRetrofit;
gankRetrofit = retrofit.create(GankRetrofit.class);            //获取GankRetrofit的对象复制代码
  • 3、获取数据:
//返回的Observable<MainData>对象就可以使用RxJava进行解析了
gankRetrofit.getMainData("Android",40);复制代码

更好的网页浏览体验——Custom-Tabs-Client

如果你使用过Chrome浏览器,那么你应该会喜欢上它,当我们在使用webview开发的时候,会发现webview存在许多的限制,并且开发者对webview不能完全控制,于是Chrome团队为了解决开发者的这些问题,就设计出这个开源库,只要用户手机上安装Chrome并且设置为默认浏览器,那么打开网页链接的时候就会看到如下的画面:

custom-tabs-client

是的!如此酷炫的画面是用到了Chrome浏览器的内核,并且读取Chrome的cookie,例如如果你在Chrome已经登录过github了,那么通过这个库打开的github链接同样也显示你已经登录了github。当然除了页面效果十分好之外,我们还可以自定义许多东西,例如过渡动画ToolBar上方的ActionButton等等,我的项目中也已经实现了这两个功能。接下来我带大家一起看看最简单的实例应该怎么编写:

CustomTabsIntent.Builder customTabsIntent;customTabsIntent = new CustomTabsIntent.Builder();     //获取到CustomTabsIntent实例//一系列的设置
customTabsIntent.setToolbarColor(activity.getResources().getColor(R.color.colorPrimaryDark));   //设置ToolBar的颜色
customTabsIntent.setShowTitle(true);    //设置是否显示网页的标题
customTabsIntent.setStartAnimations(activity, R.anim.slide_in_right, R.anim.slide_out_left);    //设置进入的动画
customTabsIntent.setExitAnimations(activity, R.anim.slide_in_left,R.anim.slide_out_right);      //设置退出的动画
//开启网页
CustomTabActivityHelper.openCustomTab(activity,       //当前的activitycustomTabsIntent.build(),view,gank,   //gank带有要打开的网页的urlnew CustomFallback() { //如果用户没有安装Chrome并将其设置为默认浏览器的话,应该做这样的处理@Overridepublic void openUri(Activity activity, View view,Gank gank) {Log.d("Gank", gank.toString());super.openUri(activity, view,gank);}});复制代码

以上就是想要跟大家一起分享的关于这个项目中一些重要的点,可能有些地方讲得并不那么清楚,但我觉得只有实践才能出真知,所以老哥还是乖乖打开AS撸撸代码啦!

版本控制

目前app的版本为V1.0.0,我会用下面的时间表记录版本的迭代,如果有更新的版本,我会及时更新这个表格。

Version Date
V1.0.0 2017/5/14

致谢

作为一名Android开发者,我们都应该具有像罗老师一样感激开源世界的情怀,而我们现在能做的就是同样为开源世界做贡献,无论是写文章亦或是写程序,记得都要时刻保持一颗感恩的心。非常感谢代码家以及他的干活集中营,也非常感谢许多前辈们做过的干活集中营app。

  • 代码家
  • 干货集中营
  • Gank.lu

后记

最近一个月,感觉自己身体被掏空,吐槽学校对我们专业的课程安排如此不合理,每天上那些自己不感兴趣的课程确实很无趣,但是生活再难也要感激它,只有通过自己的双手去努力,将来的你才会为现在的自己喝彩骄傲。下篇文章再见!

一个MVP+RxJava+Retrofit的干货集中营相关推荐

  1. android小说阅读、MVP + RxJava + Retrofit项目、证件拍照裁剪、蓝牙锁等源码

    Android精选源码 完全防美团设置支付密码,页面与细节完全一致,如不能... android智能选股应用源码 android开源小说阅读app源码(Kotlin) Android模仿Duoling ...

  2. android小说阅读、MVP + RxJava + Retrofit项目、证件拍照裁剪、蓝牙锁等源码器

    Android精选源码 完全防美团设置支付密码,页面与细节完全一致,如不能- android智能选股应用源码 android开源小说阅读app源码(Kotlin) Android模仿Duolingo的 ...

  3. 用Kotlin语言开发玩安卓,基于基于Material Design+AndroidX + MVP + RxJava + Retrofit等优秀的开源框架开发,注释超详细,方便大家练手

    WanAndroid 一位练习时长两年半的安卓练习生根据鸿神提供的WanAndroid开放Api来制作的产品级App,基本实现了所有的功能,使用Kotlin语言,基于Material Design+A ...

  4. 一款在线视频 App,基于 Material Design + MVP + RxJava + Retrofit + Realm + Glide

    Ghost 项目地址:GeekGhost/Ghost 简介:一款在线视频 App,基于 Material Design + MVP + RxJava + Retrofit + Realm + Glid ...

  5. java dagger2_从零开始搭建一个项目(rxJava+Retrofit+Dagger2) ---上

    工程结构 Androd studio 替代eclipse给我带来最大的感觉,就是不用每次需要用到什么类库,就得去网上下载一个jar包.只要在项目app/build.gradle中加入代码,就能远程使用 ...

  6. 一款纯粹的在线视频App,基于Material Design + MVP + RxJava + Retrofit + Realm

    跟大家分享一款纯粹的在线视频App,目前项目中主要使用到的技术点有: 使用RxJava配合Retrofit2做网络请求 使用RxUtil对线程操作和网络请求结果处理做了封装 使用RxPresenter ...

  7. Mvp(RxJava+Retrofit+fresco+recyclerview)

    //依赖 //recyclerview compile 'com.android.support:recyclerview-v7:26.+' //rxjava2 compile "io.re ...

  8. java dagger2_从零开始搭建一个项目(rxJava+Retrofit+Dagger2) --完结篇

    鸡汤:感到迷茫是因为你没有给自己做好人生规划 接上一章的内容,如果还没看过的朋友, 请点 本章内容 Dagger2的引入 Dagger2的引入 Dagger2是一个依赖注入框架,那么dagger2能起 ...

  9. Android RxJava+Retrofit+MVP 入门总结

    前言 RxJava+Retrofit+MVP的使用已经推出一段时间了,也一直想找个时间学习一下并且应用到接下来的项目中.趁放假这段时间仔细研究了一下,确实相比于其他框架的学习成本要高一些,不过功能实现 ...

最新文章

  1. 重型车辆盲区行为检查Behaviours – Heavy Vehicle Blind Spots
  2. Android 布局文件Graphical Layout不显示预览+不能实现拖置功能
  3. jquery判断页面是否滑动到最底部
  4. Mac 的World空格显示为.
  5. Oracle 数据库启动 startup和startup force的区别
  6. JavaScript学习笔记——BOM_window对象
  7. hdu 4143 A Simple Problem 数论
  8. Python之网络编程(TCP套接字与UDP套接字)
  9. 人工智能学习该读哪些书籍?
  10. 4g内存电脑装xp系统怎么样_系统坏了?去店了重装系统又贵?今天手把手教你如何重装系统...
  11. Unix操作系统的原理、优点与缺点
  12. 如何查询目标计算机的ip地址,基于Wireshark获取目标ip地址
  13. ESP32 开发笔记(三)源码示例 12_IR_Rev_RMT 使用RMT实现红外遥控接收解码(NEC编码)
  14. Windows上搭建PHP开发环境
  15. 2023.04.22更新大麦网移动端/M端抢购软件和使用教程
  16. 4. 假设一年期定期利率为 3.25%,计算一下需要过多少年,一万元的一年定期存款连本带息能翻番?
  17. 第12课:如何理解技术管理者(上)
  18. 日常积累6:提取并拟合图片中的曲线
  19. 操作系统在计算机科学发展中的重要性,浅谈计算机科学中的系统论与辩证法
  20. 爱也可以,飘逸洒脱,卓尔不群

热门文章

  1. SQL查询数据库完整表结构(mysql)
  2. 人脸Pose检测:ASM、AAM、CLM方法总结
  3. 几个方便编程的C++特性
  4. kaptcha配置java_kaptcha 配置
  5. 2018.12.30|区块链技术头条
  6. Mysql多表查询笔记
  7. mysql 案例~mysql主从复制延迟处理(2)
  8. Radware支招:面对新时代应用SLA,企业该如何应对
  9. MarshalByRefObject浅析
  10. 我是这样开始学编程的