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()
}
}
我试图使用 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()
}
}