ViewModelProvider继续以MVI设计模式调用其中的函数

问题描述

我在我的应用程序中将MVI设计模式与协同程序一起使用。但是viewmodelprovider内部的函数会继续触发,从而导致诸如UI始终在应用程序处于前台状态时刷新以及在应用程序关闭时崩溃的问题。请参阅下面的代码

片段:

@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE")
class PinFragment : Fragment(),InflatableFragment by InflatableFragmentDelegate(R.layout.fragment_pin) {

    private var param1: String? = null
    private var param2: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_ParaM1)
            param2 = it.getString(ARG_ParaM2)
        }
    }

    /*override fun onCreateView(
        inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment

        return inflater.inflate(R.layout.fragment_pin,container,false)
    }*/

    override fun onViewCreated(view: View,savedInstanceState: Bundle?) {
        super.onViewCreated(view,savedInstanceState)

        tv_otp!!.showSoftInputOnFocus = false

        with(viewmodelProvider(this).get(Pinviewmodel::class.java)){

            viewLifecycleOwner.lifecycleScope.launch(dispatchers.Main) {
                for (model in models){
                    createShufflePins(intents)
                    fillPinKeyboard(model)
                    enterPins(intents)
                    populateOtpView(model)
                }

            }
        }

        iv_back.setonClickListener {
            tv_otp.text = tv_otp.text.toString().dropLast(1)
        }
    }

    private fun enterPins(intents: Channel<PinIntent>) {

        tv_one.setonClickListener {
            lifecycleScope.launch {
                intents.send(EnterPin(tv_one.text.toString()))
            }
        }

        tv_two.setonClickListener {
            lifecycleScope.launch {
                intents.send(EnterPin(tv_one.text.toString()))
            }
        }

        tv_three.setonClickListener {
            lifecycleScope.launch {
                intents.send(EnterPin(tv_one.text.toString()))
            }
        }

        tv_four.setonClickListener {
            lifecycleScope.launch {
                intents.send(EnterPin(tv_one.text.toString()))
            }
        }

        tv_five.setonClickListener {
            lifecycleScope.launch {
                intents.send(EnterPin(tv_one.text.toString()))
            }
        }

        tv_six.setonClickListener {
            lifecycleScope.launch {
                intents.send(EnterPin(tv_one.text.toString()))
            }
        }

        tv_seven.setonClickListener {
            lifecycleScope.launch {
                intents.send(EnterPin(tv_one.text.toString()))
            }
        }

        tv_eight.setonClickListener {
            lifecycleScope.launch {
                intents.send(EnterPin(tv_one.text.toString()))
            }
        }

        tv_nine.setonClickListener {
            lifecycleScope.launch {
                intents.send(EnterPin(tv_one.text.toString()))
            }
        }

        tv_zero.setonClickListener {
            lifecycleScope.launch {
                intents.send(EnterPin(tv_one.text.toString()))
            }
        }

    }

    private fun populateOtpView(pin: PinModel) {
        if (pin.typedPin!= null){
            val otp = tv_otp.text.toString()+""+pin.typedPin
            tv_otp.text = otp
        }
    }

    private fun createShufflePins(intents: Channel<PinIntent>) {
        lifecycleScope.launch {
            intents.send(
                RequestSufflePins("")
            )
        }
    }

    private fun fillPinKeyboard(model: PinModel) {
        if (model.pinNumbers.isNotEmpty()) {
            val pinNumbers = model.pinNumbers
            tv_one.text = pinNumbers.elementAt(0)
            tv_two.text = pinNumbers.elementAt(1)
            tv_three.text = pinNumbers.elementAt(2)
            tv_four.text = pinNumbers.elementAt(3)
            tv_five.text = pinNumbers.elementAt(4)
            tv_six.text = pinNumbers.elementAt(5)
            tv_seven.text = pinNumbers.elementAt(6)
            tv_eight.text = pinNumbers.elementAt(7)
            tv_nine.text = pinNumbers.elementAt(8)
            tv_zero.text = pinNumbers.elementAt(9)
        }
    }


    override fun onResume() {
        super.onResume()
    }

}

viewmodel:

class Pinviewmodel(

   val models: Channel<PinModel> = Channel(1),val intents: Channel<PinIntent> = Channel(1),private val coroutinescope: Coroutinescope = Coroutinescope(SupervisorJob()+dispatchers.IO)

): viewmodel() {
    init {
        coroutinescope.launch {
            models.send(PinModel())
            for (intent in intents){
                when (intent){
                    is RequestSufflePins -> requestShufflePins(intent)
                    is EnterPin -> enterPin(intent)
                }
            }
        }
    }

    private suspend fun enterPin(intent: EnterPin) {
        val typedPin = intent.typedPin
        models.send(PinModel(typedPin = typedPin))
    }

    private suspend fun requestShufflePins(intent: RequestSufflePins) {
        val response = getShuffledPins(intent)
        models.send(PinModel(response.pinNumbers))
    }

    private fun getShuffledPins(intent: RequestSufflePins): PinModel {
        var pinNumbers = setof("0","8","6","4","2","1","3","5","7","9")
        pinNumbers = pinNumbers.shuffled(Random()).toSet()
        return PinModel(pinNumbers = pinNumbers)
    }

    public override fun onCleared() {
        coroutinescope.cancel()
        intents.cancel()
        models.cancel()
        super.onCleared()
    }
}

模型类:

data class PinModel(val pinNumbers: Set<String> = setof(),val typedPin: String? = null)

意图类:

sealed class PinIntent

data class RequestSufflePins(val a: String):PinIntent()
data class EnterPin(val typedPin: String): PinIntent()

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...