【问题标题】:Kotlin: How to display data?Kotlin:如何显示数据?
【发布时间】:2019-08-20 16:48:30
【问题描述】:

我正在开发这个显示热门电影的应用。我得到了这个日志:“/results:retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall@9daee07”。我完成了所有工作,但在我的 RecyclerView 中没有得到任何结果。我不知道如何显示我获取的数据。这是网址:http://api.themoviedb.org/3/movie/popular?api_key=api_key_goes_here

MovieResponse.kt

data class MovieResponse(
    val page: Int,
    val results: List<Movie>,
    @SerializedName("total_pages") val totalPages: Int,
    @SerializedName("total_results") val totalResults: Int
)

电影.kt

data class Movie(
    val id: Int,
    val overview: String,
    val popularity: Double,
    @SerializedName("poster_path") val posterPath: String,
    @SerializedName("release_date") val releaseDate: String,
    val title: String,
    @SerializedName("vote_average") val voteAverage: Double
)

MainAdapter.kt

package com.example.sloomena.ui

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.sloomena.R
import com.example.sloomena.data.MovieResponse
import kotlinx.android.synthetic.main.movie_details_row.view.*

class MainAdapter: RecyclerView.Adapter<CustomHolder>(){

    val movies: MutableList<MovieResponse> = mutableListOf()

    fun refreshData(newResults: List<MovieResponse>) {
        movies.clear()
        movies.addAll(newResults)
        notifyDataSetChanged()
    }

    override fun getItemCount(): Int {
        return movies.size
    }

    override fun onBindViewHolder(holder: CustomHolder, position: Int) {
        holder.bind(movies.get(position))
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomHolder {
        val layoutInflater = LayoutInflater.from(parent?.context)
        val cellForRow =  layoutInflater.inflate(R.layout.movie_details_row, parent, false)
        return CustomHolder(cellForRow)
    }
}
class CustomHolder(itemView: View): RecyclerView.ViewHolder(itemView){
    fun bind(movie: MovieResponse) {

        itemView.title.text = movie.results.toString()
    }
}

thmdbAPI.kt

interface tmdbAPI {

    @GET("movie/popular")
    fun getPopularMovies(
        @Query("api_key") api_key: String
    ): Call<List<MovieResponse>>
}

Networking.kt

const val BASE_URL = "http://api.themoviedb.org/3/"

object Networking{
    val showSearchService: tmdbAPI = Builder()
        .addConverterFactory(ConverterFactory.converterFactory)
        .client(HttpClient.client)
        .baseUrl(BASE_URL)
        .build()
        .create(tmdbAPI::class.java)
}
object ConverterFactory{
    val converterFactory = GsonConverterFactory.create()
}
object HttpClient{
    val client = OkHttpClient.Builder()
        .addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
        .build()
}

MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        setUpUi()
        findMovies()
    }

    private fun setUpUi() {
        id_recyclerview.layoutManager = LinearLayoutManager(this)
        id_recyclerview.adapter = MainAdapter()
    }

    private fun findMovies() {
        GlobalScope.launch(Dispatchers.Main) {
            val results = Networking.showSearchService.getPopularMovies("api_key_goes_here")
            Log.d("results", results.toString())
        }}
}

在我的 movie_details_row.xml 中有(id_picture_movie、id_movie_realise_date 和标题)。 另外,我不知道如何在 MovieResponse 的 List(Movie) 中获取属性。

【问题讨论】:

  • 请包含完整的错误
  • 没有错误,只有我的日志显示这个'* * * retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall@9daee07'

标签: rest api kotlin


【解决方案1】:

在您设置回收站视图后,您实际上并没有传回任何要显示的项目。所以你要做的是设置它,发送一个网络请求,然后你对这些数据什么都不做。

val mainAdapter = MainAdapter()
...

private fun findMovies() {
        GlobalScope.launch(Dispatchers.Main) {
            val results = Networking.showSearchService.getPopularMovies("0b0e8d104f0d6130a4fc67848f89e107")
            Log.d("results", results.toString())

            //Assuming you're returning a list 
            mainAdapter.refreshData(results)
        }}
}

【讨论】:

  • 是的,我明白了,但仍然不知道如何在 recyclerview 中显示数据。我已经尝试过您所说的,但出现错误'类型不匹配。必需列表,找到调用>'。
  • 您需要添加数据,这是您缺少的步骤。我无法事先推断出results 的类型,但是如果您在结果中查找属性,可能是results.body() 并将其传递进去,那么您可能不会再收到该错误了
【解决方案2】:

1) 如果我是你,我会编辑你的帖子以排除你的 API 密钥。将您的回复粘贴到Pastebin 之类的网站上。将来,请尝试粘贴错误的堆栈跟踪,以使答案的生活更加轻松。

2) 在您的响应数据类中,您可能需要将 @SerializedName 用于您的其他值。自从我使用 Gson 作为我的反序列化器已经有一段时间了,所以这可能是不正确的。这可能是这个的原因“另外,我不知道如何在 MovieResponse 的 List(Movie) 中获取属性。”

3) API 服务的返回类型错误。以下是格式化的 API 调用结果:https://pastebin.com/TQb0YSty。可以看到返回类型不是列表,而是单个 JSON 对象。所以你的Call&lt;List&lt;MovieResponse&gt;&gt; 的返回类型应该是Call&lt;MovieResponse&gt;。这可能是导致ExecutorCallbackCall 错误的原因。

可能还有其他问题,但这些是我立即发现的问题

【讨论】:

  • 谢谢,我会改的 :) 我没有任何错误,我的屏幕上也没有任何显示,只是日志告诉我 smth 是错误的。我更改为@SerializedNameCall&lt;MovieResponse&gt; 但仍然是相同的日志* * * retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall@9daee07你有什么想法如何显示获取的数据吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-19
  • 2021-10-07
  • 2021-08-14
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多