Faire des premières actions graphiques avec Kotlin dans un projet Android [AK 4 UI Native]
Ce tutoriel explique comment réaliser des actions graphiques de base avec Kotlin, dans un projet Android Studio, d’ores et déjà configuré avec Kotlin (cf. Configurer Kotlin dans un projet Android Studio [AK 2]). Le but est de créer une interface graphique simple.
Dans cet article, il est expliqué comment :
- Afficher un message court
- Ouvrir une boîte de dialogue
- Lancer une page Internet
- Proposer d’envoyer un email
- Proposer de partager du contenu
- Lancer un autre écran
- Afficher un message d’erreur
Note : Historiquement, avec le langage Kotlin, la bibliothèque Anko Commons [1] était utilisée pour réaliser des développements classiques liés principalement à l’interface graphique. Puis, les incontournables bibliothèques de développement d’application mobile Android avec le langage Kotlin étaient :
- Splitties [4] : ensemble de bibliothèques Kotlin multiplateformes légères
- KTX [5] : ensemble d’extensions Kotlin soutenues par Google
Par ailleurs, une bonne pratique est d’utiliser le View Binding afin d’accéder facilement aux éléments d’une vue XML (cf. AK-4).
Afficher un message court
Afin de présenter des messages d’information court à l’utilisateur, le SDK Android fournit la classe Toast (cf. documentation officiel).
Avec le SDK Android, cela revient à utiliser la classe Toast,
dont l’import correspond à import android.widget.Toast
, depuis une Activity.
Elle permet de créer un message avec makeText(),
cette dernière prend 3 paramètres :
- le contexte de l’application (
this
depuis une Activity,requireActivity
depuis un Fragment) - le message
- la durée d’affichage long ou court
Enfin, il s’agit d’afficher le message ainsi créé via la fonction show() (l’appel indispensable à ne pas oublier lorsqu’on code à la plage ;).
Toast.makeText(this, "${getString(R.string.text_island)}", Toast.LENGTH_SHORT).show()
ou bien alternativement :
Toast.makeText(this, "${getString(R.string.text_island)}", Toast.LENGTH_LONG).show()
Ouvrir une boite de dialogue
Avec le SDK Android, cela revient à créer une classe DialogFragment (cf. documentation Dialogs), puis à l’utiliser depuis une Activity :
class FireMissilesDialogFragment : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle): Dialog {
return activity?.let {
// Use the Builder class for convenient dialog construction
val builder = AlertDialog.Builder(it)
builder.setMessage(R.string.dialog_fire_missiles)
.setPositiveButton(R.string.fire,
DialogInterface.OnClickListener { dialog, id ->
// FIRE ZE MISSILES!
})
.setNegativeButton(R.string.cancel,
DialogInterface.OnClickListener { dialog, id ->
// User cancelled the dialog
})
// Create the AlertDialog object and return it
builder.create()
} ?: throw IllegalStateException("Activity cannot be null")
}
}
Une alternative est de créer la boîte de dialogue, avec AlertDialog directement dans l’Activity.
Retrouvez le code dans le thème “Interface Utilisateur Native” de l’application “Kotlin pour Android”.
Ouvrir une page Internet
Afin d’ouvrir une page Internet avec le navigateur natif, il s’agit d’utiliser une intention fournit par le SDK Android, tout comme le lancement d’un second écran.
Plus précisément, cela revient à utiliser la classe Intent, comme suit, depuis une Activity :
val url = "https://www.chillcoding.com/"
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse(url)
startActivity(i)
-
Créez la fonction browse() :
private fun browse(url: String) { var browser = Intent(Intent.ACTION_VIEW, Uri.parse("https://"+url)) startActivity(browser) }
-
Appelez la fonction ainsi créée sur un bouton :
findViewById<Button>(R.id.mainBtn).setOnClickListener { browse("www.chillcoding.com") }
Proposer d’envoyer un email
Afin de proposer d’envoyer un email, à l’utilisateur, avec une application native, le SDK Android fournit la classe Intent avec un paramétrage spécifique.
Plus précisément, cela revient à utiliser la classe Intent, instanciée de la façon suivante :
val intent = new Intent(Intent.ACTION_SENDTO);
intent.type = "text/plain"
intent.putExtra(Intent.EXTRA_EMAIL, arrayOf("hello@chillcoding.com"))
intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.subject_feedback))
intent.putExtra(Intent.EXTRA_TEXT, "")
startActivity(Intent.createChooser(intent, "Send Email"))
-
Créez la fonction sendEmail() :
private fun sendEmail(to: String, subject: String, msg: String) { val emailIntent = Intent(Intent.ACTION_SEND) emailIntent.data = Uri.parse("mailto:") emailIntent.type = "text/plain" emailIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf(to)) emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject) emailIntent.putExtra(Intent.EXTRA_TEXT, msg) try { startActivity(Intent.createChooser(emailIntent, getString(R.string.title_send_email))) } catch (ex: ActivityNotFoundException) { toast(R.string.text_no_email_client) } }
-
Appelez la fonction ainsi créée sur un bouton :
sendEmail("macha@chillcoding.com", "Hi", "Hello!")
Proposer de partager du contenu
Afin de proposer de partager du contenu via les applications disponibles, installées au préalable par l’utilisateur (Slack, Messenger, etc.), le SDK Android fournit la classe Intent avec un paramétrage spécifique.
Plus précisément, cela revient à utiliser la classe Intent de la façon suivante :
val intent = Intent(Intent.ACTION_SEND)
intent.type = "text/plain"
intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name))
intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.text_share_app))
startActivity(Intent.createChooser(intent, "Share"))
- Dans un nouveau fichier
Tool.kt
, implémentez la fonction d’extension :fun Context.share(text: Int, subject: Int = R.string.app_name): Boolean { try { val intent = Intent(android.content.Intent.ACTION_SEND) intent.type = "text/plain" intent.putExtra(android.content.Intent.EXTRA_SUBJECT, getString(subject)) intent.putExtra(android.content.Intent.EXTRA_TEXT, getString(text)) startActivity(Intent.createChooser(intent, null)) return true } catch (e: ActivityNotFoundException) { e.printStackTrace() return false } }
-
Appelez la fonction share() :
share(R.string.text_share, R.string.title_share)
Lancer un autre écran
Afin d’empiler un second écran dans la pile d’écrans, le SDK Android fournit la classe Intent (cf. documentation officiel), représentant une intention, à combiner avec startActivity().
Avec le SDK Android, cela revient à utiliser la classe Intent,
dont l’import correspond à import android.content.Intent
, depuis une Activity :
val intent = Intent(this, MySecondaryActivity::class.java)
intent.putExtra("id", 3)
intent.putExtra("name", "Macha")
startActivity(intent)
Note : Les données peuvent être récupérées via arguments.getExtra("givenkey")
(soit arguments.getExtra("id"
) depuis la seconde Activity.
Une alternative est d’utiliser la bibliothèque navigation de Jetpack afin de gérer l’enchainement des écrans de l’application mobile Android (cf. d.android.com: Navigation for responsive UIs).
Afficher un message d’erreur
Afin d’afficher des messages dans la console du développeur Logcat, soit dans la console Android Monitor, le SDK Android fournit la classe Log (cf. documentation officiel). Il s’agit d’utiliser les méthodes Log.i(), Log.e(), etc. Elles prennent 2 paramètres :
- un TAG, une chaine de caractères comprenant le nom de la classe courante
- le message à afficher dans la console
Avec le SDK Android, cela revient à utiliser la classe Log
dont l’import correspond à import android.util.Log
:
Log.i(MainActivity::class.simpleName, "Kotlin is an island")
Retour d’expérience
Finalement, ces implémentations peuvent être codées via des fonctions d’extensions Kotlin. En particulier, cela permet de programmer très rapidement les tâches utilisateurs les plus courantes :
- Voir un message rapide
- Interagir avec une boîte de dialogue
- Ouvrir un autre écran
- Voir une page Internet
- Envoyer un email
- Partager du contenu
La connaissance du SDK Android est alors bienvenue.
Aussi, l’implémentation de ses propres fonctions d’extensions peuvent être restreintes
à un contexte spécifique, c’est-à-dire qu’elles peuvent être appelées depuis
une Activity (context
)
ou bien depuis un Fragment (requireContext
).
Par ailleurs, utiliser une bibliothèque c’est cool, cela dit si elle n’est pas soutenue par Google alors cela peut tomber à l’eau… En effet, mettre à jour une bibliothèque est fastidieux.
Aussi, Google soutient des nouveautés et ces dernières ne sont pas immédiatement adoptées par la communauté. Par exemple, le langage Kotlin a pris plusieurs années avant d’avoir une autorité et prendre la place méri†ée.
Compose c’est de la bombe cela dit il n’est pas intéressant de convertir les UIs XML des anciens projets en @Composable. Cependant avec l’intéropérabilité il est possible de mixer Compose et interface graphique XML.
Pour finir, il est important de savoir ce qu’il y a sous le capot (Cmd
ou Ctrl
+ clique :)
afin de voir les implémentations originales.
Parfois, il est nécessaire de mettre les mains dans le cambouis afin de développer
une fonctionnalité plus évoluée, voir plus complexe, voir plus adaptée à ses besoins.
L’existant est alors une source d’inspiration.
Références :
- GoodBye Anko on GitHub
- Setting up a Material Components theme for Android
- Choose an open source license
- Splitties: All the Android splits
- Android KTX, Part of Android Jetpack.
Partagez ou réagissez sur Twitter.
Vous avez trouvé une erreur ou voulez améliorer cet article ? Editez le directement !