I'm gonna write a method like:
object UIBehavior {
fun dialog(context: Context, title: Int | String, message: Int | String){
val dialogObj = AlertDialog.Builder(context)
dialogObj.setTitle(title)
dialogObj.setMessage(message)
}
}
The methods dialogObj.setTitle and dialogObj.setMessage allow two types of parameters, and how can I delare the parameter that can let the method dialog allow only two types Int and String?
You can't do that in Kotlin.
But you can have multiple versions of a function, e.g.
object UIBehavior {
fun dialog(context: Context, titleId: Int, messageId: Int){
val titleString = context.getString(titleId)
val messageString = context.getString(messageId)
dialog(context, titleString, messageString)
}
fun dialog(context: Context, title: String, message: String) {
val dialogObj = AlertDialog.Builder(context)
dialogObj.setTitle(title)
dialogObj.setMessage(message)
}
}
That way you can simply call the function with either ids or strings and it looks like you are using the same function
UIBehavior.dialog(this, R.string.title, R.string.message)
UIBehavior.dialog(this, "title", "message")
You could also use a common supertype of Int
and String
but that would allow a lot more and I wouldn't recommend that.
fun dialog(context: Context, title: Any, messageId: Any){
val titleString = when (title) {
is String -> title
is Int -> context.getString(title)
else -> throw IllegalArgumentException("Unsupported type")
}
val messageString = when ...
...
dialog(context, titleString, messageString)
}
Generics don't work here either because you can't call dialogObj.setTitle(title)
dynamically. It must be known at compile time whether you want to call the Int
or the String
overload of that function. It's also not really different from using Any
.
You could use Generics to have the same method, and check the type in the method body.
Or have two different methods.
You could use Any, but I don't think it is a very nice solution at all.
It would be much better to make both the title and message a String or CharSequence in line with the types setTitle and setMessage take as parameters.
Thank you guys, I was writing codes
interface DialogOption {
val title: Any
val message: Any
val positiveBtnTxt: Any
val negativeBtnTxt: Any
fun confirm(d: DialogInterface, n: Int) {
d.dismiss()
}
fun cancel(d: DialogInterface, n: Int) {
d.dismiss()
}
}
object UIBehavior {
fun dialog(context: Context, opt: DialogOption) {
val dialogObj = AlertDialog.Builder(context)
val title = opt.title
val message = opt.message
val poTxt = opt.positiveBtnTxt
val negTxt = opt.negativeBtnTxt
fun positiveCallback(d: DialogInterface, n: Int) {
opt.confirm(d, n)
}
fun negativeCallback(d: DialogInterface, n: Int) {
opt.cancel(d, n)
}
if (title is String) {
dialogObj.setTitle(title)
} else if (title is Int) {
dialogObj.setTitle(title)
}
if (message is String) {
dialogObj.setMessage(message)
} else if (message is Int) {
dialogObj.setMessage(message)
}
if (poTxt is String) {
dialogObj.setPositiveButton(poTxt, ::positiveCallback)
} else if (poTxt is Int) {
dialogObj.setPositiveButton(poTxt, ::positiveCallback)
}
if ( negTxt is String) {
dialogObj.setNegativeButton(negTxt, ::negativeCallback)
} else if (negTxt is Int) {
dialogObj.setNegativeButton(negTxt, ::negativeCallback)
}
dialogObj.show()
}
}
It works but not sure if it's reasonable