Kotlin: Generic function for modal dialog message window


Topics interesting only for Kotlin / Android / SQLite programmers

Link to this posting

Postby Ursego » 31 Mar 2020, 10:22

THE PROBLEM:

Usually, displaying a modal window requires developers to mix business code, which should be executed on positive response, with the technical boilerplate code (all that garbage with the alert dialog builder). If the business code is not very short (not everybody refactor it to a function!), that results in a terrible mess where the beginning and the end of the dialog building process have a long business fragment between them - unfortunately, there is no real modal window in Kotlin which would allow to ask user firstly, and then branch the business logic depending on the answer.

THE SOLUTION:

The boilerplate code is taken to a generic function, which accepts the function to be executed on positive response (and, optionally, the function to be executed on negative response) - thanks to the Kotlin's ability to pass functions as arguments. So, everything is done in an elegant way: you place the business logic in a well-named function, and pass it to the technical function which does for you al the boring work.

STEPS:

@ Add to your res/values/strings.xml:

Code: Select all
    <string name="yes">YES/string>
    <string name="no">NO</string>
    <string name="are_sure_you_want_to_proceed">Are you sure you want to proceed?</string>

@ Add to your application the "util" package (where you put the technical stuff), if it doesn't exist.

@ In that package, create a file Util.kt (if it doesn't exist) and add the global function modalDialog() to it (an example of use is provided as a comment inside it):

Code: Select all
import android.app.AlertDialog

fun modalDialog ( // http://code.intfast.ca/viewtopic.php?t=828
            title: String? = null,
            msg: String,
            funcToCallOnPositiveResponse: () -> Unit,
            funcToCallOnNegativeResponse: () -> Unit = {/* dummy function, does nothing */},
            context: Context,
            positiveButtonText: String? = context.getString(R.string.yes),
            negativeButtonText: String? = context.getString(R.string.no),
            doYoWantToProceedMsgFragment: String = context.getString(R.string.are_sure_you_want_to_proceed)
    ) {
    val builder = AlertDialog.Builder(context).apply {
        setTitle(title)
        setMessage(msg + "\n\n" + doYoWantToProceedMsgFragment)
        setPositiveButton(positiveButtonText) { _, _ -> funcToCallOnPositiveResponse() }
        setNegativeButton(negativeButtonText) { _, _ -> funcToCallOnNegativeResponse() }
    }
    val dialog: AlertDialog = builder.create()
    dialog.show()

    /* Example of use: ***********************
   
    modalDialog (
        title = getString(R.string.msg__do_you_want_to_take_over_the_world__title), // omit this arg if no title
        msg = getString(R.string.msg__do_you_want_to_take_over_the_world),
        funcToCallOnPositiveResponse = {takeOverTheWorld()},
        funcToCallOnNegativeResponse = {displayMsgYouAreLooser()}, // omit this arg to do nothing on Cancel
        context = this
    )
    *****************************************/
}

As you see, the default button texts are "YES" and "NO", but you can provide custom texts if needed. I preferred to add "YES" and "NO" to the String resources rather than use the Android's built-in resources android.R.string.yes and android.R.string.no since the last ones by some reason display "OK" and "CANCEL" respectively.
User avatar
Ursego
Site Admin
 
Posts: 143
Joined: 19 Feb 2013, 20:33



Ketones are a more high-octane fuel for your brain than glucose. Become a biohacker and upgrade yourself to version 2.0!



cron
Traffic Counter

eXTReMe Tracker