【问题标题】:Android RecyclerView shows up empty after successful retrofit call成功改造调用后,Android RecyclerView 显示为空
【发布时间】:2021-07-26 02:35:17
【问题描述】:

我正在尝试使用 Retrofit 的响应来构建 RecyclerView。但是,我遇到了一个问题,我的 Recycler 变成了空白,而我的日志显示我的 ArrayList 中有来自网络响应的数据。 (在我熟悉 Kotlin 之前,我不想设置 MVVM。)

播放列表回收器适配器

class PlaylistRecyclerAdapter (private val playListNames: Array<String>) :
    RecyclerView.Adapter<PlaylistRecyclerAdapter.PlayListViewHolder>() {

    // Describes an item view and its place within the RecyclerView
    class PlayListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val playlistTextView: TextView = itemView.findViewById(R.id.playlist_name_text)

        fun bind(word: String) {
            playlistTextView.text = word
        }
    }

    // Returns a new ViewHolder
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PlayListViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.playlist_name_item, parent, false)

        return PlayListViewHolder(view)
    }

    // Returns size of data list
    override fun getItemCount(): Int {
        return playListNames.size
    }

    // Displays data at a certain position
    override fun onBindViewHolder(holder: PlayListViewHolder, position: Int) {
        holder.bind(playListNames[position])
    }

}

MainActivity.kt

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

        val recyclerView: RecyclerView = findViewById(R.id.recyclerView)
        val templist = getPlaylistItems()
        //Log.d("RESPONSE", "onCreate: "+templist.get(0).toString())
        
        recyclerView.adapter = PlaylistRecyclerAdapter(templist.toTypedArray())
        recyclerView.adapter?.notifyDataSetChanged()
    }

    private fun getPlaylistItems(): ArrayList<String> {
        var playlisttitles = ArrayList<String>()

        var BASE_URL = "https://flicastdemo.s3.amazonaws.com/jwplayer/"
        val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        val service = retrofit.create(HomeWebService::class.java)
        val call = service.getHomeContent()

        var home = HomeRoot()

        call.enqueue(object : Callback<HomeRoot> {
            override fun onResponse(call: Call<HomeRoot>, response: Response<HomeRoot>) {
                if (response.code() == 200) {
                    home = response.body()

                    if(!home.equals(null))
                    {
                        //Log.e("HOME", "val: " + home.toString())
                        for (i in 0 until home.content.size){

                            val BASE_URL = "https://cdn.jwplayer.com/v2/"
                            val retrofit = Retrofit.Builder()
                                .baseUrl(BASE_URL)
                                .addConverterFactory(GsonConverterFactory.create())
                                .build()

                            val service = retrofit.create(PlaylistWebService::class.java)
                            val call = service.getPlayListItem(home.content.get(i).playlistId) //"1QhdrFVq"

                            call.enqueue(object : Callback<PlaylistRoot> {
                                override fun onResponse(call: Call<PlaylistRoot>, response: Response<PlaylistRoot>) {
                                    if (response.code() == 200) {
                                        var playlistinfo : PlaylistRoot = response.body();
                                        playlisttitles.add(playlistinfo.title)
                                        Log.e("PlaylistTitle!", "onResponseTitle: "+playlistinfo.title)
                                    }
                                }
                                override fun onFailure(call: Call<PlaylistRoot>, t: Throwable) {
                                    Log.d("NO!NO!NO!", "onResponse: "+"NO!")
                                    playlisttitles.add("No Playlist")
                                }
                            })
                        }
                    }
                }
            }
            override fun onFailure(call: Call<HomeRoot>, t: Throwable) {
                Log.d("NO!NO!NO!", "onResponse: "+"NO!")
            }
        })

        return playlisttitles
    }
}

【问题讨论】:

    标签: android kotlin android-recyclerview retrofit2


    【解决方案1】:

    Retrofit 在后台线程中返回数据,因此对onResponse() 的回调与 UI 是异步的,即数据进入需要一些时间;因此,getPlaylistItems() 方法将在改造数据完成之前返回。因此它在val templist = getPlaylistItems() 中返回一个空列表。

    要解决此问题,您可以创建一个侦听器接口,或者只是在 onResponse 回调中构建 RecyclerView:

    override fun onResponse(call: Call<PlaylistRoot>, response: Response<PlaylistRoot>) {
        if (response.code() == 200) {
            var playlistinfo : PlaylistRoot = response.body();
            playlisttitles.add(playlistinfo.title)
            Log.e("PlaylistTitle!", "onResponseTitle: "+playlistinfo.title)
            
            recyclerView.adapter = PlaylistRecyclerAdapter(playlisttitles.toTypedArray())
            recyclerView.adapter?.notifyDataSetChanged()            
        }
    }
    

    【讨论】:

    • 嗯,我有时会失明。哈哈。感谢您指出,我在回复中错过了这两行,并将它们留在了我的 onCreate 中。
    猜你喜欢
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-11
    • 1970-01-01
    • 2021-11-24
    • 2014-12-17
    • 1970-01-01
    相关资源
    最近更新 更多