我是一名初学者Android开发人员,试图通过构建电影数据库应用程序来学习移动开发。我正在用Kotlin编写我的应用程序,并使用Retrofit进行网络通话。我对如何调用以及如何使用tmdb API中的电影海报填充Recyclerview感到困惑。
这是我的界面:
interface APImovies {
fun getMovies()
}
这是我与Retrofit服务器对象的主要活动:
class MainActivity() : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val recyclerView = findViewById<RecyclerView>(R.id.recycler_view);
recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
recyclerView.layoutManager = GridLayoutManager(this, 3);
recyclerView.adapter = PosterAdapter()
}
object RetrofitServer{
val client: APImovies by lazy{
val client = OkHttpClient.Builder().build()
val retrofit = Retrofit
.Builder()
.baseUrl("https://api.themoviedb.org/3/movie/550?api_key=")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()
retrofit.create(APImovies::class.java)
}
}
}
这是我的适配器,当前使用占位符图像填充Recyclerview:
class PosterAdapter() : RecyclerView.Adapter<PosterHolder>(){
override fun getItemCount(): Int { return 300}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PosterHolder{
val layoutInflater = LayoutInflater.from(parent.context)
val listItem = layoutInflater.inflate(R.layout.list_item, parent, false)
return PosterHolder(listItem)
}
override fun onBindViewHolder(holder: PosterHolder, position: Int) {
holder.view.movie_poster?.setImageResource(R.mipmap.beauty_and_the_beast_ver3)
holder.view.movie_poster?.scaleType = ImageView.ScaleType.FIT_XY
}
}
class PosterHolder(val view: View) : RecyclerView.ViewHolder(view), View.OnClickListener {
var imageView: ImageView? = null
fun PosterHolder(view: View){ this.imageView = view.findViewById<View>(R.id.movie_poster) as ImageView }
override fun onClick(p0: View?) {}
}
答案 0 :(得分:3)
我使用以下设置。看看这是否对您有帮助。
interface WebService {
@GET
fun getMovies(): Call<List<MyResponseObject>>
companion object {
fun create(): WebService {
val client = OkHttpClient.Builder().build()
val retrofit = Retrofit.Builder()
.baseUrl("YOUR_BASE_URL")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()
return retrofit.create(WebService::class.java)
}
}
}
在MainActivity
中执行以下操作以进行网络通话
class MainActivity : AppCompatActivity() {
private val webService = WebService.create()
override fun onCreate(savedInstanceState: Bundle?, persistentState:
PersistableBundle?) {
/*...*/
fetchMovies()
}
private fun fetchMovies() {
var call = webService.getMovies()
call.enqueue(object : Callback<MyResponseObject> {
override fun onFailure(call: Call<MyResponseObject>?, t: Throwable?) { }
override fun onResponse(call: Call<MyResponseObject>?, response: Response<List<Class>>?) {
if (response != null && response.isSuccessful) {
val myListData: MyResponseObject = response.body()
setUpRecyclerView(myListData) // The usual way of setting up a RecyclerView
}
}
})
}
}
这仅适用于初学者。我建议您使用Android体系结构组件和Dagger 2(用于依赖注入)研究MVVM体系结构。如 Nail Shaykhraziev
所述,由于您使用Kotlin,因此可以使用,Kotlin Coroutines和AndroidKTX进行DI的优势答案 1 :(得分:-1)
我用这样的东西:
public final class ApiClient {
private static OkHttpClient sClient;
private static volatile MovieService movieService;
private ApiClient() {
}
public static MovieService getMovieService() {
MovieService service = movieService;
if (service == null) {
synchronized (ApiClient.class) {
service = movieService;
if (service == null) {
service = movieService = buildRetrofit().create(MovieService.class);
}
}
}
return service; // this is one of the implementation options singlton pattern. You can use some di tools(Kodein, Dagger)
}
private static Retrofit buildRetrofit() {
return new Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.client(getClient())
.addConverterFactory(GsonConverterFactory.create(getGson()))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
}
private static Gson getGson() {
return new GsonBuilder()
.setLenient()
.create();
}
private static OkHttpClient getClient() {
OkHttpClient client = sClient;
if (client == null) {
synchronized (ApiClient.class) {
client = sClient;
if (client == null) {
client = sClient = buildClient();
}
}
}
return client;
}
private static OkHttpClient buildClient() {
return new OkHttpClient.Builder()
.addInterceptor(TokenInterceptor.create())
.build();
}}
在Presenter / Interactor / ViewModel调用改造服务方法之后:
ApiClient.movieService.popularMovies()
.map { it.movies }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe { view.showProgress }
.doAfterTerminate { view.hideProgress }
.subscribeBy(onSuccess = {
view.showMovies(it)
}, onError = {
view.showErrors()
})
关于活动/片段/视图:
class Activity : AppCompatActivity(), MovieView {
override fun onCreate(savedInstanceState: Bundle?) {
// your code
}
override fun showMovies(list: List<Movie>) {
adapter.update(list)
}
}