这次是学习了阅读类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而已。学习这个项目花了一周时间,今天来做个总结,果然多阅读别人的代码,多敲敲自己的代码,就会学到很多东西,加油!