ANDROID 如何通过适配器将 mutableLiveData 绑定到我的 Recyclerview
Posted
技术标签:
【中文标题】ANDROID 如何通过适配器将 mutableLiveData 绑定到我的 Recyclerview【英文标题】:ANDROID How do i bind my mutableLiveData through an adapter to my Recyclerview 【发布时间】:2021-11-17 01:22:46 【问题描述】:首先对不起我的英语不好。 我正在尝试在我的 android APP 中从我自己编写的 Python 后端(REST-API)接收数据。
ApiService.kt:
private const val Base_URL = "http://192.168.178.93:5000/api/"
private val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
private val retrofit = Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.baseUrl(Base_URL)
.build()
interface TodoApiService
@GET("todo")
suspend fun getToDo(): List<ToDo>
object ToDoApi
val retrofitService : TodoApiService by lazy
retrofit.create(TodoApiService::class.java)
MainActivityViewModel.kt:
class MainActivityViewModel : ViewModel()
of the most recent request
private val _status = MutableLiveData<String>()
val status: LiveData<String> = _status
private val _toDo = MutableLiveData<List<ToDo>>()
val toDo: LiveData<List<ToDo>> = _toDo
init
getToDo()
private fun getToDo()
viewModelScope.launch
try
_toDo.value = ToDoApi.retrofitService.getToDo()
_status.value = "Success $_toDo"
catch (e: Exception)
_status.value = "Failure $e.message"
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_
android:layout_
tools:context=".MainActivity"
>
<androidx.recyclerview.widget.RecyclerView
android:scrollbars="vertical"
android:layout_
android:layout_
android:id="@+id/recycler_view"
tools:listitem="@layout/todo_item"/>
</FrameLayout>
todo_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp">
<RelativeLayout
android:layout_
android:layout_
android:padding="8dp">
<TextView
android:id="@+id/text_view_name"
android:layout_
android:layout_
android:text="1"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>
TodoAdapter.kt
class TodoAdapter(private val context: Context, private val Items: List<ToDo>):RecyclerView. Adapter<TodoAdapter.TodoViewHolder>()
class TodoViewHolder(private val view: View) : RecyclerView.ViewHolder(view)
val textView: TextView = view.findViewById(R.id.text_view_name)
override fun getItemCount() = Items.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TodoViewHolder
val adapterLayout = LayoutInflater.from(parent.context)
.inflate(R.layout.todo_item, parent, false)
return TodoViewHolder(adapterLayout)
override fun onBindViewHolder(holder: TodoViewHolder, position: Int)
val ToDo = Items.get(position)
holder.textView.text = context.resources.getString(ToDo.Id.toInt())
MainActivity.kt:
class MainActivity : AppCompatActivity()
private val viewModel = MainActivityViewModel()
private lateinit var binding: ActivityMainBinding
private lateinit var linearLayoutManager: LinearLayoutManager
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
linearLayoutManager = LinearLayoutManager(this)
binding.recyclerView.layoutManager = linearLayoutManager
binding.recyclerView.adapter = TodoAdapter(this, viewModel.toDo.value)
我知道我需要一个适配器来将我的 LiveData 连接到我的 recyclerView。但我无法正确实施。 Android Studio 告诉我,我不能将 MutableLiveData 用于只需要一个普通列表的适配器(必需:找到的列表:列表?。我无法投射,因为数据可能为空。
【问题讨论】:
【参考方案1】:您对 LiveData 的使用不正确。您将其用作简单变量,将其当前值(为空)传递给适配器。 LiveData 用于数据流,需要观察。
我喜欢为 Adapter 类上的数据添加一个 setter:
fun setData(data: List<ToDo>)
Items = data
notifyDataSetChanged()
并在 Activity 中观察 ViewModel 的实时数据,并在新数据到达时更新适配器:
class MainActivity : AppCompatActivity()
private lateinit var adapter: TodoAdapter
override fun onCreate(savedInstanceState: Bundle?)
...
adapter = TodoAdapter(this)
viewModel.todo.observe(this, todos ->
adapter.setData(todos)
...
现在,当您在 ViewModel 中为 LiveData 设置值时,将通知适配器。
【讨论】:
【参考方案2】:这是因为您正在从活动向适配器发送一个可能为空的列表。你必须这样做:
binding.recyclerView.adapter = TodoAdapter(this, viewModel.toDo?.value ?: listOf())
【讨论】:
以上是关于ANDROID 如何通过适配器将 mutableLiveData 绑定到我的 Recyclerview的主要内容,如果未能解决你的问题,请参考以下文章
如何将值从基本适配器传递到 Android 中的 Activity
如何将最新数据附加到android中的自定义基本适配器列表视图?
如何将 getIntent.getStringExtra("username") 放入 android 适配器 onBindViewHolder(@NonNull final Vi
通过适配器在片段之间传递数据(Kotlin Android)