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

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 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.

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="do_you_want_to_proceed">Do you want to proceed?</string>

@ Add to your "util" package (where you put the technical stuff):

Code: Select all
import android.app.AlertDialog

@ In that package, create the global function modalDialog() (an example of use is provided as a comment inside it):

Code: Select all
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.do_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



IF you want to ((lose weight) OR (have unbelievable (brain function AND mental clarity))) THEN click:




cron
Traffic Counter

free counters

eXTReMe Tracker