web-dev-qa-db-fra.com

Méthode d'appel de la classe Kotlin

J'ai une classe util Kotlin où je définit le titre de la barre d'outils, masquer ou afficher la barre d'outils dépend du 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
    }
}

comment appeler showToolbar (...) depuis Fragment? Je viens d'essayer MyToolbarUtils.showToolbar(..) mais ça ne peut pas être possible

une seule façon que je découvre est:

val setToolbarTitle = MyToolbarUtils()
setToolbarTitle.showToolbar(activity, tag)

mais il doit y avoir une meilleure façon de le faire ..

8
Stepan

Convertissez votre classe en un objet qui est censé fonctionner de manière similaire à = Java méthodes statiques.

Vous pouvez obtenir plus d'informations ici: https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations

12
ilya.dorofeev

Les sons comme MyToolbarUtils devraient être un déclaration d'objet au lieu d'une classe.

Une autre façon serait de déclarer des fonctions à l'intérieur de cette classe au niveau supérieur dans un fichier (pas à l'intérieur d'une classe) et de les désigner simplement par leur nom simple.

4
Alexander Udalov

D'autres ont répondu comment faire de vos fonctions des méthodes statiques, mais pour ce cas d'utilisation, vous avez une option plus idiomatique.

Les fonctions d'extension dans Kotlin remplacent les classes utilitaires statiques en Java:

Puisque toutes toutes vos fonctions prennent un Activity comme paramètre, pourquoi ne pas utiliser fonctions d'extension et les faire étendre la classe Activity ou MainActivity à la place?

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?
    }
}

Maintenant, ils sont tous dans le contexte de vos classes MainActivity ou Activity (le this est maintenant une instance de l'une d'entre elles), vous n'avez pas à aller les chercher dans une autre classe ActivityUtils non liée. Chaque fois que vous êtes dans la classe d'activité, vous pouvez simplement:

showToolbar("Main_fragment")

ou d'un autre endroit où vous avez une référence à une activité:

// 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")

Notez également que j'ai nettoyé un peu le code et utilisé when comme expression pour définir le titre, ainsi que la suppression de var (c'est rare lorsque vous besoin d'un var, alors pensez toujours à la façon de travailler avec val). Et en tant qu'expression, le when aura besoin d'une clause else, donc je l'ai fait de la même manière que vous par défaut "" chaîne vide.

Alternative comme méthodes de classe:

Étant donné que les 3 méthodes nécessitent toutes une instance de MainActivity (en fonction de leur transtypage), pourquoi ne pas simplement les mettre dans MainActivity en tant que fonctions membres.

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?
        }
    }
}

Et appelez-les depuis n'importe quelle référence à MainActivity.

Alternative comme déclaration d'objet:

Enfin, comme suggéré par d'autres et pour être complet, ils sont ici dans une classe d'utilité agissant de manière similaire à la statique mais à la place des méthodes sur un singleton déclaration d'objet :

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?
        }
    }
}

Mais je pense que c'est le pire et le moins comme Kotlin pour étendre les fonctionnalités d'une autre classe. Les classes/objets comme SomethingUtils pleins de statiques signifient que vous devriez probablement écrire fonctions d'extension à la place.

2
Jayson Minard

Créez une classe singleton dans Kotlin en utilisant le mot clé object et appelez la classe singleton Kotlin dans Java comme ci-dessous:

object SampleSingleton {
   fun someMethod() { 
     println("I love coding")
   }
}

Si de Java alors comme suit

public static void main(String args[]) {
   SampleSingleton.INSTANCE.someMethod();
}

ou de la classe Kotlin comme suit

SampleSingleton.someMethod()
0
Alok Gupta