检索参数以启动Android vielmodelinit与构造函数

问题描述

我正在尝试实例化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))

        }

    }

}

}

这里还有一个空列表:

版本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))

        }

    }

}

}

版本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))

}

}

这是我的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")
    )
}

非常感谢您。

解决方法

自从我回答了您的last question后,我对您的代码流程一无所知

您应该更新它,而不是在ViewModel中传递参数,因为您正在共享和监听两个片段

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

}