{"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\/es\/blog\/news\/sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet","title":{"rendered":"\u00bfC\u00f3mo funciona la creaci\u00f3n de una calculadora de propinas en Kotlin?","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"\u00bfC\u00f3mo funciona la creaci\u00f3n de una calculadora de propinas en Kotlin?\" src=\"\/wp-content\/uploads\/2019\/04\/faaae0beaf023f1c11bb9102312fe429.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nTe mostramos c\u00f3mo crear una aplicaci\u00f3n simple para calcular propinas en el lenguaje Kotlin. M\u00e1s espec\u00edficamente, en Kotlin 1.3.21, Android 4 y Android Studio 3. Este art\u00edculo ser\u00e1 interesante, sobre todo, para aquellos que comienzan su camino en el desarrollo de aplicaciones Android. Permite entender qu\u00e9 y c\u00f3mo funciona dentro de la aplicaci\u00f3n. <\/p>\n<p>Esta calculadora ser\u00e1 \u00fatil cuando necesites calcular la suma de propinas para un grupo que ha decidido pasar tiempo en un restaurante o caf\u00e9. Por supuesto, no todos y no siempre dejan propina a los camareros, es m\u00e1s una tradici\u00f3n occidental, pero el proceso de desarrollo de dicha aplicaci\u00f3n es interesante de todos modos. <br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<blockquote><p><b>Recordamos:<\/b> <i>para todos los lectores de \u00abHabr\u00bb \u2014 un descuento de 10,000 rublos al registrarse en cualquier curso de Skillbox usando el c\u00f3digo promocional \u00abHabr\u00bb.<\/i><\/p>\n<p><b>Skillbox recomienda:<\/b> Curso pr\u00e1ctico <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\">\u00abDesarrollador m\u00f3vil PRO<\/a><\/noindex>.\n<\/p><\/blockquote>\n<p>\nAs\u00ed es como se ve la aplicaci\u00f3n en funcionamiento:<\/p>\n<p><img decoding=\"async\" alt=\"\u00bfC\u00f3mo funciona la creaci\u00f3n de una calculadora de propinas en Kotlin?\" src=\"\/wp-content\/uploads\/2019\/04\/fa375744a4ca5d07667ec494db38648b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nIngresas el porcentaje deseado de la suma total, el n\u00famero de participantes en la reuni\u00f3n y obtienes el resultado: la cantidad de propina a dejar.<\/p>\n<h3>Empezamos<\/h3>\n<p>\nLa interfaz completa de la aplicaci\u00f3n se ve de la siguiente manera:<br \/>\n<img decoding=\"async\" alt=\"\u00bfC\u00f3mo funciona la creaci\u00f3n de una calculadora de propinas en Kotlin?\" src=\"\/wp-content\/uploads\/2019\/04\/e95058f09c4a6c151b6c5500ae549c0e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\n<img decoding=\"async\" alt=\"\u00bfC\u00f3mo funciona la creaci\u00f3n de una calculadora de propinas en Kotlin?\" src=\"\/wp-content\/uploads\/2019\/04\/ac31c73ade24640078c76d71700de0b4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nLa primera acci\u00f3n es <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lawreyios\/tipcalculator\/tree\/starter_project\">cargar la base del proyecto<\/a><\/noindex>. La abrimos en Android Studio 3.0 o una versi\u00f3n m\u00e1s reciente. Compilamos y ejecutamos el proyecto y vemos una pantalla blanca. Todo est\u00e1 bien, as\u00ed debe ser.<\/p>\n<p><img decoding=\"async\" alt=\"\u00bfC\u00f3mo funciona la creaci\u00f3n de una calculadora de propinas en Kotlin?\" src=\"\/wp-content\/uploads\/2019\/04\/f4e3361ddc45d56794cc5c7c36d8b206.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\n<img decoding=\"async\" alt=\"\u00bfC\u00f3mo funciona la creaci\u00f3n de una calculadora de propinas en Kotlin?\" src=\"\/wp-content\/uploads\/2019\/04\/7828c10dcb3936eb095f5110094ea8bf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nLas acciones del usuario est\u00e1n escritas en el proyecto en orden cronol\u00f3gico para que todo sea claro. Para verlas, abrimos Ver -&gt; Ventanas de herramientas -&gt; TODO.<\/p>\n<p>Exploramos el proyecto y abrimos colors.xml para evaluar la paleta de colores. En strings.xml se encuentran los datos de texto (etiquetas), y en styles.xml hay varias plantillas de fuentes.<\/p>\n<h3>Desarrollo de la secci\u00f3n de gastos<\/h3>\n<p>\nAbrimos activity_main.xml y agregamos el siguiente c\u00f3digo en LinearLayout (#1):<\/p>\n<pre><code class=\"kotlin\"><\/code><\/pre>\n<p>\nAhora se puede ajustar el estilo del directorio values o jugar con los colores utilizando <noindex><a rel=\"nofollow\" href=\"https:\/\/material.io\/tools\/color\/#!\/?view.left=0&amp;view.right=0&amp;primary.color=37474F\">la herramienta material.io<\/a><\/noindex>.<\/p>\n<p>As\u00ed es como se ve el proyecto ahora:<\/p>\n<p><img decoding=\"async\" alt=\"\u00bfC\u00f3mo funciona la creaci\u00f3n de una calculadora de propinas en Kotlin?\" src=\"\/wp-content\/uploads\/2019\/04\/ab47023cafd97fdbd171a9d9a1c35dd5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i> Como puedes ver, el c\u00e1lculo de gastos se realiza en base a los datos introducidos por el usuario. <\/i><\/p>\n<h3>Desarrollo de la secci\u00f3n de cuentas<\/h3>\n<p>\nAgregamos el c\u00f3digo a continuaci\u00f3n en LinearLayout despu\u00e9s de la Secci\u00f3n de Gastos (#2):<\/p>\n<pre><code class=\"kotlin\">&lt;! \u2014 TODO #3: Build Bill Section \u2192\n \n\u2026<\/code><\/pre>\n<p>\nCerramos el LinearLayout despu\u00e9s de la lista de tareas pendientes y luego a\u00f1adimos nuevo c\u00f3digo, coloc\u00e1ndolo dentro de LinearLayout (#3):<\/p>\n<pre><code class=\"kotlin\"><\/code><\/pre>\n<p>\nDado que la principal tarea de la aplicaci\u00f3n es calcular los gastos individuales de cada uno de los participantes en la cena, el Texto costPerPersonTextView tiene una gran importancia. <\/p>\n<p>EditText limita la entrada de datos a una l\u00ednea; este par\u00e1metro debe tener el valor NumberDecimal inputType.<\/p>\n<p><img decoding=\"async\" alt=\"\u00bfC\u00f3mo funciona la creaci\u00f3n de una calculadora de propinas en Kotlin?\" src=\"\/wp-content\/uploads\/2019\/04\/7dc4e90d8188a08933e7a92b119472ee.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i> Iniciamos el proyecto para probar y ingresamos los par\u00e1metros de da\u00f1o total (tazas, platos rotos, etc.)<\/i><\/p>\n<h3>Desarrollo de la secci\u00f3n 'Personas y Propinas'<\/h3>\n<p>\nPara agregar la opci\u00f3n de elegir el monto de la propina, insertamos el siguiente c\u00f3digo en la nueva secci\u00f3n LinearLayout (#4):<\/p>\n<pre><code class=\"kotlin\"><\/code><\/pre>\n<p>\nEste fragmento de c\u00f3digo es necesario para calcular con precisi\u00f3n la cantidad de propina. El valor predeterminado del texto es 20. Los ImageButtons est\u00e1n equipados con \u00edconos en la carpeta con permisos de escritura.<\/p>\n<p>Copiamos completamente la secci\u00f3n y a\u00f1adimos lo siguiente (#5):<\/p>\n<ul>\n<li> IDs de ImageButton (subtractPeopleButton, addPeopleButton)<\/li>\n<li> IDs de TextView (numberOfPeopleStaticText, numberOfPeopleTextView)<\/li>\n<li> DefaultText para numberOfPeopleTextView (debe ser 4).<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"\u00bfC\u00f3mo funciona la creaci\u00f3n de una calculadora de propinas en Kotlin?\" src=\"\/wp-content\/uploads\/2019\/04\/df99acfb33c3d27126db807b805c9c87.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAhora, al iniciar la aplicaci\u00f3n, hay una opci\u00f3n para agregar la cantidad de la cuenta; tambi\u00e9n funcionan los botones 'Agregar\/Substraer', pero por ahora no sucede nada.<\/p>\n<h3>A\u00f1adimos Views<\/h3>\n<p>\nAbrimos MainActivity.kt y a\u00f1adimos esto en la funci\u00f3n 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>Terminamos los botones<\/h3>\n<p>\nPara agregar soporte para los clics de botones, implementamos View.OnClickListener a nivel de clase (#7):<\/p>\n<p>class MainActivity: AppCompatActivity(), View.OnClickListener {<\/p>\n<p>No se podr\u00e1 compilar el proyecto ahora, es necesario realizar algunas acciones adicionales (#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>\nEn cuanto a los botones y switches, todo est\u00e1 muy bien organizado en Kotlin. Agregamos el c\u00f3digo a continuaci\u00f3n en todas las funciones de incremento y decremento<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>\nAqu\u00ed el c\u00f3digo protege las funciones de incremento con valores m\u00e1ximos (MAX_TIP &amp; MAX_PEOPLE). Adem\u00e1s, el c\u00f3digo protege las funciones de decremento con valores m\u00ednimos (MIN_TIP &amp; MIN_PEOPLE).<\/p>\n<p>Ahora vinculamos los botones a los listeners en la funci\u00f3n 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=\"\u00bfC\u00f3mo funciona la creaci\u00f3n de una calculadora de propinas en Kotlin?\" src=\"\/wp-content\/uploads\/2019\/04\/73e7477d4b02548aad7c2112c6be5d80.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAhora se pueden agregar los gastos totales, las propinas y el n\u00famero de participantes en la reuni\u00f3n. Y ahora lo m\u00e1s importante\u2026<\/p>\n<h3>Secci\u00f3n de c\u00e1lculo de gastos<\/h3>\n<p>Este c\u00f3digo calcula los gastos (#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>\nY aqu\u00ed se llama a la funci\u00f3n que permite tener en cuenta el n\u00famero de personas en la compa\u00f1\u00eda y calcular las propinas (#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 lanzando la aplicaci\u00f3n. Se ve y funciona genial. Pero puede ser mejor.<\/p>\n<p>Si intentas eliminar la cantidad de la cuenta y luego aumentar el n\u00famero de propinas o amigos, la aplicaci\u00f3n se caer\u00e1, ya que a\u00fan no hay una verificaci\u00f3n para valores de costos nulos. Adem\u00e1s, si intentas cambiar la cantidad de la cuenta, los gastos no se actualizar\u00e1n.<\/p>\n<h3>Pasos finales<\/h3>\n<p>\nAgregamos TextWatcher (#16):<\/p>\n<p>class MainActivity: AppCompatActivity(), View.OnClickListener, TextWatcher {<\/p>\n<p>Luego embebemos el listener billEditText (#17):<\/p>\n<p>billEditText.addTextChangedListener(this)<\/p>\n<p>Adem\u00e1s, a\u00f1adimos c\u00f3digo para ejecutar 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=\"\u00bfC\u00f3mo funciona la creaci\u00f3n de una calculadora de propinas en Kotlin?\" src=\"\/wp-content\/uploads\/2019\/04\/623256a43c969d8b3a434d10a357c1a0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\n\u00a1Ahora todo funciona perfectamente! Felicitaciones, has escrito tu propio 'Calculador de propinas' en Kotlin.<\/p>\n<p><img decoding=\"async\" alt=\"\u00bfC\u00f3mo funciona la creaci\u00f3n de una calculadora de propinas en Kotlin?\" src=\"\/wp-content\/uploads\/2019\/04\/5650bfecfadf3fd56785b7d6ac72ed87.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<blockquote><p><b>Skillbox recomienda:<\/b><\/p>\n<ul>\n<li>Curso pr\u00e1ctico de dos a\u00f1os <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\">\u00abSoy Desarrollador Web PRO\u00bb<\/a><\/noindex>.<\/li>\n<li>Curso en l\u00ednea <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\">\u00abDesarrollador C#\u00bb<\/a><\/noindex>.<\/li>\n<li>Curso pr\u00e1ctico de un a\u00f1o <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\">\u00abDesarrollador PHP desde 0 hasta PRO\u00bb<\/a><\/noindex>.\n<\/li>\n<\/ul>\n<\/blockquote>\n<p>Fuente: <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\/es\/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=\"es_ES\" \/>\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\/es\/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\udd47Creando un calculador de propinas en Kotlin: \u00bfc\u00f3mo funciona? | ProHoster","description":"Te contamos c\u00f3mo crear uno simple.","canonical_url":"https:\/\/prohoster.info\/es\/blog\/news\/sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","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\/es\/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\/es\/wp-json\/wp\/v2\/posts\/31843","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=31843"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/31843\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/23712"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=31843"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=31843"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=31843"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}