自己動手寫個 Android客戶端

woodyxt發表於2018-04-26

一個WanAndroid和開眼一鍋燴的客戶端

上拉載入更多

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…

相關文章