Kotlin - How to wait for the user to return a function called inside the while loop

Asked

Viewed 249 times

2

I have an algorithm that via console helps the user in sorting a list of items, it works well for the console (code below), but I’m adapting the interface to become an app (as print)

I wanted that as soon as the user clicked one of the two buttons, the function promptInput returned the text corresponding to the button, so that the second while of the insertionSort function worked well replacing the console readline.

inserir a descrição da imagem aqui

override fun onCreateView() {
    val arr = arrayOf("finish homework", "finish chores", "go shopping")
    val result = insertionSort("What needs to be done first", arr)
    println(result.toList())
}

fun promptInput(comparison: String, str1: String, str2: String): String {
    println("$comparison: $str1 or $str2?");
    return readLine()!!
}

fun insertionSort(comparison: String, arr: Array<String>): Array<String> {
    println("arr size: ${arr.size}")
    var len = arr.size
    var i = -1
    var j: Int
    var tmp: String

    while (len-- != 0) {
        tmp = arr[++i];
        j = i
        while (j-- != 0 && (promptInput(comparison, arr[j], tmp) == arr[j])) {
            arr[j + 1] = arr[j];
        }
        arr[j + 1] = tmp
    }

    return arr.apply { reverse() }
}

1 answer

2

I had to use Kotlin’s Livedata and Coroutine to manage asynchronicity, I changed the functions to suspended functions with the use of lifecycleScope to properly manage the function calls and Livedata to use the reactive programming in Kotlin and allow receiving the value immediately updated after the user click on one of the two buttons (par1 or par2)

var par1:Button? = null
var par2:Button? = null
var parTextLive: MutableLiveData<String> = MutableLiveData<String>()

var arr = arrayOf("finish homework", "finish chores", "go shopping")

override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {
        val root = inflater.inflate(R.layout.fragment_main, container, false)
        par1 = root!!.findViewById(R.id.par1) as Button
        par2 = root!!.findViewById(R.id.par2) as Button

        lifecycleScope.launch {
            arr = insertionSort(arr)
            value!!.text=arr.toList().toString()
            par1!!.text="finished"
            par2!!.text="finished"
        }
        par1!!.setOnClickListener {
            lifecycleScope.launch {
                parTextLive.value = (par1!!.text.toString()) //valor da LiveData é atualizado
            }
        }
        par2!!.setOnClickListener {
            lifecycleScope.launch {
                parTextLive.value = (par2!!.text.toString()) //valor da LiveData é atualizado
            }
        }

        return root
    }

    suspend fun promptInput(str1: String, str2: String): String {
        return withContext(Dispatchers.Main) {
            println("opções setadas: $str1 or $str2")
            par1!!.text = str1
            par2!!.text = str2

            val parText = (parTextLive.asFlow().first()) //aguarda até que a variável parTextLive receba um valor

            parTextLive = MutableLiveData<String>()  //zera o valor recebido pra poder aguardar novamente no próximo while

            return@withContext parText  //retorna o valor armzenado recebido
        }
    }

    suspend fun insertionSort(arr: Array<String>): Array<String> {
        return withContext(Dispatchers.Default) {
            var len = arr.size
            var i = -1
            var j: Int
            var tmp: String

            while(len-- != 0) {
                tmp = arr[++i];
                j = i
                println("if-while")
                println(len)

                while (j-- != 0 && (promptInput(arr[j], tmp) == arr[j])) {
                    println("sec while")
                    println(arr[j])
                    println(tmp)
                    arr[j + 1] = arr[j];
                }
                arr[j + 1] = tmp
            }
            return@withContext arr.apply { reverse() }
        }
    }

Browser other questions tagged

You are not signed in. Login or sign up in order to post.