我正在尝试实例化ViewModel,以便根据给定的参数显示不同的列表。然而,我对init和构造函数的调用有点困惑。
下面的版本给了我一个MainViewModel> has no zero argument constructor
错误。
版本1
class MainViewModel(private val param: String) : ViewModel() {
private var list: ArrayList<ModelDialogOption>? = null
val userMutableLiveData: MutableLiveData<ArrayList<ModelDialogOption>?> = MutableLiveData()
init {
populateList()
userMutableLiveData.value = list!!
}
private fun populateList() {
list = ArrayList()
when (param) {
"Choose your age range" -> {
list!!.add(ModelDialogOption("Prefer not to say", false))
list!!.add(ModelDialogOption("16-39", false))
list!!.add(ModelDialogOption("40-59", true))
list!!.add(ModelDialogOption("60+", false))
}
}
}
}
版本2
然而,这给了我一个找不到参数的空列表,因为构造函数只有在初始化之后才被调用:
class MainViewModel() : ViewModel() {
var param: String? = null
private var list: ArrayList<ModelDialogOption>? = null
val userMutableLiveData: MutableLiveData<ArrayList<ModelDialogOption>?> = MutableLiveData()
init {
populateList()
userMutableLiveData.value = list!!
}
constructor(param: String) : this() {
this.param = param
populateList()
userMutableLiveData.value = list!!
}
private fun populateList() {
list = ArrayList()
when (param) {
"Choose your age range" -> {
list!!.add(ModelDialogOption("Prefer not to say", false))
list!!.add(ModelDialogOption("16-39", false))
list!!.add(ModelDialogOption("40-59", true))
list!!.add(ModelDialogOption("60+", false))
}
}
}
}
这里还有另一个空列表:
版本3
class MainViewModel() : ViewModel() {
var param: String? = null
private var list: ArrayList<ModelDialogOption>? = null
val userMutableLiveData: MutableLiveData<ArrayList<ModelDialogOption>?> = MutableLiveData()
constructor(param: String) : this() {
this.param = param
populateList()
userMutableLiveData.value = list!!
}
private fun populateList() {
list = ArrayList()
when (param) {
"Choose your age range" -> {
list!!.add(ModelDialogOption("Prefer not to say", false))
list!!.add(ModelDialogOption("16-39", false))
list!!.add(ModelDialogOption("40-59", true))
list!!.add(ModelDialogOption("60+", false))
}
}
}
}
版本4
这给了我列表填充,但肯定没有参数,因为没有传递任何参数,只是将其用作我的起点:
class MainViewModel : ViewModel() {
private var list: ArrayList<ModelDialogOption>? = null
val userMutableLiveData: MutableLiveData<ArrayList<ModelDialogOption>?> = MutableLiveData()
init {
populateList()
userMutableLiveData.value = list!!
}
private fun populateList() {
list = ArrayList()
list!!.add(ModelDialogOption("Prefer not to say", false))
list!!.add(ModelDialogOption("16-39", false))
list!!.add(ModelDialogOption("40-59", true))
list!!.add(ModelDialogOption("60+", false))
}
}
这是我的ViewModelFactory:
public class MyViewModelFactory implements ViewModelProvider.Factory {
private String param;
public MyViewModelFactory(String param) {
this.param = param;
}
@NotNull
@Override
public <T extends ViewModel> T create(@NotNull Class<T> modelClass) {
return (T) new MainViewModel(param);
}
}
以这种方式启动:
private val viewModel: MainViewModel by activityViewModels {
MyViewModelFactoryForHashMap(
arguments?.getString("headerText")
)
}
非常感谢。
自从我回答了你的最后一个问题以来,我对你的代码流了解甚少
您不应该在ViewModel中传递param,而应该更新它,因为您正在共享和侦听两个片段
class CovidCheckInFragment : Fragment(R.layout.fragment_covid_check_in) {
var navController: NavController? = null
private val model: MainViewModel by activityViewModels()
private lateinit var tartTextView:TextView
@RequiresApi(Build.VERSION_CODES.M)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
tvHeader.text = "COVID Check-in"
navController = Navigation.findNavController(view)
// Listeners
etYourAge.setOnClickListener(onClick)
etYourCounty.setOnClickListener(onClick)
etYourLocality.setOnClickListener(onClick)
rbFemale.setOnClickListener(onClickRb)
rbMale.setOnClickListener(onClickRb)
rbPreferNotToSay.setOnClickListener(onClickRb)
model.userMutableLiveData.observe(viewLifecycleOwner, Observer {
it?.let {
it.filter {
it.selected == true
}.map {
tartTextView.text = it.title
}
}
})
}
private val onClick = View.OnClickListener {
val destination: Int = R.id.action_covidCheckInFragment_to_my_dialog_fragment
val message: String? = when (it.id) {
R.id.etYourAge -> {
tartTextView = etYourAge
model.updateList("Choose your age range")
"Choose your age range"
}
R.id.etYourCounty -> {
tartTextView = etYourCounty
model.updateList("Choose your county")
"Choose your county"
}
R.id.etYourLocality -> {
tartTextView = etYourLocality
model.updateList("Choose your locality")
"Choose your locality"
}
else -> {
""
}
}
val bundle = bundleOf("headerText" to message)
navController = Navigation.findNavController(it)
navController!!.navigate(
destination,
bundle
)
}
@RequiresApi(Build.VERSION_CODES.M)
private val onClickRb = View.OnClickListener {
val list = listOf<Button>(rbFemale, rbMale, rbPreferNotToSay)
for (i in list) {
i.setTextColor(resources.getColor(R.color.text))
i.background.setTint(ContextCompat.getColor(activity as MainActivity, R.color.greyEee))
}
if ((it as AppCompatRadioButton).isChecked) {
it.setTextColor(resources.getColor(R.color.white))
it.background.setTint(ContextCompat.getColor(activity as MainActivity, R.color.shadow))
}
}
}
这是您的MainViewModel
class MainViewModel : ViewModel() {
private var list = ArrayList<ModelDialogOption>()
val userMutableLiveData: MutableLiveData<ArrayList<ModelDialogOption>> = MutableLiveData()
fun updateItem(position: Int) {
val itemToUpdate = list[position]
itemToUpdate.selected = !itemToUpdate.selected!!
list[position] = itemToUpdate
}
fun flushItems() {
userMutableLiveData.value = list
}
fun updateList(param: String) {
list = ArrayList()
when (param) {
"Choose your age range" -> {
list.add(ModelDialogOption("Prefer not to say", false))
list.add(ModelDialogOption("16-39", false))
list.add(ModelDialogOption("40-59", false))
list.add(ModelDialogOption("60+", false))
}
"Choose your county" -> {
list.add(ModelDialogOption("Prefer not to say", false))
list.add(ModelDialogOption("County1", false))
list.add(ModelDialogOption("County2", false))
list.add(ModelDialogOption("County3", false))
}
"Choose your locality" -> {
list.add(ModelDialogOption("Prefer not to say", false))
list.add(ModelDialogOption("Locality1", false))
list.add(ModelDialogOption("Locality2", false))
list.add(ModelDialogOption("Locality3", false))
}
}
flushItems()
}
}