检索参数以启动 Android vielmodel(初始化与构造函数)

Retrieve param to initiate Android vielmodel (init vs constructor)

我正在尝试实例化我的 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 中传递参数,因为您正在共享和监听两个片段

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

}