{"id":31843,"date":"2019-10-31T21:43:27","date_gmt":"2019-10-31T18:43:27","guid":{"rendered":"https:\/\/prohoster.info\/blog\/sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet\/"},"modified":"2019-10-31T21:43:27","modified_gmt":"2019-10-31T18:43:27","slug":"sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet","status":"publish","type":"post","link":"https:\/\/prohoster.info\/fr\/blog\/news\/sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet","title":{"rendered":"Cr\u00e9er un calculateur de pourboire en Kotlin : comment \u00e7a fonctionne ?","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Cr\u00e9er un calculateur de pourboire en Kotlin : comment \u00e7a fonctionne ?\" src=\"\/wp-content\/uploads\/2019\/04\/faaae0beaf023f1c11bb9102312fe429.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nNous vous montrons comment cr\u00e9er une simple application pour calculer les pourboires en Kotlin. Plus pr\u00e9cis\u00e9ment, avec Kotlin 1.3.21, Android 4 et Android Studio 3. Cet article sera surtout int\u00e9ressant pour ceux qui commencent leur parcours dans le d\u00e9veloppement d'applications Android. Il permet de comprendre ce qui fonctionne et comment \u00e0 l'int\u00e9rieur d'une application. <\/p>\n<p>Un tel calculateur sera utile lorsque vous devez calculer le montant des pourboires pour un groupe qui a d\u00e9cid\u00e9 de passer du temps dans un restaurant ou un caf\u00e9. Bien s\u00fbr, tout le monde ne laisse pas toujours des pourboires aux serveurs, c'est plut\u00f4t une tradition occidentale, mais le processus de d\u00e9veloppement d'une telle application est de toute fa\u00e7on int\u00e9ressant. <br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<blockquote><p><b>Rappelons-le :<\/b> <i>pour tous les lecteurs de \u00ab Habr \u00bb \u2014 une r\u00e9duction de 10 000 roubles lors de l'inscription \u00e0 tout cours Skillbox avec le code promo \u00ab Habr \u00bb.<\/i><\/p>\n<p><b>Skillbox recommande :<\/b> Cours pratique <noindex><a rel=\"nofollow\" href=\"https:\/\/skillbox.ru\/agima\/?utm_source=skillbox.media&amp;utm_medium=habr.com&amp;utm_campaign=AGIMA&amp;utm_content=articles&amp;utm_term=kotlintips\">D\u00e9veloppeur Mobile PRO<\/a><\/noindex>.\n<\/p><\/blockquote>\n<p>\nVoici \u00e0 quoi ressemble l'application en cours d'ex\u00e9cution :<\/p>\n<p><img decoding=\"async\" alt=\"Cr\u00e9er un calculateur de pourboire en Kotlin : comment \u00e7a fonctionne ?\" src=\"\/wp-content\/uploads\/2019\/04\/fa375744a4ca5d07667ec494db38648b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nVous saisissez le pourcentage d\u00e9sir\u00e9 du montant total, le nombre de participants \u00e0 la rencontre et vous obtenez le r\u00e9sultat : le montant des pourboires \u00e0 laisser.<\/p>\n<h3>Commencer<\/h3>\n<p>\nL'interface compl\u00e8te de l'application ressemble \u00e0 ceci :<br \/>\n<img decoding=\"async\" alt=\"Cr\u00e9er un calculateur de pourboire en Kotlin : comment \u00e7a fonctionne ?\" src=\"\/wp-content\/uploads\/2019\/04\/e95058f09c4a6c151b6c5500ae549c0e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\n<img decoding=\"async\" alt=\"Cr\u00e9er un calculateur de pourboire en Kotlin : comment \u00e7a fonctionne ?\" src=\"\/wp-content\/uploads\/2019\/04\/ac31c73ade24640078c76d71700de0b4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nLa premi\u00e8re action - <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lawreyios\/tipcalculator\/tree\/starter_project\">charger la base du projet<\/a><\/noindex>. Ouvrez-le dans Android Studio 3.0 ou une version ult\u00e9rieure. Construisez et ex\u00e9cutez le projet, et vous verrez un \u00e9cran blanc. Tout va bien, c'est ainsi que cela devrait \u00eatre.<\/p>\n<p><img decoding=\"async\" alt=\"Cr\u00e9er un calculateur de pourboire en Kotlin : comment \u00e7a fonctionne ?\" src=\"\/wp-content\/uploads\/2019\/04\/f4e3361ddc45d56794cc5c7c36d8b206.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\n<img decoding=\"async\" alt=\"Cr\u00e9er un calculateur de pourboire en Kotlin : comment \u00e7a fonctionne ?\" src=\"\/wp-content\/uploads\/2019\/04\/7828c10dcb3936eb095f5110094ea8bf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nLes actions de l'utilisateur sont d\u00e9crites dans le projet dans l'ordre chronologique, afin que tout soit clair. Pour le voir, ouvrez Vue -&gt; Fen\u00eatres d'outils -&gt; TODO.<\/p>\n<p>\u00c9tudiez le projet et ouvrez colors.xml pour \u00e9valuer la palette de couleurs. Les donn\u00e9es textuelles (\u00e9tiquettes) se trouvent dans strings.xml, et plusieurs mod\u00e8les de polices sont pr\u00e9sents dans styles.xml.<\/p>\n<h3>D\u00e9veloppement de la section des d\u00e9penses<\/h3>\n<p>\nOuvrez activity_main.xml et ajoutez le code situ\u00e9 ci-dessous dans LinearLayout (#1) :<\/p>\n<pre><code class=\"kotlin\"><\/code><\/pre>\n<p>\nVous pouvez maintenant configurer le style du r\u00e9pertoire values ou jouer avec les couleurs en utilisant <noindex><a rel=\"nofollow\" href=\"https:\/\/material.io\/tools\/color\/#!\/?view.left=0&amp;view.right=0&amp;primary.color=37474F\">l'outil material.io<\/a><\/noindex>.<\/p>\n<p>Actuellement, le projet ressemble \u00e0 ceci :<\/p>\n<p><img decoding=\"async\" alt=\"Cr\u00e9er un calculateur de pourboire en Kotlin : comment \u00e7a fonctionne ?\" src=\"\/wp-content\/uploads\/2019\/04\/ab47023cafd97fdbd171a9d9a1c35dd5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i> Comme vous pouvez le voir, le calcul des d\u00e9penses est effectu\u00e9 \u00e0 partir des donn\u00e9es saisies par l'utilisateur. <\/i><\/p>\n<h3>D\u00e9veloppement de la section des factures<\/h3>\n<p>\nAjoutez le code ci-dessous dans LinearLayout apr\u00e8s la section des d\u00e9penses (#2) :<\/p>\n<pre><code class=\"kotlin\">&lt;! \u2014 TODO #3: Construire la section de facture \u2192\n\n\u2026<\/code><\/pre>\n<p>\nNous fermons le LinearLayout apr\u00e8s la liste des TODOs, puis nous ajoutons un nouveau code en le pla\u00e7ant \u00e0 l'int\u00e9rieur du LinearLayout (#3) :<\/p>\n<pre><code class=\"kotlin\"><\/code><\/pre>\n<p>\nPuisque la principale t\u00e2che de l'application est de calculer les d\u00e9penses individuelles pour chaque participant \u00e0 la sortie au restaurant, le costPerPersonTextView est d'une importance primordiale. <\/p>\n<p>L'EditText limite l'entr\u00e9e de donn\u00e9es \u00e0 une seule ligne, et ce param\u00e8tre doit avoir la valeur NumberDecimal pour inputType.<\/p>\n<p><img decoding=\"async\" alt=\"Cr\u00e9er un calculateur de pourboire en Kotlin : comment \u00e7a fonctionne ?\" src=\"\/wp-content\/uploads\/2019\/04\/7dc4e90d8188a08933e7a92b119472ee.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i> Nous lan\u00e7ons le projet pour tester et saisissons les param\u00e8tres des dommages totaux (tasses et assiettes cass\u00e9es, etc.).<\/i><\/p>\n<h3>D\u00e9veloppement de la section \"Personnes et pourboires\".<\/h3>\n<p>\nPour ajouter une s\u00e9lection du montant des pourboires, ins\u00e9rez le code ci-dessous dans une nouvelle section LinearLayout (#4) :<\/p>\n<pre><code class=\"kotlin\"><\/code><\/pre>\n<p>\nCe morceau de code est n\u00e9cessaire pour calculer avec pr\u00e9cision le montant des pourboires. La valeur par d\u00e9faut du texte est de 20. Les ImageButtons sont fournis avec des ic\u00f4nes dans le dossier avec des droits d'\u00e9criture.<\/p>\n<p>Nous copions enti\u00e8rement la section et ajoutons ce qui suit (#5) :<\/p>\n<ul>\n<li> Identifiants des ImageButton (subtractPeopleButton, addPeopleButton)<\/li>\n<li> Identifiants des TextView (numberOfPeopleStaticText, numberOfPeopleTextView)<\/li>\n<li> DefaultText pour numberOfPeopleTextView (doit \u00eatre 4).<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Cr\u00e9er un calculateur de pourboire en Kotlin : comment \u00e7a fonctionne ?\" src=\"\/wp-content\/uploads\/2019\/04\/df99acfb33c3d27126db807b805c9c87.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nMaintenant, lors du lancement de l'application, il est possible d'ajouter le montant de la facture, les boutons \u00ab Ajouter\/Soustraire \u00bb fonctionnent \u00e9galement, mais rien ne se passe pour l'instant.<\/p>\n<h3>Ajout de Views<\/h3>\n<p>\nOuvrez MainActivity.kt et ajoutez ceci \u00e0 la fonction initViews (#6) :<\/p>\n<pre><code class=\"kotlin\">private fun initViews() {\n        expensePerPersonTextView = findViewById(R.id.expensePerPersonTextView)\n        billEditText = findViewById(R.id.billEditText)\n \naddTipButton = findViewById(R.id.addTipButton)\n        tipTextView = findViewById(R.id.tipTextView)\n        subtractTipButton = findViewById(R.id.subtractTipButton)\n \naddPeopleButton = findViewById(R.id.addPeopleButton)\n        numberOfPeopleTextView = findViewById(R.id.numberOfPeopleTextView)\n        subtractPeopleButton = findViewById(R.id.subtractPeopleButton)\n \n\/\/TODO #8: Bind Buttons to Listener\n \n\/\/TODO #16: Bind EditText to TextWatcher\n \n}<\/code><\/pre>\n<p><\/p>\n<h3>Finalisation des boutons<\/h3>\n<p>\nPour ajouter le support du clic sur les boutons, nous allons impl\u00e9menter View.OnClickListener au niveau de la classe (#7):<\/p>\n<p>class MainActivity: AppCompatActivity(), View.OnClickListener {<\/p>\n<p>Il ne sera pas possible de compiler le projet maintenant, il reste encore quelques \u00e9tapes \u00e0 effectuer (#8):<\/p>\n<pre><code class=\"kotlin\">override fun onClick(v: View?) {\n        when (v?.id) {\n            R.id.addTipButton -&gt; incrementTip()\n            R.id.subtractTipButton -&gt; decrementTip()\n            R.id.addPeopleButton -&gt; incrementPeople()\n            R.id.subtractPeopleButton -&gt; decrementPeople()\n        }\n    }<\/code><\/pre>\n<p>\nConcernant les boutons et les commutateurs, tout est tr\u00e8s bien organis\u00e9 en Kotlin ! Ajoutez le code ci-dessous dans toutes les fonctions d'incr\u00e9ment et de d\u00e9cr\u00e9ment<br \/>\n (#9\u200a\u2013#12):<\/p>\n<pre><code class=\"kotlin\">private fun incrementTip() {\n        if (tipPercent != MAX_TIP) {\n            tipPercent += TIP_INCREMENT_PERCENT\n            tipTextView.text = String.format(\"%d%%\", tipPercent)\n        }\n    }\n \nprivate fun decrementTip() {\n        if (tipPercent != MIN_TIP) {\n            tipPercent -= TIP_INCREMENT_PERCENT\n            tipTextView.text = String.format(\"%d%%\", tipPercent)\n        }\n    }\n \nprivate fun incrementPeople() {\n        if (numberOfPeople != MAX_PEOPLE) {\n            numberOfPeople += PEOPLE_INCREMENT_VALUE\n            numberOfPeopleTextView.text = numberOfPeople.toString()\n        }\n    }\n \nprivate fun decrementPeople() {\n        if (numberOfPeople != MIN_PEOPLE) {\n            numberOfPeople -= PEOPLE_INCREMENT_VALUE\n            numberOfPeopleTextView.text = numberOfPeople.toString()\n        }\n    }<\/code><\/pre>\n<p>\nCe code prot\u00e8ge les fonctions d'incr\u00e9mentation avec des valeurs maximales (MAX_TIP &amp; MAX_PEOPLE). De plus, il prot\u00e8ge les fonctions de d\u00e9cr\u00e9mentation avec des valeurs minimales (MIN_TIP &amp; MIN_PEOPLE).<\/p>\n<p>Nous allons maintenant lier les boutons aux \u00e9couteurs dans la fonction initViews (#13):<\/p>\n<pre><code class=\"kotlin\">private fun initViews() {\n \n...\n \naddTipButton.setOnClickListener(this)\n        subtractTipButton.setOnClickListener(this)\n \naddPeopleButton.setOnClickListener(this)\n        subtractPeopleButton.setOnClickListener(this)\n \n\/\/TODO #15: Bind EditText to TextWatcher\n}<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Cr\u00e9er un calculateur de pourboire en Kotlin : comment \u00e7a fonctionne ?\" src=\"\/wp-content\/uploads\/2019\/04\/73e7477d4b02548aad7c2112c6be5d80.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nNous pouvons maintenant ajouter le total des d\u00e9penses, des pourboires et le nombre de participants \u00e0 la r\u00e9union. Et maintenant, la chose la plus importante...<\/p>\n<h3>Section des calculs des d\u00e9penses<\/h3>\n<p>Ce code calcule les d\u00e9penses (#14):<\/p>\n<pre><code class=\"kotlin\">private fun calculateExpense() {\n \nval totalBill = billEditText.text.toString().toDouble()\n \nval totalExpense = ((HUNDRED_PERCENT + tipPercent) \/ HUNDRED_PERCENT) * totalBill\n        val individualExpense = totalExpense \/ numberOfPeople\n \nexpensePerPersonTextView.text = String.format(\"$%.2f\", individualExpense)\n \n}<\/code><\/pre>\n<p>\nEt ici, la fonction est appel\u00e9e, ce qui permet de prendre en compte le nombre de personnes dans le groupe et de calculer le pourboire (#15):<\/p>\n<pre><code class=\"kotlin\">private fun incrementTip() {\n \n\u2026\n \n}\n \nprivate fun decrementTip() {\n \n\u2026\n \n}\n \nprivate fun incrementPeople() {\n \n\u2026\n \n}\n \nprivate fun decrementPeople() {\n \n\u2026\n \n}<\/code><\/pre>\n<p>\nNous lan\u00e7ons l'application. Elle est magnifique et fonctionne parfaitement. Mais cela pourrait \u00eatre encore mieux.<\/p>\n<p>Si vous essayez de supprimer le montant de la facture, puis d'augmenter le nombre de pourboires ou d'amis, l'application va planter car il n'y a pas encore de v\u00e9rification pour une valeur de co\u00fbt nulle. De plus, si vous essayez de modifier le montant de la facture, les d\u00e9penses ne seront pas mises \u00e0 jour.<\/p>\n<h3>\u00c9tapes finales<\/h3>\n<p>\nAjoutons TextWatcher (#16) :<\/p>\n<p>class MainActivity: AppCompatActivity(), View.OnClickListener, TextWatcher {<\/p>\n<p>Ensuite, int\u00e9grons l'\u00e9couteur billEditText (#17) :<\/p>\n<p>billEditText.addTextChangedListener(this)<\/p>\n<p>De plus, ajoutons le code pour ex\u00e9cuter TextWatcher (#18) :<\/p>\n<pre><code class=\"kotlin\">override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {\n        if (!billEditText.text.isEmpty()) {\n            calculateExpense()\n        }\n    }\noverride fun afterTextChanged(s: Editable?) {}\n\n    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Cr\u00e9er un calculateur de pourboire en Kotlin : comment \u00e7a fonctionne ?\" src=\"\/wp-content\/uploads\/2019\/04\/623256a43c969d8b3a434d10a357c1a0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nEt maintenant, tout fonctionne parfaitement ! F\u00e9licitations, vous avez cr\u00e9\u00e9 votre propre \u00ab Calculateur de pourboires \u00bb en Kotlin.<\/p>\n<p><img decoding=\"async\" alt=\"Cr\u00e9er un calculateur de pourboire en Kotlin : comment \u00e7a fonctionne ?\" src=\"\/wp-content\/uploads\/2019\/04\/5650bfecfadf3fd56785b7d6ac72ed87.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<blockquote><p><b>Skillbox recommande :<\/b><\/p>\n<ul>\n<li>Cours pratique de deux ans <noindex><a rel=\"nofollow\" href=\"https:\/\/iamwebdev.skillbox.ru\/?utm_source=skillbox.media&amp;utm_medium=habr.com&amp;utm_campaign=WEBDEVPRO&amp;utm_content=articles&amp;utm_term=kotlintips\">\u00ab Je suis D\u00e9veloppeur Web PRO \u00bb<\/a><\/noindex>.<\/li>\n<li>Cours en ligne <noindex><a rel=\"nofollow\" href=\"https:\/\/skillbox.ru\/c-sharp\/?utm_source=skillbox.media&amp;utm_medium=habr.com&amp;utm_campaign=CSHDEV&amp;utm_content=articles&amp;utm_term=kotlintips\">\u00ab D\u00e9veloppeur C# \u00bb<\/a><\/noindex>.<\/li>\n<li>Cours pratique d'un an <noindex><a rel=\"nofollow\" href=\"https:\/\/skillbox.ru\/php\/?utm_source=skillbox.media&amp;utm_medium=habr.com&amp;utm_campaign=PHPDEV&amp;utm_content=articles&amp;utm_term=kotlintips\">\u00abD\u00e9veloppeur PHP de 0 \u00e0 PRO\u00bb<\/a><\/noindex>.\n<\/li>\n<\/ul>\n<\/blockquote>\n<p>Source : <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/skillbox\/blog\/448582\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0420\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0447\u0430\u0435\u0432\u044b\u0445 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 Kotlin. \u0415\u0441\u043b\u0438 \u0442\u043e\u0447\u043d\u0435\u0435, \u0442\u043e Kotlin 1.3.21, Android 4, Android Studio 3. \u0421\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439, \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0441\u0432\u043e\u0439 \u043f\u0443\u0442\u044c \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 Android-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u0438 \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0422\u0430\u043a\u043e\u0439 \u043a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0443\u043c\u043c\u0443 \u0447\u0430\u0435\u0432\u044b\u0445 \u0441 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438, [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":23712,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[702],"tags":[],"class_list":["post-31843","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0420\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/fr\/blog\/news\/sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440\u0430 \u0447\u0430\u0435\u0432\u044b\u0445 \u043d\u0430 Kotlin: \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442? | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0420\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/fr\/blog\/news\/sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:43:27+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:43:27+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Cr\u00e9ation d'un calculateur de pourboires en Kotlin : comment cela fonctionne ? | ProHoster","description":"Nous expliquons comment cr\u00e9er quelque chose de simple.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/news\/sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440\u0430 \u0447\u0430\u0435\u0432\u044b\u0445 \u043d\u0430 Kotlin: \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442? | ProHoster","og:description":"\u0420\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435.","og:url":"https:\/\/prohoster.info\/fr\/blog\/news\/sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:43:27+00:00","article:modified_time":"2019-10-31T18:43:27+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"31843","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 08:07:20","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 03:10:45","updated":"2026-01-21 08:07:20","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/31843","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=31843"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/31843\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/23712"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=31843"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=31843"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=31843"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}