Android RecyclerView 在改造调用成功后显示为空

Android RecyclerView shows up empty after successful retrofit call

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

PlaylistRecyclerAdapter

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
    }
}

在后台线程中改造 returns 数据,因此对 onResponse() 的回调与 UI 是异步的,即数据进来需要一些时间;因此 getPlaylistItems() 方法将在 retrofit 数据上升之前返回。因此它 returns 是 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()            
    }
}