#android #user-interface #android-livedata #kotlin-coroutines
#Android #пользовательский интерфейс #android-livedata #kotlin-сопрограммы
Вопрос:
Я начинаю с архитектуры MVVM и реактивного программирования Kotlin. Как я могу использовать kotlin LiveData, Coroutines and/or Observable
для выполнения в optionSelected()
функции возврата только после того, как пользователь нажмет кнопки par1 или par2, чтобы вернуть содержимое во второе время insertionSort()
функции?
class PlaceholderFragment : Fragment() {
var par1:Button? = null
var par2:Button? = null
var parTextLive: LiveData<String> = MutableLiveData<String>()
var arr = arrayOf("homework", "chores", "shopping")
var i = -1
var j: Int = 0
var tmp: String = ""
var clicked: Boolean = false
var parText: String = ""
var len: Int = arr.size
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 {
insertionSort()
}
par1!!.setOnClickListener {
lifecycleScope.launch {
//how to get in LiveData the String value?
//parTextLive = (par1!!.text.toString())
parText = (par1!!.text.toString())
}
}
par2!!.setOnClickListener {
lifecycleScope.launch {
//how to get in LiveData the String value?
//parTextLive = (par2!!.text.toString())
parText = (par2!!.text.toString())
}
}
return root
}
suspend fun optionSelected(str1: String, str2: String): String {
return withContext(Dispatchers.Main) {
println("opções setadas: $str1 or $str2")
par1!!.text = str1
par2!!.text = str2
// I setted the buttons pair1 and pair2 with texts of str1 and str2. When the user click in one of them, I want to return the text of clicked button
delay(5000) //substitute the delay by the user click event
return@withContext str1 //returning the variable parTextLive with the refreshed value
}
}
suspend fun insertionSort(): Array<String> {
return withContext(Dispatchers.Default) {
while(len-- != 0) {
tmp = arr[ i];
j = i
while (j-- != 0 amp;amp; (optionSelected(arr[j], tmp) == arr[j])) {
arr[j 1] = arr[j];
}
arr[j 1] = tmp
}
return@withContext arr.apply { reverse() }
}
}
}
Комментарии:
1. Во-первых, я хочу, чтобы вы поняли использование
LiveData
. TLDR; Он предназначен для использования сViewModel
, и действие должно реагировать только на события. Если вы все еще не можете понять, не стесняйтесь связаться со мной здесь.
Ответ №1:
Чтобы присвоить значение MutableLiveData, я использовал parTextLive.value
ожидание получения значения LiveData щелчком мыши, я использовал parTextLive.asFlow().first()
, он ждет, пока parTextLive
не получит некоторое значение
class PlaceholderFragment : Fragment() {
var par1:Button? = null
var par2:Button? = null
var parTextLive: LiveData<String> = MutableLiveData<String>()
var arr = arrayOf("homework", "chores", "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 {
insertionSort(arr)
}
par1!!.setOnClickListener {
lifecycleScope.launch {
parTextLive.value = (par1!!.text.toString())
}
}
par2!!.setOnClickListener {
lifecycleScope.launch {
parTextLive.value = (par2!!.text.toString())
}
}
return root
}
suspend fun optionSelected(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())
parTextLive = MutableLiveData<String>()
return@withContext parText
}
}
suspend fun insertionSort(): Array<String> {
return withContext(Dispatchers.Default) {
while(len-- != 0) {
tmp = arr[ i];
j = i
while (j-- != 0 amp;amp; (optionSelected(arr[j], tmp) == arr[j])) {
arr[j 1] = arr[j];
}
arr[j 1] = tmp
}
return@withContext arr.apply { reverse() }
}
}
}