{"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\/pt\/blog\/news\/sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet","title":{"rendered":"Criando uma calculadora de gorjetas em Kotlin: como funciona?","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Criando uma calculadora de gorjetas em Kotlin: como funciona?\" src=\"\/wp-content\/uploads\/2019\/04\/faaae0beaf023f1c11bb9102312fe429.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nVamos explicar como criar um aplicativo simples para calcular gorjetas em Kotlin. Especificamente, Kotlin 1.3.21, Android 4, Android Studio 3. Este artigo ser\u00e1 interessante, especialmente para aqueles que est\u00e3o come\u00e7ando sua jornada no desenvolvimento de aplicativos Android. Ele permite entender como e o que funciona dentro do aplicativo. <\/p>\n<p>Esse calculador ser\u00e1 \u00fatil quando for necess\u00e1rio calcular o valor das gorjetas de um grupo que decidiu passar um tempo em um restaurante ou caf\u00e9. Claro, nem todos e nem sempre deixam gorjetas para os gar\u00e7ons, isso \u00e9 mais uma tradi\u00e7\u00e3o ocidental, mas o processo de desenvolvimento desse aplicativo \u00e9, de qualquer forma, interessante. <br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<blockquote><p><b>Lembramos:<\/b> <i>para todos os leitores do \u00abHabr\u00bb \u2014 desconto de 10.000 rublos na inscri\u00e7\u00e3o em qualquer curso Skillbox com o c\u00f3digo promocional \u00abHabr\u00bb.<\/i><\/p>\n<p><b>A Skillbox recomenda:<\/b> Curso Pr\u00e1tico <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\">Desenvolvedor M\u00f3vel PRO<\/a><\/noindex>.\n<\/p><\/blockquote>\n<p>\nVeja como o aplicativo se apresenta em funcionamento:<\/p>\n<p><img decoding=\"async\" alt=\"Criando uma calculadora de gorjetas em Kotlin: como funciona?\" src=\"\/wp-content\/uploads\/2019\/04\/fa375744a4ca5d07667ec494db38648b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nVoc\u00ea insere a porcentagem desejada sobre o total, o n\u00famero de participantes da reuni\u00e3o e obt\u00e9m o resultado \u2014 o valor das gorjetas a serem deixadas.<\/p>\n<h3>Come\u00e7ar<\/h3>\n<p>\nA interface completa do aplicativo \u00e9 mostrada da seguinte forma:<br \/>\n<img decoding=\"async\" alt=\"Criando uma calculadora de gorjetas em Kotlin: como funciona?\" src=\"\/wp-content\/uploads\/2019\/04\/e95058f09c4a6c151b6c5500ae549c0e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\n<img decoding=\"async\" alt=\"Criando uma calculadora de gorjetas em Kotlin: como funciona?\" src=\"\/wp-content\/uploads\/2019\/04\/ac31c73ade24640078c76d71700de0b4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nPrimeira a\u00e7\u00e3o \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lawreyios\/tipcalculator\/tree\/starter_project\">carregamento da base do projeto<\/a><\/noindex>. Abra-o no Android Studio 3.0 ou vers\u00e3o mais recente. Compile e execute o projeto e voc\u00ea ver\u00e1 uma tela branca. Tudo est\u00e1 normal, \u00e9 assim que deve ser.<\/p>\n<p><img decoding=\"async\" alt=\"Criando uma calculadora de gorjetas em Kotlin: como funciona?\" src=\"\/wp-content\/uploads\/2019\/04\/f4e3361ddc45d56794cc5c7c36d8b206.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\n<img decoding=\"async\" alt=\"Criando uma calculadora de gorjetas em Kotlin: como funciona?\" src=\"\/wp-content\/uploads\/2019\/04\/7828c10dcb3936eb095f5110094ea8bf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAs a\u00e7\u00f5es do usu\u00e1rio est\u00e3o escritas no projeto em ordem cronol\u00f3gica, para que tudo fique claro. Para visualiz\u00e1-las, v\u00e1 em View -&gt; Tool Windows -&gt; TODO.<\/p>\n<p>Examine o projeto e abra colors.xml para avaliar a paleta de cores. No strings.xml est\u00e3o os dados de texto (r\u00f3tulos), e no styles.xml h\u00e1 alguns modelos de fonte.<\/p>\n<h3>Desenvolvimento da se\u00e7\u00e3o de despesas<\/h3>\n<p>\nAbra activity_main.xml e adicione o c\u00f3digo abaixo ao LinearLayout (#1):<\/p>\n<pre><code class=\"kotlin\"><\/code><\/pre>\n<p>\nAgora voc\u00ea pode configurar o estilo do diret\u00f3rio values ou brincar com as cores, usando <noindex><a rel=\"nofollow\" href=\"https:\/\/material.io\/tools\/color\/#!\/?view.left=0&amp;view.right=0&amp;primary.color=37474F\">a ferramenta material.io<\/a><\/noindex>.<\/p>\n<p>Neste momento, o projeto se apresenta assim:<\/p>\n<p><img decoding=\"async\" alt=\"Criando uma calculadora de gorjetas em Kotlin: como funciona?\" src=\"\/wp-content\/uploads\/2019\/04\/ab47023cafd97fdbd171a9d9a1c35dd5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i> Como voc\u00ea pode ver, o c\u00e1lculo das despesas \u00e9 feito com base nos dados que o usu\u00e1rio insere. <\/i><\/p>\n<h3>Desenvolvimento da se\u00e7\u00e3o de contas<\/h3>\n<p>\nAdicione o c\u00f3digo abaixo ao LinearLayout ap\u00f3s a Se\u00e7\u00e3o de Despesas (#2):<\/p>\n<pre><code class=\"kotlin\">&lt;! \u2014 TODO #3: Construir Se\u00e7\u00e3o de Conta \u2192\n\n\u2026<\/code><\/pre>\n<p>\nFechamos o LinearLayout ap\u00f3s a lista de TODOs e, em seguida, adicionamos novo c\u00f3digo, colocando-o dentro do LinearLayout (#3):<\/p>\n<pre><code class=\"kotlin\"><\/code><\/pre>\n<p>\nComo a principal fun\u00e7\u00e3o do aplicativo \u00e9 calcular os custos individuais para cada participante das refei\u00e7\u00f5es no restaurante, o TextView costPerPerson \u00e9 de grande import\u00e2ncia. <\/p>\n<p>O EditText limita a entrada de dados a uma linha, e esse par\u00e2metro deve ter o valor NumberDecimal para inputType.<\/p>\n<p><img decoding=\"async\" alt=\"Criando uma calculadora de gorjetas em Kotlin: como funciona?\" src=\"\/wp-content\/uploads\/2019\/04\/7dc4e90d8188a08933e7a92b119472ee.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i> Executamos o projeto para teste e inserimos os par\u00e2metros de custo total (como copos, pratos quebrados etc.).<\/i><\/p>\n<h3>Desenvolvimento da se\u00e7\u00e3o 'Pessoas e gorjetas'.<\/h3>\n<p>\nPara incluir a escolha do valor da gorjeta, inserimos o c\u00f3digo abaixo na nova se\u00e7\u00e3o LinearLayout (#4):<\/p>\n<pre><code class=\"kotlin\"><\/code><\/pre>\n<p>\nEste trecho de c\u00f3digo \u00e9 necess\u00e1rio para calcular corretamente o valor da gorjeta. O valor padr\u00e3o do texto \u00e9 20. Os ImageButtons t\u00eam \u00edcones na pasta com permiss\u00f5es de grava\u00e7\u00e3o.<\/p>\n<p>Copiamos completamente a se\u00e7\u00e3o e adicionamos o seguinte (#5):<\/p>\n<ul>\n<li> IDs dos ImageButtons (subtractPeopleButton, addPeopleButton)<\/li>\n<li> IDs dos TextViews (numberOfPeopleStaticText, numberOfPeopleTextView)<\/li>\n<li> Valor padr\u00e3o para numberOfPeopleTextView (deve ser 4).<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Criando uma calculadora de gorjetas em Kotlin: como funciona?\" src=\"\/wp-content\/uploads\/2019\/04\/df99acfb33c3d27126db807b805c9c87.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAgora, ao iniciar o aplicativo, h\u00e1 a possibilidade de adicionar o valor da conta, e os bot\u00f5es 'Adicionar\/Subtrair' est\u00e3o funcionando, mas por enquanto, nada acontece.<\/p>\n<h3>Adicionando Views<\/h3>\n<p>\nAbrimos o MainActivity.kt e adicionamos isto na fun\u00e7\u00e3o initViews (#6):<\/p>\n<pre><code class=\"kotlin\">fun\u00e7\u00e3o privada 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: V\u00ednculo de Bot\u00f5es ao Listener\n \n\/\/TODO #16: V\u00ednculo de EditText ao TextWatcher\n }<\/code><\/pre>\n<p><\/p>\n<h3>Finalizando os bot\u00f5es<\/h3>\n<p>\nPara adicionar suporte ao clique dos bot\u00f5es, estamos implementando View.OnClickListener no n\u00edvel da classe (#7):<\/p>\n<p>classe MainActivity: AppCompatActivity(), View.OnClickListener {<\/p>\n<p>N\u00e3o ser\u00e1 poss\u00edvel compilar o projeto agora, precisamos realizar mais algumas etapas (#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>\nEm termos de bot\u00f5es e switches, o Kotlin est\u00e1 muito bem organizado! Adicione o c\u00f3digo abaixo em todas as fun\u00e7\u00f5es increment e decrement<br \/>\n (#9\u200a\u2013#12):<\/p>\n<pre><code class=\"kotlin\">fun\u00e7\u00e3o privada incrementTip() {\n        if (tipPercent != MAX_TIP) {\n            tipPercent += TIP_INCREMENT_PERCENT\n            tipTextView.text = String.format(\"%d%%\", tipPercent)\n        }\n    }\n \nfun\u00e7\u00e3o privada decrementTip() {\n        if (tipPercent != MIN_TIP) {\n            tipPercent -= TIP_INCREMENT_PERCENT\n            tipTextView.text = String.format(\"%d%%\", tipPercent)\n        }\n    }\n \nfun\u00e7\u00e3o privada incrementPeople() {\n        if (numberOfPeople != MAX_PEOPLE) {\n            numberOfPeople += PEOPLE_INCREMENT_VALUE\n            numberOfPeopleTextView.text = numberOfPeople.toString()\n        }\n    }\n \nfun\u00e7\u00e3o privada decrementPeople() {\n        if (numberOfPeople != MIN_PEOPLE) {\n            numberOfPeople -= PEOPLE_INCREMENT_VALUE\n            numberOfPeopleTextView.text = numberOfPeople.toString()\n        }\n    }<\/code><\/pre>\n<p>\nAqui o c\u00f3digo protege as fun\u00e7\u00f5es de incremento com valores m\u00e1ximos (MAX_TIP &amp; MAX_PEOPLE). Al\u00e9m disso, o c\u00f3digo protege as fun\u00e7\u00f5es de decremento com valores m\u00ednimos (MIN_TIP &amp; MIN_PEOPLE).<\/p>\n<p>Agora vamos vincular os bot\u00f5es aos ouvintes na fun\u00e7\u00e3o initViews (#13):<\/p>\n<pre><code class=\"kotlin\">fun\u00e7\u00e3o privada initViews() {\n \n...\n \naddTipButton.setOnClickListener(this)\n        subtractTipButton.setOnClickListener(this)\n \naddPeopleButton.setOnClickListener(this)\n        subtractPeopleButton.setOnClickListener(this)\n \n\/\/TODO #15: V\u00ednculo de EditText ao TextWatcher\n}<\/code><\/pre>\n<p>\n<img decoding=\"async\" alt=\"Criando uma calculadora de gorjetas em Kotlin: como funciona?\" src=\"\/wp-content\/uploads\/2019\/04\/73e7477d4b02548aad7c2112c6be5d80.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAgora podemos adicionar os gastos totais, gorjetas e o n\u00famero de participantes da reuni\u00e3o. E agora o mais importante\u2026<\/p>\n<h3>Se\u00e7\u00e3o de c\u00e1lculo de gastos<\/h3>\n<p>Este c\u00f3digo calcula os gastos (#14):<\/p>\n<pre><code class=\"kotlin\">fun\u00e7\u00e3o privada 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>\nE aqui chamamos a fun\u00e7\u00e3o que permite considerar o n\u00famero de pessoas na empresa e calcular a gorjeta (#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>\nEstamos lan\u00e7ando o aplicativo. Ele parece e funciona muito bem. Mas pode ser ainda melhor.<\/p>\n<p>Se voc\u00ea tentar remover o valor da conta e, em seguida, aumentar o n\u00famero de dicas ou amigos, o aplicativo ir\u00e1 falhar, pois ainda n\u00e3o h\u00e1 verifica\u00e7\u00e3o para o valor de custo zero. Al\u00e9m disso, se voc\u00ea tentar alterar o valor da conta, as despesas n\u00e3o ser\u00e3o atualizadas.<\/p>\n<h3>Etapas finais<\/h3>\n<p>\nAdicionando o TextWatcher (#16):<\/p>\n<p>class MainActivity: AppCompatActivity(), View.OnClickListener, TextWatcher {<\/p>\n<p>Em seguida, incorporamos o ouvinte billEditText (#17):<\/p>\n<p>billEditText.addTextChangedListener(this)<\/p>\n<p>Al\u00e9m disso, adicionamos o c\u00f3digo para realizar o 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=\"Criando uma calculadora de gorjetas em Kotlin: como funciona?\" src=\"\/wp-content\/uploads\/2019\/04\/623256a43c969d8b3a434d10a357c1a0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAgora tudo funciona perfeitamente! Parab\u00e9ns, voc\u00ea escreveu seu pr\u00f3prio \"Calculadora de Gorjetas\" em Kotlin.<\/p>\n<p><img decoding=\"async\" alt=\"Criando uma calculadora de gorjetas em Kotlin: como funciona?\" src=\"\/wp-content\/uploads\/2019\/04\/5650bfecfadf3fd56785b7d6ac72ed87.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<blockquote><p><b>A Skillbox recomenda:<\/b><\/p>\n<ul>\n<li>Curso Pr\u00e1tico de Dois Anos <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\">\u2018Eu Sou um Desenvolvedor Web PRO\u2019<\/a><\/noindex>.<\/li>\n<li>Curso online <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\">\"Desenvolvedor C#\"<\/a><\/noindex>.<\/li>\n<li>Curso pr\u00e1tico de um ano <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\">\"Desenvolvedor PHP do zero ao PRO\"<\/a><\/noindex>.\n<\/li>\n<\/ul>\n<\/blockquote>\n<p>Fonte: <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.3 - 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\/pt\/blog\/news\/sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\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\/pt\/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\udd47 Criando uma calculadora de gorjetas em Kotlin: como isso funciona? | ProHoster","description":"Vamos mostrar como criar um simples.","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/news\/sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","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\/pt\/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\/pt\/wp-json\/wp\/v2\/posts\/31843","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=31843"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/31843\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/23712"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=31843"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=31843"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=31843"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}