电影资讯App是一个纯练手项目,使用了系统API28,全部是基于Androidx包下的。使用Kotlin语言开发,使用了AndroidJetPack中的LiveData、ViewModel以及Room。为了学习Kotlin和巩固自定义View和ViewGroup,这个项目是尽量少应用依赖第三方库。Api来自豆瓣电影,豆瓣电影Api目前是不公开的,小编是在简书上看到有人公开了访问豆瓣电影的Api的API_KEY,如果有侵犯,请联系删除!
项目截图截图1截图2截图3截图4截图5app主要设计到知识点:MaterialDesignUI设计风格;使用Kotlin开发,大家想学习和巩固Kotlin,可以参考这个App;Retrofit适配LiveData手写一个LiveDataCallAdapter适配器;RecyclerView支持上拉刷新和下拉加载,并且可以添加不同类型头部和底部的View以及动画;支持视频播放
看几段代码,访问网络的核心代码,设计到了蛮多的知识点,这是初始化Retrofit
classRetrofitClient{companionobject{valserviceApi:ServiceApibylazy{valretrofitClient=Retrofit.Builder().baseUrl(BASE_URL).client(OkHttpClient.Builder().addInterceptor(HttpLoggingInterceptor(HttpLoggingInterceptor.Logger{message->Log.i(TAG,message)}).setLevel(HttpLoggingInterceptor.Level.BODY)).build()).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(LiveDataCallAdapterFactory()).build()retrofitClient.create(ServiceApi::class.java)}}}
注意这段代码,通过工厂模式添加一个LiveData数据源适配器
.addCallAdapterFactory(LiveDataCallAdapterFactory())
通过方法工厂返回LiveDataCallAdapter的实例,并且获取泛型的参数类型
classLiveDataCallAdapterFactory:Factory(){overridefunget(returnType:Type,annotations:Array<Annotation>,retrofit:Retrofit):CallAdapter<*,*>?{valresponseType:Typeif(Factory.getRawType(returnType)!=LiveData::class.java){throwIllegalStateException("returntypemustbeparameterized")}valobservableType=Factory.getParameterUpperBound(0,returnTypeasParameterizedType)valrawObservableType=Factory.getRawType(observableType)responseType=if(rawObservableType==Response::class.java){if(observableType!isParameterizedType){throwIllegalArgumentException("Responsemustbeparameterized")}Factory.getParameterUpperBound(0,observableType)}else{observableType}returnLiveDataCallAdapter<Any>(responseType)}}
注意adapt()方法中的代码,通过适配器模式将Call转为LiveData
classLiveDataCallAdapter<R>(privatevalresponseType:Type):CallAdapter<R,LiveData<R>>{overridefunresponseType()=responseTypeoverridefunadapt(call:Call<R>):LiveData<R>{returnobject:LiveData<R>(){privatevarstarted=AtomicBoolean(false)overridefunonActive(){super.onActive()if(started.compareAndSet(false,true)){call.enqueue(object:Callback<R>{overridefunonResponse(call:Call<R>,response:Response<R>){postValue(response.body())}overridefunonFailure(call:Call<R>,throwable:Throwable){postValue(null)}})}}}}}
大家可能看这些代码会比较懵,我是看了RxJava2中的RxJava2CallAdapterFactory中的代码,以前只是会写,但是点击去看源码,在分析就不一样了。Observable在这相当于LiveData(被观察者)。通过调用retrofitClient.create(ServiceApi::class.java),最终会调用到adapt()方法中。
公众号后台回复:“源码”关键字获取项目地址。