简体   繁体   中英

Kotlin Elvis Statement with Live Data

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM