We have a common flow pattern in our code base in Android Java, but I am trying to learn Kotlin so I want to try and get the best statement to be used throughout the code. The follow pattern is usually that a user hits a button gets a dialog and we have to build up the data. The line below is what I want to try to make more efficient.
viewModel.getLiveData().value
?.let { viewModel.setTarget(viewModel.getLiveData().value!!.copy(targetNumber = result)) }
?: viewModel.setTarget(Target(result, null))
Here is my basic fragment
class DemoFragment : Fragment(R.layout.fragment_demo_layout) {
private val viewModel: DemoViewModel by viewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btn_toast.setOnClickListener {
Toast.makeText(context, "Hello", Toast.LENGTH_SHORT).show()
}
btn_toast.setOnLongClickListener {
Toast.makeText(context, "Hello long click", Toast.LENGTH_SHORT).show()
true
}
viewModel.getLiveData().observe(viewLifecycleOwner) { target -> updateUI(target) }
btnTargetNumber.setOnClickListener {
val dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_text_entry, null)
AlertDialog.Builder(context)
.setTitle("Enter Target Number")
.setView(dialogView)
.setPositiveButton("OK") { _, _ ->
run {
val result =
dialogView.findViewById<EditText>(R.id.targetNumberInput).editableText.toString()
viewModel.getLiveData().value
?.let { viewModel.setTarget(viewModel.getLiveData().value!!.copy(targetNumber = result)) }
?: viewModel.setTarget(Target(result, null))
}
}.show()
}
}
private fun updateUI(target: Target?) {
btnTargetNumber.text = target?.targetNumber
}
}
Here is the simple view model
class DemoViewModel(private val handle : SavedStateHandle) : ViewModel() {
private val targetData : MutableLiveData<Target> = MutableLiveData()
fun setTarget (target: Target){
targetData.value = target
}
fun getLiveData() : LiveData<Target>
{
return targetData
}
}
You can use it
inside let
to get the non-null value instead of writing whole statement again and set the target
outside let without duplicating statement
viewModel.setTarget(viewModel.getLiveData().value?.let { it.copy(targetNumber = result) }?: Target(result, null))
It could be simplified to a single call to setTarget
and inside the call ?:
will do this with simplification.
viewModel.setTarget(viewModel.getLiveData().value?.copy(targetNumber = result)?:Target(result, null))
In above viewModel.getLiveData().value?.copy(targetNumber = result) this will either execute if value
not null else the part after ?:
ie Target(result, null)
. So you can acheive the same result.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.