{"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\/sv\/blog\/news\/sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet","title":{"rendered":"Att skapa en dricks-kalkylator i Kotlin: hur fungerar det?","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Att skapa en dricks-kalkylator i Kotlin: hur fungerar det?\" src=\"\/wp-content\/uploads\/2019\/04\/faaae0beaf023f1c11bb9102312fe429.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nVi visar hur man skapar en enkel applikation f\u00f6r att r\u00e4kna dricks p\u00e5 Kotlin-spr\u00e5ket. Mer specifikt, Kotlin 1.3.21, Android 4, Android Studio 3. Artikeln kommer att vara intressant, framf\u00f6r allt f\u00f6r dem som b\u00f6rjar sin v\u00e4g inom utvecklingen av Android-applikationer. Den g\u00f6r det m\u00f6jligt att f\u00f6rst\u00e5 vad som fungerar och hur det fungerar inuti applikationen. <\/p>\n<p>En s\u00e5dan kalkylator \u00e4r anv\u00e4ndbar n\u00e4r man beh\u00f6ver r\u00e4kna ut dricksbeloppet f\u00f6r ett s\u00e4llskap som har best\u00e4mt sig f\u00f6r att tillbringa tid p\u00e5 en restaurang eller ett caf\u00e9. Sj\u00e4lvklart l\u00e4mnar inte alla och inte alltid dricks till servit\u00f6rer, det \u00e4r mer en v\u00e4sterl\u00e4ndsk tradition, men utvecklingsprocessen av en s\u00e5dan applikation \u00e4r intressant i alla fall. <br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<blockquote><p><b>P\u00e5minnelse:<\/b> <i>f\u00f6r alla l\u00e4sare av \"Habr\" \u2014 10 000 rubel rabatt vid registrering f\u00f6r vilken kurs som helst p\u00e5 Skillbox med rabattkoden \"Habr\".<\/i><\/p>\n<p><b>Skillbox rekommenderar:<\/b> Praktisk kurs <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\">Mobilutvecklare PRO<\/a><\/noindex>.\n<\/p><\/blockquote>\n<p>\nS\u00e5 h\u00e4r ser applikationen ut under drift:<\/p>\n<p><img decoding=\"async\" alt=\"Att skapa en dricks-kalkylator i Kotlin: hur fungerar det?\" src=\"\/wp-content\/uploads\/2019\/04\/fa375744a4ca5d07667ec494db38648b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nDu anger \u00f6nskad procentandel av den totala summan, antal deltagare i m\u00f6tet och f\u00e5r resultatet \u2014 dricksbeloppet som b\u00f6r l\u00e4mnas.<\/p>\n<h3>Vi b\u00f6rjar<\/h3>\n<p>\nDet fullst\u00e4ndiga gr\u00e4nssnittet f\u00f6r applikationen ser ut som f\u00f6ljer:<br \/>\n<img decoding=\"async\" alt=\"Att skapa en dricks-kalkylator i Kotlin: hur fungerar det?\" src=\"\/wp-content\/uploads\/2019\/04\/e95058f09c4a6c151b6c5500ae549c0e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\n<img decoding=\"async\" alt=\"Att skapa en dricks-kalkylator i Kotlin: hur fungerar det?\" src=\"\/wp-content\/uploads\/2019\/04\/ac31c73ade24640078c76d71700de0b4.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nDet f\u00f6rsta steget \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lawreyios\/tipcalculator\/tree\/starter_project\">ladda projektets grundstruktur<\/a><\/noindex>. \u00d6ppna den i Android Studio 3.0 eller senare. Bygg och k\u00f6r projektet, och se en vit sk\u00e4rm. Allt \u00e4r normalt, s\u00e5 ska det vara.<\/p>\n<p><img decoding=\"async\" alt=\"Att skapa en dricks-kalkylator i Kotlin: hur fungerar det?\" src=\"\/wp-content\/uploads\/2019\/04\/f4e3361ddc45d56794cc5c7c36d8b206.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\n<img decoding=\"async\" alt=\"Att skapa en dricks-kalkylator i Kotlin: hur fungerar det?\" src=\"\/wp-content\/uploads\/2019\/04\/7828c10dcb3936eb095f5110094ea8bf.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nAnv\u00e4ndarens \u00e5tg\u00e4rder \u00e4r angivna i projektet i kronologisk ordning, s\u00e5 att allt ska vara klart. F\u00f6r att se det \u00f6ppnar vi View -&gt; Tool Windows -&gt; TODO.<\/p>\n<p>Vi studerar projektet och \u00f6ppnar colors.xml f\u00f6r att bed\u00f6ma f\u00e4rgpaletten. I strings.xml finns textdata (etiketter), och i styles.xml finns det flera typsnittsmallar.<\/p>\n<h3>Utveckling av kostnadsavsnittet<\/h3>\n<p>\n\u00d6ppna activity_main.xml och l\u00e4gg till koden nedan i LinearLayout (#1):<\/p>\n<pre><code class=\"kotlin\"><\/code><\/pre>\n<p>\nNu kan du justera stil i directory-namnvalues eller leka med f\u00e4rger, med hj\u00e4lp av <noindex><a rel=\"nofollow\" href=\"https:\/\/material.io\/tools\/color\/#!\/?view.left=0&amp;view.right=0&amp;primary.color=37474F\">material.io-verktyget<\/a><\/noindex>.<\/p>\n<p>Nu ser projektet ut s\u00e5 h\u00e4r:<\/p>\n<p><img decoding=\"async\" alt=\"Att skapa en dricks-kalkylator i Kotlin: hur fungerar det?\" src=\"\/wp-content\/uploads\/2019\/04\/ab47023cafd97fdbd171a9d9a1c35dd5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i> Som du ser ber\u00e4knas kostnaderna utifr\u00e5n de uppgifter som anv\u00e4ndaren anger. <\/i><\/p>\n<h3>Utveckling av r\u00e4kenskapsavsnittet<\/h3>\n<p>\nL\u00e4gg till koden nedan i LinearLayout efter Expense Section (#2):<\/p>\n<pre><code class=\"kotlin\">&lt;! \u2014 TODO #3: Bygg r\u00e4knesektionen \u2192\n \n\u2026<\/code><\/pre>\n<p>\nVi st\u00e4nger LinearLayout efter TODO-listan och l\u00e4gger sedan till ny kod genom att placera den inuti LinearLayout (#3):<\/p>\n<pre><code class=\"kotlin\"><\/code><\/pre>\n<p>\nEftersom appens huvudsyfte \u00e4r att ber\u00e4kna individuella kostnader f\u00f6r varje deltagare vid restaurangbes\u00f6k, \u00e4r costPerPersonTextView av stor betydelse. <\/p>\n<p>EditText begr\u00e4nsar inmatning till en rad, detta parameter ska ha v\u00e4rdet NumberDecimal inputType.<\/p>\n<p><img decoding=\"async\" alt=\"Att skapa en dricks-kalkylator i Kotlin: hur fungerar det?\" src=\"\/wp-content\/uploads\/2019\/04\/7dc4e90d8188a08933e7a92b119472ee.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i> Vi k\u00f6r projektet f\u00f6r att testa och anger parametrarna f\u00f6r den totala skadan (\u00f6mt\u00e5liga f\u00f6rem\u00e5l som krossade muggar och tallrikar etc.).<\/i><\/p>\n<h3>Utveckling av avsnittet 'M\u00e4nniskor och dricks'<\/h3>\n<p>\nF\u00f6r att l\u00e4gga till val av dricksbelopp, infoga f\u00f6ljande kod i den nya sektionen LinearLayout (#4):<\/p>\n<pre><code class=\"kotlin\"><\/code><\/pre>\n<p>\nDenna kodavsnitt \u00e4r n\u00f6dv\u00e4ndig f\u00f6r att exakt ber\u00e4kna beloppet f\u00f6r dricks. Standardv\u00e4rdet f\u00f6r texten \u00e4r 20. ImageButtons \u00e4r f\u00f6rsedda med ikoner i mappen med skrivbeh\u00f6righet.<\/p>\n<p>Vi kopierar hela avsnittet och l\u00e4gger till f\u00f6ljande (#5):<\/p>\n<ul>\n<li> ImageButton ids (subtractPeopleButton, addPeopleButton)<\/li>\n<li> TextView ids (numberOfPeopleStaticText, numberOfPeopleTextView)<\/li>\n<li> DefaultText f\u00f6r numberOfPeopleTextView (ska vara 4).<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Att skapa en dricks-kalkylator i Kotlin: hur fungerar det?\" src=\"\/wp-content\/uploads\/2019\/04\/df99acfb33c3d27126db807b805c9c87.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nNu, vid start av appen, finns det m\u00f6jlighet att l\u00e4gga till summan av notan, knapparna 'L\u00e4gg till\/Drag bort' fungerar ocks\u00e5, men just nu h\u00e4nder inget.<\/p>\n<h3>Vi l\u00e4gger till Views<\/h3>\n<p>\nVi \u00f6ppnar MainActivity.kt och l\u00e4gger till detta i funktionen 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>F\u00e4rdigst\u00e4ll knapparna<\/h3>\n<p>\nF\u00f6r att l\u00e4gga till klickst\u00f6d f\u00f6r knapparna implementerar vi View.OnClickListener p\u00e5 klassniv\u00e5 (#7):<\/p>\n<p>class MainActivity: AppCompatActivity(), View.OnClickListener {<\/p>\n<p>Det g\u00e5r inte att kompilera projektet just nu, vi beh\u00f6ver utf\u00f6ra n\u00e5gra fler \u00e5tg\u00e4rder (#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>\nKnappar och switchar i Kotlin \u00e4r verkligen v\u00e4l organiserade! L\u00e4gg till koden nedan i alla increment- och decrement-funktioner<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>\nDenna kod skyddar increment-funktionerna med maximala v\u00e4rden (MAX_TIP &amp; MAX_PEOPLE). Dessutom skyddar koden decrement-funktionerna med minimala v\u00e4rden (MIN_TIP &amp; MIN_PEOPLE).<\/p>\n<p>Nu l\u00e4nkar vi knapparna till lyssnare i funktionen 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=\"Att skapa en dricks-kalkylator i Kotlin: hur fungerar det?\" src=\"\/wp-content\/uploads\/2019\/04\/73e7477d4b02548aad7c2112c6be5d80.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nNu kan vi r\u00e4kna ut den totala kostnaden, dricks och antal deltagare. Och det viktigaste\u2026<\/p>\n<h3>Avsnitt f\u00f6r kostnadsber\u00e4kning<\/h3>\n<p>Denna kod r\u00e4knar ut kostnaden (#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>\nOch h\u00e4r anropas funktionen som m\u00f6jligg\u00f6r att ta h\u00e4nsyn till antalet personer i s\u00e4llskapet och r\u00e4kna ut dricksen (#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>\nVi startar appen. Den ser bra ut och fungerar utm\u00e4rkt. Men det kan bli \u00e4nnu b\u00e4ttre.<\/p>\n<p>Om du f\u00f6rs\u00f6ker ta bort summan av notan och sedan \u00f6ka antalet tips eller v\u00e4nner kommer appen att krascha eftersom det inte finns n\u00e5gon kontroll f\u00f6r nollv\u00e4rdet. Dessutom, om du f\u00f6rs\u00f6ker \u00e4ndra summan av notan kommer kostnaderna inte att uppdateras.<\/p>\n<h3>Sista stegen<\/h3>\n<p>\nL\u00e4gg till TextWatcher (#16):<\/p>\n<p>class MainActivity: AppCompatActivity(), View.OnClickListener, TextWatcher {<\/p>\n<p>Sedan integrerar vi lyssnaren billEditText (#17):<\/p>\n<p>billEditText.addTextChangedListener(this)<\/p>\n<p>Plus vi l\u00e4gger till koden f\u00f6r att k\u00f6ra 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=\"Att skapa en dricks-kalkylator i Kotlin: hur fungerar det?\" src=\"\/wp-content\/uploads\/2019\/04\/623256a43c969d8b3a434d10a357c1a0.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n <br \/>\nOch nu fungerar allt perfekt! Grattis, du har skrivit din egen \"Dricksbok\" i Kotlin.<\/p>\n<p><img decoding=\"async\" alt=\"Att skapa en dricks-kalkylator i Kotlin: hur fungerar det?\" src=\"\/wp-content\/uploads\/2019\/04\/5650bfecfadf3fd56785b7d6ac72ed87.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<blockquote><p><b>Skillbox rekommenderar:<\/b><\/p>\n<ul>\n<li>Tv\u00e5\u00e5rig praktisk kurs <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\">\u00abJag \u00e4r PRO Webbutvecklare\u00bb<\/a><\/noindex>.<\/li>\n<li>Onlinekurs <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\">\u00abC#-utvecklare\u00bb<\/a><\/noindex>.<\/li>\n<li>Praktisk \u00e5rskurs <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\">PHP-utvecklare fr\u00e5n grunden till PRO<\/a><\/noindex>.\n<\/li>\n<\/ul>\n<\/blockquote>\n<p>K\u00e4lla: <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.4 - 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\/sv\/blog\/news\/sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sv_SE\" \/>\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\/sv\/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\udd47Skapa en dricksbok i Kotlin: hur fungerar det? | ProHoster","description":"Vi ber\u00e4ttar hur man skapar en enkel.","canonical_url":"https:\/\/prohoster.info\/sv\/blog\/news\/sozdanie-kalkulyatora-chaevyh-na-kotlin-kak-eto-rabotaet","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sv_SE","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\/sv\/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\/sv\/wp-json\/wp\/v2\/posts\/31843","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=31843"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/31843\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media\/23712"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=31843"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=31843"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=31843"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}