一个WanAndroid和开眼一锅烩的客户端
- 整个客户端用Kotlin编写
- 网络请求用retrofit2 + okhttp3 + rxjava2 MVP架构
- 图片加载使用glide4
- FRAGMENT的操作使用了Fragmentation
- 网页内容显示用了AgentWeb
- 视频播放使用了ijkplayer + GSYVideoPlayer
上拉加载更多
SwipeRefreshLayout可以提供下拉刷新的支持但是并没有提供上拉加载的功能,网上有很多框架可以实现这一功能,但是有些功能未必在此处未必需要,所以这里干脆自己实现一个最简单的加载
refresh.setOnChildScrollUpCallback { parent, child ->
child?.let {
if(!child.canScrollVertically(1)){
get(page)
return@setOnChildScrollUpCallback true
}
return@setOnChildScrollUpCallback false
}
return@setOnChildScrollUpCallback false
}
用SwipeRefreshLayout.setOnChildScrollUpCallback()方法设置向上滑动时的监听回调用View.canScrollVertically()来判断子View是否还可以向上滑动,如果不能则调用接口请求更多数据,此方法当参数大于0时判断向上小于0时判断向下,类似的还有View.canScrollHorizontally()用来判断左右滚动。
动态url及重定向拦截
有的时候我们发送的请求并非是事先就可以确定的,比如在文章列表中就只是给出了文章的少量基本信息和一个网页链接,如果要点击打开网页需要我们自己去实现,只是开个网页也还好,就交给webview去load了,但是此处视频列表中视频的url无法这样处理,因为这些链接是自动重定向的请求,播放器无法直接处理,这只好再次使用retrofit2请求后拦截重定向获取到重定向的location后交给播放器播放:
@GET
fun getVideoPath(@Url url: String): Observable<RealUrl>
在接口中给方法的参数用上@Url注解在调用时直接传入url就可以请求任意链接
val httpClient = OkHttpClient.Builder()
.addNetworkInterceptor(interceptor)
.addInterceptor(Interceptor{
val req: Request = it.request()
var resp:Response = it.proceed(req)
if(resp.code() == HTTP_MOVED_TEMP){
resp.header("location")
val json = "{\"url\":\"" + resp.header("location") + "\"}"
val buffer:Buffer = Buffer().writeString(json, UTF_8)
resp = resp.newBuilder().code(HTTP_OK)
.body(RealResponseBody("application/json",
-1,
buffer))
.build()
}
return@Interceptor resp
})
.followRedirects(false)
.build()
为了可以拦截重定向并得到新的location,在构建okhttp时设置了不允许重定向followRedirects(false)并且添加了拦截器,在其中判断response code等于302 也就是常量HTTP_MOVED_TEMP时去获取header中的location并将其包装到json中,重新构建response。
总结
写了一个最基本功能的APP,各种功能倾向于用尽量轻的方式实现~~说到底就是懒=。=
kotlin-android-extensions省去了很多findViewById() data类让Bean不需要再写很多getter/setter。总之,发明这门语言的人绝对是个了不起的人(ง •̀_•́)ง
github github.com/woodygithub…