您好:)我正在开发一款应用,该应用可以显示热门电影以及每部电影的一些详细信息。我创建了一个RecyclerView,其中应显示信息。我一直在获取和显示数据。我正在使用https://www.themoviedb.org/页的api。
我正在按照以下步骤操作:http://imakeanapp.com/make-a-movies-app-using-tmdb-api-part-4-networking-using-retrofit-library/,但是它是用Java编写的,我需要用Kotlin编写代码。我自己转换了部分代码,这就是我的经验:
在Movie.kt
data class Movie (
@SerializedName("id") val id: Int,
@SerializedName("title") val title: String,
@SerializedName("poster_path") val posterPath: String,
@SerializedName("release_date") val releaseDate: String,
@SerializedName("vote_average") val rating: Float
)
在MoviesResponse.kt
data class MoviesResponse (
@SerializedName("page") val page: Int,
@SerializedName("total_results") val totalResults: Int,
@SerializedName("results") val movies: List<Movie>,
@SerializedName("total_pages") val totalPages: Int
)
在TMDbApi.kt
interface TMDbApi {
@GET("movie/popular")
fun getPopularMovies (
@Query("api_key") apiKey: String,
@Query("language") language: String,
@Query("page") page: Int
): Call<List<MoviesResponse>>
}
在OnGetMoviesCallback.kt
interface OnGetMoviesCallback {
fun onSuccess(movies: List<Movie>)
fun onError()
}
在MainAdapter.kt
class MainAdapter: RecyclerView.Adapter<CustomHolder>(){
var movies: List<Movie> = listOf()
fun MainAdapter(movies: List<Movie>) {
this.movies = movies
}
override fun getItemCount(): Int {
return movies.size
}
override fun onBindViewHolder(holder: CustomHolder, position: Int) {
holder.bind(movies.get(position))
holder?.setOnClick()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomHolder {
val layoutInflater = LayoutInflater.from(parent?.context)
val cellForRow = layoutInflater.inflate(R.layout.movie_row, parent, false)
return CustomHolder(cellForRow)
}
}
class CustomHolder(view: View): RecyclerView.ViewHolder(view){
fun bind(result: Movie){
itemView.title.text = result.title
itemView.release_date.text = result.releaseDate
}
}
在MoviesRepository.kt
val BASE_URL: String = "https://api.themoviedb.org/3/"
val LANGUAGE: String = "en-US"
data class MoviesRepository (
val repositroy: MoviesRepository,
val api: TMDbApi
)
object getInstance{
val retrofit: TMDbApi = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.client(OkHttpClient().newBuilder().build())
.baseUrl(BASE_URL)
.build()
.create(TMDbApi::class.java)
}
在AllMoviesActivity.kt
class AllMoviesActivity : AppCompatActivity(), Callback<List<MoviesResponse>> {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_all_movies)
rw_main.layoutManager = LinearLayoutManager(this)
rw_main.adapter = MainAdapter()
getMovies()
}
private fun getMovies() {
getInstance.retrofit.getPopularMovies("2B0b0e8d104f0d6130a4fc67848f89e107", LANGUAGE, 1).enqueue(this)
}
override fun onResponse(call: retrofit2.Call<List<MoviesResponse>>, response: Response<List<MoviesResponse>>) {
val moviesResponse = response.body() ?: listOf()
Log.d("Results", moviesResponse.toString())
}
override fun onFailure(call: retrofit2.Call<List<MoviesResponse>>, t: Throwable) {
Toast.makeText(this, "Failed", Toast.LENGTH_SHORT).show()
}
}
我已经在清单文件中添加了Internet权限。运行此命令时,出现“失败”的吐司,但看不到RecyclerView。你能告诉我我想念的是什么吗?我一直在搜索Internet解决方案,但没有结果。希望你能帮助我。谢谢!
答案 0 :(得分:0)
好像您缺少一些小东西。在邮递员上调用API后,您在响应正文中的期望如下:
{
"page": 1,
"total_results": 10000,
"total_pages": 500,
"results": [...
}
在 TMDbApi.kt 中显示了这一点,让您摘要了一下,您已经指出,您期望的响应是List<MoviesResponse>
,它与您收到的响应是JSON冲突类型为MoviesResponse
的类型,
修复:
...): Call<List<MoviesResponse>>
}
收件人:
): Call<MoviesResponse>
}
其余的都是一些小补丁,可以调整您的响应处理。
转到 AllMoviesActivity.kt 并更改以下内容:
class AllMoviesActivity : AppCompatActivity(), Callback<List<MoviesResponse>> {
到
class MainActivity : AppCompatActivity(), Callback<MoviesResponse>
然后在回调函数上,如下更改签名:
override fun onResponse(call: retrofit2.Call<List<MoviesResponse>>, response: Response<List<MoviesResponse>>) {
val moviesResponse = response.body() ?: listOf() ...
收件人:
override fun onResponse(call: Call<MoviesResponse>, response:Response<MoviesResponse>
) {
val moviesResponse = response.body()//type will be inferred ...
最后,
override fun onFailure(call: retrofit2.Call<List<MoviesResponse>>, t: Throwable) {
收件人:
override fun onFailure(call: Call<MoviesResponse>, t: Throwable) {
这是获得响应并使 Failure 吐司保持沉默的基本条件。
将日志设为您的朋友,他们可以显示混乱且最小的未命中