通过对MVP架构的学习,继续对练习的项目做总结。

这次是学习了阅读类App (MVP + RxJava + Retrofit)
通过对此项目的学习,对Rxjava以及Retrofit有了在基础之上的练习,同时对MVP架构有了新的认识,以及对OkHttp的新的学习。在完成项目后,我对此项目加了一点小小的UI美化(包括一个侧滑,以及swipeBack的滑动关闭界面的功能)同时对原项目的轮播图也进行了美化
=。=,多加了小点点指示器
这里附上我的Github项目的地址
这里写图片描述
这里写图片描述
这里写图片描述

下边开始正式总结此项目

首先是包的结构

这里写图片描述
不像之前做的那个MVP项目,这个项目是把MVP写到一个包中。
在开始总结之前,我要先说一下对于新手初次使用ButterKinfe所遇到的尴尬之处,通常按照步骤,下载好AS插件,重启之后然后添加依赖。之后就以为可以随便使用了,结果右键到鼠标爆照都不出现自动注入插件的框框,于是乎百度,可是也查不到结果。无意间发现,原来是要在setContextView(xxxx)这句话上右键。
这里写图片描述

唉,找到了想偷懒的方法,还费了很大的力气才会使用。

首先是SplashActivity
具体动画效果的实现我就不说了,因为我用到了别人的自定义view即SplashView来实现的一个酷炫的动画。
这个界面要说的就是给TextView设置自定义字体。首先在
工程目录下新创建一个assets包,然后将下好的字体放到此包下新创建的fonts目录中。之后在用到的SplashActivity中,来获取就可以

AssetManager assets = getAssets();//得到AssetManager
 Typeface tf = Typeface.createFromAsset(assets, "fonts/rm_albion.ttf");//根据路径得到Typeface
 mTextView.setTypeface(tf);//设置字体

这样就实现了更换字体。

下面就进入主界面。

对项目的总结,确实要先把要总结的东西列好,不然的话没有方向,就像现在。。。

主界面的各个fragment里,获取数据,展现数据的方法都是通过调用Presenter层的具体方法实现的。

学习这个项目的开始遇到很多疑问的地方,这个项目的作者采用了JAVA8的新特性,对lambda表达式用得很熟练,于是对我造成很大的打击,刚开始看不懂啊,于是有学习了这方面的知识
比如说在代码中人家是这样的

 zhihuApi.getLatestNews()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(newsTimeLine -> {
                        disPlayZhihuList(newsTimeLine, context, mIZhihuFgView, mRecyclerView);
                    },this::loadError);

我理解后才明白原来是这个意思

zhihuApi.getLatestNews()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(newsTimeLine -> {
                        disPlayZhihuList(newsTimeLine, context, mIZhihuFgView, mRecyclerView);
                    }, new Action1<Throwable>() {
                        @Override
                        public void call(Throwable throwable) {
                            loadError(throwable);
                        }
                    });

这里用到了RxJava的链式语法,此处是Rxjava结合Retrofit的使用方式

这个项目我学习到最多的地方是通过 Retrofit 和okhttp实现了无网缓存

一.配置Okhttp的Cache
二.配置请求头中的cache-control或者统一处理所有请求的请求头
三.自己写拦截器修改响应头中cache-control

1.配置okhttp中的Cache(先创建缓存目录)

File httpCacheDirectory = new File(MyApp.mContext.getCacheDir(), "responses");
        int cacheSize = 10 * 1024 * 1024; // 10 MiB
        Cache cache = new Cache(httpCacheDirectory, cacheSize);

        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
                .cache(cache).build();

2.自己写拦截器修改响应头response中的cache-control

Interceptor REWRITE_CACHE_CONTROL_INTERCEPTOR = chain -> {

        CacheControl.Builder cacheBuilder = new CacheControl.Builder();
        cacheBuilder.maxAge(0, TimeUnit.SECONDS);
        cacheBuilder.maxStale(365, TimeUnit.DAYS);
        CacheControl cacheControl = cacheBuilder.build();

        Request request = chain.request();
        if (!StateUtils.isNetworkAvailable(MyApp.mContext)) {
            request = request.newBuilder()
                    .cacheControl(cacheControl)
                    .build();//StatuUtils是个判断有无网络的工具类

        }
        Response originalResponse = chain.proceed(request);
        if (StateUtils.isNetworkAvailable(MyApp.mContext)) {
            int maxAge = 0; // read from cache
            return originalResponse.newBuilder()
                    .removeHeader("Pragma")
                    .header("Cache-Control", "public ,max-age=" + maxAge)
                    .build();
        } else {
            int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale
            return originalResponse.newBuilder()
                    .removeHeader("Pragma")
                    .header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
                    .build();
        }
    };

此外这个项目还有一个我比较喜欢的地方,就是图片存储到本地相册这个功能。

mTextView.buildDrawingCache();//为自己的textview建立相应的缓存, 这个cache就是一个bitmap对象
Bitmap bitmap = mIvMeizhiPic.getDrawingCache();
 //将Bitmap转换成二进制,写入本地
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        byte[] byteArray = stream.toByteArray();
        File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/new+");
        if (!dir.exists()) {
            dir.mkdir();
        }
        File file = new File(dir, img_desc.substring(0, 10) + ".png");
        try {
            FileOutputStream fos = new FileOutputStream(file);
            fos.write(byteArray, 0, byteArray.length);
            fos.flush();

            //用广播通知相册进行更新相册
            Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            Uri uri = Uri.fromFile(file);
            intent.setData(uri);
            PictureActivity.this.sendBroadcast(intent);
            Snackbar.make(mContainer, "图片保存成功~恭喜你收获到新的妹子~~", Snackbar.LENGTH_SHORT).show();
            } catch (Exception e) {
            e.printStackTrace();
        }

除此之外,本项目还有很多值得学习的地方,比如RecyclerView 加载了多种复杂布局,这里真的是很复杂的布局,类型有5~6种,不过方法就是很固定,switch判断,哪种类型加载那个holder而已。学习这个项目花了一周时间,今天来做个总结,果然多阅读别人的代码,多敲敲自己的代码,就会学到很多东西,加油!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fighting_Boss_Hao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值