I have an util Kotlin class where I set toolbar title, hide or show toolbar depends on the fragment:
class MyToolbarUtils() {
fun hideToolbar(activity: Activity) {
(activity as MainActivity).supportActionBar!!.hide()
}
fun showToolbar(activity: Activity, tag: String) {
setToolbarTitle(tag, activity)
(activity as MainActivity).supportActionBar!!.show()
}
fun setToolbarTitle(tag: String, activity: Activity) {
var title = ""
when (tag) {
"Main_fragment" -> title = activity.resources.getString(R.string.Main_screen)
"Add_note" -> title = activity.resources.getString(R.string.Add_note)
}
activity.title = title
}
}
how to call showToolbar(...) from Fragment?
I just tried MyToolbarUtils.showToolbar(..)
but it can not be possible
only one way I discover is:
val setToolbarTitle = MyToolbarUtils()
setToolbarTitle.showToolbar(activity, tag)
but there must be better way to do that..
Convert your class into an object which is supposed to work similarly to java static methods.
You can get more info here: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations
Sounds like MyToolbarUtils
should be an object declaration instead of a class.
Another way would be to declare functions inside this class on the top level in a file (not inside any class) and just refer to them by their simple name.
Others answered how to make your functions feel like static methods, but for this use case you have a more idiomatic option.
Extension functions in Kotlin replace static utility classes in Java:
Since all of your functions take an Activity
as a parameter, why not use extension functions and make them extend the Activity
or MainActivity
class instead?
fun MainActivity.hideToolbar() {
supportActionBar!!.hide()
}
fun MainActivity.showToolbar(tag: String) {
setToolbarTitle(tag)
supportActionBar!!.show()
}
fun Activity.setToolbarTitle(tag: String) {
title = when (tag) {
"Main_fragment" -> title = resources.getString(R.string.Main_screen)
"Add_note" -> title = resources.getString(R.string.Add_note)
else -> "" // or did you mean this to be an exception?
}
}
Now they are all in context of your MainActivity
or Activity
classes (the this
is now an instance of one of those), you don't have to go hunt for them in some other unrelated ActivityUtils
class. Whenever you are inside the activity class you can simply:
showToolbar("Main_fragment")
or from somewhere else where you have a reference to an activity:
// you have a reference of MainActivity type
myMainActivity.showToolbar("Main_fragment")
// you have a reference you can cast to MainActivity type
(someActivity as MainActivity).showToolbar("Main_fragment")
// this function works with any Activity
someActivity.setToolbarTitle("Add_note")
Also note that I cleaned up the code a little and used when
as an expression to set the title, and also the removal of var
(it is rare when you need a var
, so always think about how to work with val
). And as an expression the when
will need an else
clause, so I made that the same as you default ""
empty string.
Alternative as Class Methods:
Since all 3 methods all require an instance of MainActivity
(based on their casting), why not just put them into MainActivity
as member functions.
class MainActivity ... {
...
fun hideToolbar() {
supportActionBar!!.hide()
}
fun showToolbar(tag: String) {
setToolbarTitle(tag)
supportActionBar!!.show()
}
fun setToolbarTitle(tag: String) {
title = when (tag) {
"Main_fragment" -> title = resources.getString(R.string.Main_screen)
"Add_note" -> title = resources.getString(R.string.Add_note)
else -> "" // or did you mean this to be an exception?
}
}
}
And call them from any reference to MainActivity
.
Alternative as Object Declaration:
Lastly as suggested by others and for completeness, here they are in a utility class acting similar to statics but instead methods on a singleton object declaration:
object MyToolbarUtils() {
fun hideToolbar(activity: MainActivity) {
activity.supportActionBar!!.hide()
}
fun showToolbar(activity: MainActivity, tag: String) {
setToolbarTitle(activity, tag)
activity.supportActionBar!!.show()
}
fun setToolbarTitle(activity: Activity, tag: String) {
activity.title = when (tag) {
"Main_fragment" -> title = resources.getString(R.string.Main_screen)
"Add_note" -> title = resources.getString(R.string.Add_note)
else -> "" // or did you mean this to be an exception?
}
}
}
But I think this is the worst and least Kotlin-like way to extend functionality of another class. Classes/Objects like SomethingUtils
full of statics means that you probably should be writing extension functions instead.
// Kotlin
@file:JvmName("DemoUtils")
package demo
class ClassInKotlin
fun methodInKotlin() {
}
// Java
new demo.ClassInKotlin();
demo.DemoUtils.methodInKotlin();
Try this. This should work.