{"id":370320,"date":"2024-05-21T04:22:31","date_gmt":"2024-05-21T04:22:31","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=370320"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=370320","title":{"rendered":"<span>Android-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 Compose \u0441 \u043d\u0443\u043b\u044f: \u0427\u0430\u0441\u0442\u044c 2 (UI)<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/539\/2a7\/38c\/5392a738cd3493fd230c528c334d581f.png\" width=\"1920\" height=\"1080\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/539\/2a7\/38c\/5392a738cd3493fd230c528c334d581f.png\"\/><\/figure>\n<p>\u0417\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439, \u0434\u043e\u0440\u043e\u0433\u043e\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c!<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u044d\u0442\u0430\u043f\u043d\u0443\u044e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u0438\u0437\u0430\u0439\u043d-\u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438 UI \u0434\u043b\u044f Android-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f &#171;\u041a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440&#187;, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 Jetpack Compose. \u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0435.<\/p>\n<p><strong>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f \u043f\u043e\u00a0\u0446\u0438\u043a\u043b\u0443 \u0441\u0442\u0430\u0442\u0435\u0439:<\/strong><\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/798755\/\" rel=\"noopener noreferrer nofollow\">\u0427\u0430\u0441\u0442\u044c 1 &#8212; \u041f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/a><\/p>\n<\/li>\n<li>\n<p>\u0427\u0430\u0441\u0442\u044c 2 &#8212; UI (\u0412\u044b \u0437\u0434\u0435\u0441\u044c)<\/p>\n<\/li>\n<li>\n<p>\u0427\u0430\u0441\u0442\u044c 3 &#8212; \u0411\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430 (\u0412 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435)<\/p>\n<\/li>\n<\/ul>\n<h3>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/h3>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0435\u0449\u0451 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d \u043f\u0440\u043e\u0435\u043a\u0442, \u0430 Android Studio \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0430\u0441\u044c \u0432\u043f\u0435\u0440\u0432\u044b\u0435.<\/p>\n<p><strong>\u0428\u0430\u0433 1.<\/strong> \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d &#171;Empty Compose Activity&#187;:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e23\/a55\/80f\/e23a5580fa6975fa2a03d991e8cd808d.png\" alt=\"\u041f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430, \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0442\u043e\u043b\u0431\u0435\u0446, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f &quot;Empty Activity&quot;, \u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443 \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0439 \u0448\u0435\u0441\u0442\u0438\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a ;)\" title=\"\u041f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430, \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0442\u043e\u043b\u0431\u0435\u0446, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f &quot;Empty Activity&quot;, \u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443 \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0439 \u0448\u0435\u0441\u0442\u0438\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a ;)\" width=\"907\" height=\"664\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e23\/a55\/80f\/e23a5580fa6975fa2a03d991e8cd808d.png\"\/><\/p>\n<div><figcaption>\u041f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430, \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0442\u043e\u043b\u0431\u0435\u0446, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f &#171;Empty Activity&#187;, \u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443 \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0439 \u0448\u0435\u0441\u0442\u0438\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a \ud83d\ude09<\/figcaption><\/div>\n<\/figure>\n<p><strong>\u0428\u0430\u0433 2.<\/strong> \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (1), \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u0430 (2), \u043c\u0435\u0441\u0442\u043e\u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (3) \u0438 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e Android (4):<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2d4\/284\/527\/2d42845279edf949f7675a44a7b8ed9d.png\" alt=\"\u0412 \u043f\u043e\u043b\u0435 (1) \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c &quot;My Tech Calculator&quot;, \u0432 \u043f\u043e\u043b\u0435 (2) \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c &quot;my.tech.calculator&quot;, \u0430 \u043f\u043e\u043b\u044f 3 \u0438 4 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c\u0438.\" title=\"\u0412 \u043f\u043e\u043b\u0435 (1) \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c &quot;My Tech Calculator&quot;, \u0432 \u043f\u043e\u043b\u0435 (2) \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c &quot;my.tech.calculator&quot;, \u0430 \u043f\u043e\u043b\u044f 3 \u0438 4 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c\u0438.\" width=\"901\" height=\"652\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2d4\/284\/527\/2d42845279edf949f7675a44a7b8ed9d.png\"\/><\/p>\n<div><figcaption>\u0412 \u043f\u043e\u043b\u0435 (1) \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c &#171;My Tech Calculator&#187;, \u0432 \u043f\u043e\u043b\u0435 (2) \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c &#171;my.tech.calculator&#187;, \u0430 \u043f\u043e\u043b\u044f 3 \u0438 4 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c\u0438.<\/figcaption><\/div>\n<\/figure>\n<p>\u0421\u0442\u043e\u0438\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0430 \u044d\u0442\u043e\u043c \u0448\u0430\u0433\u0435 \u0438 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u043e\u0435 \u043f\u043e\u043b\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e:<\/p>\n<ul>\n<li>\n<p><em>Application name<\/em> &#8212; \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0443\u0432\u0438\u0434\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u0441\u043c\u0430\u0440\u0442\u0444\u043e\u043d\u0430;<\/p>\n<\/li>\n<li>\n<p><em>Package name<\/em> &#8212; \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0438\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0437\u043d\u0430\u043a\u043e\u043c &#171;.&#187; (\u0442\u043e\u0447\u043a\u0430);<\/p>\n<\/li>\n<li>\n<p><em>Save location<\/em> &#8212; \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 \u0412\u0430\u0448\u0435\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435;<\/p>\n<\/li>\n<li>\n<p><em>Minimum SDK<\/em> &#8212; \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f Android, \u0442.\u0435. \u043d\u0438\u0436\u0435 \u044d\u0442\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043d\u0435 \u0441\u043c\u043e\u0433\u0443\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 &#171;Finish&#187; \u0432 \u043d\u0438\u0436\u043d\u0435\u043c \u043b\u0435\u0432\u043e\u043c \u0443\u0433\u043b\u0443 \u0434\u0438\u0430\u043b\u043e\u0433\u043e\u0432\u043e\u0433\u043e \u043e\u043a\u043d\u0430.<\/p>\n<p><strong>\u0428\u0430\u0433 3.<\/strong> \u041f\u043e\u0441\u043b\u0435 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0435\u043c \u043a \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/33d\/b56\/fb7\/33db56fb707a9b5ad1a8a42f4db04946.png\" alt=\"Domain-\u043c\u043e\u0434\u0443\u043b\u044c \u043e\u043f\u0443\u0441\u0442\u0438\u043b\u0438, \u0442.\u043a. \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u043e\u043d \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u0435\u043d\" title=\"Domain-\u043c\u043e\u0434\u0443\u043b\u044c \u043e\u043f\u0443\u0441\u0442\u0438\u043b\u0438, \u0442.\u043a. \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u043e\u043d \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u0435\u043d\" width=\"393\" height=\"410\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/33d\/b56\/fb7\/33db56fb707a9b5ad1a8a42f4db04946.png\"\/><\/p>\n<div><figcaption>Domain-\u043c\u043e\u0434\u0443\u043b\u044c \u043e\u043f\u0443\u0441\u0442\u0438\u043b\u0438, \u0442.\u043a. \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u043e\u043d \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u0435\u043d<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u043f\u044b\u0442\u043d\u044b\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u043e \u043c\u043d\u0435\u043d\u0438\u0438, \u0447\u0442\u043e \u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0432 \u043f\u0440\u043e\u0441\u0442\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e\u043c\u043e\u0434\u0443\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0438\u0437\u044b\u0441\u043a\u0430\u043d\u043d\u044b\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d\u0438 \u043b\u0438\u0448\u044c \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u044e\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u044e\u0442 \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e.<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044f \u044d\u0442\u0438\u043c \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u044f\u043c \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<ul>\n<li>\n<p><strong><em>base<\/em><\/strong> &#8212; \u0445\u0440\u0430\u043d\u0438\u0442 \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p><strong><em>ui<\/em><\/strong> &#8212; \u0445\u0440\u0430\u043d\u0438\u0442 \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f;<\/p>\n<ul>\n<li>\n<p><em>theme &#8212; \u0444\u0430\u0439\u043b\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0434\u0438\u0437\u0430\u0439\u043d-\u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f;<\/em><\/p>\n<ul>\n<li>\n<p>components &#8212; <em>\u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b;<\/em><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><em>screens &#8212; \u0444\u0430\u0439\u043b\u044b, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u044d\u043a\u0440\u0430\u043d\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f;<\/em><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong><em>data<\/em><\/strong> &#8212; \u0445\u0440\u0430\u043d\u0438\u0442 \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435\u043c \u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445;<\/p>\n<ul>\n<li>\n<p><em>datasource &#8212; \u043a\u043b\u0430\u0441\u0441\u044b, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c \u0434\u0430\u043d\u043d\u044b\u043c;<\/em><\/p>\n<\/li>\n<li>\n<p><em>repository &#8212; \u043a\u043b\u0430\u0441\u0441\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438;<\/em><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong><em>utils<\/em><\/strong> &#8212; \u0445\u0440\u0430\u043d\u0438\u0442 \u0432\u0441\u0435 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u043e\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0448\u0430\u0433\u0443.<\/p>\n<hr\/>\n<h3>\u041f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0434\u0438\u0437\u0430\u0439\u043d-\u0441\u0438\u0441\u0442\u0435\u043c\u0443:<\/h3>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0434\u0438\u0437\u0430\u0439\u043d-\u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u043e\u0432 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0434 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u0435\u0435, \u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u0440\u0438 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0435\u043d\u0438\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u043a\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p><strong>\u0428\u0430\u0433 1.<\/strong> \u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e Material-\u0442\u0435\u043c\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041e\u043d\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e \u043f\u0443\u0442\u0438 <code>\"ui\/theme\"<\/code>.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0a9\/532\/50c\/0a953250c6ed64bbb0650dab6a45495b.png\" alt=\"\u0412 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f 3 \u0444\u0430\u0439\u043b\u0430, \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u0430 \u0446\u0432\u0435\u0442\u043e\u0432\u0443\u044e \u0441\u0445\u0435\u043c\u0443, \u0442\u0435\u043c\u0443 \u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0441\u0442\u0438\u043b\u0438\" title=\"\u0412 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f 3 \u0444\u0430\u0439\u043b\u0430, \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u0430 \u0446\u0432\u0435\u0442\u043e\u0432\u0443\u044e \u0441\u0445\u0435\u043c\u0443, \u0442\u0435\u043c\u0443 \u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0441\u0442\u0438\u043b\u0438\" width=\"495\" height=\"431\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0a9\/532\/50c\/0a953250c6ed64bbb0650dab6a45495b.png\"\/><\/p>\n<div><figcaption>\u0412 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f 3 \u0444\u0430\u0439\u043b\u0430, \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u0430 \u0446\u0432\u0435\u0442\u043e\u0432\u0443\u044e \u0441\u0445\u0435\u043c\u0443, \u0442\u0435\u043c\u0443 \u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0441\u0442\u0438\u043b\u0438<\/figcaption><\/div>\n<\/figure>\n<p><em>\u0428\u0430\u0433 1.1.<\/em> \u0412 \u0444\u0430\u0439\u043b\u0435 <code>Color.kt<\/code> \u043c\u0435\u043d\u044f\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">\/\/ \u0426\u0432\u0435\u0442\u0430 \u0434\u043b\u044f \u0441\u0432\u0435\u0442\u043b\u043e\u0439 \u0442\u0435\u043c\u044b val LightBackground = Color(0xFFC6C6C6) val LightSurface = Color(0xFFF2F2F2) val LightPrimaryColor = Color(0xFF575757) val LightSecondaryColor = Color(0xFFE1E1E1) val LightOnPrimaryColor = Color(0xFFFFFFFF) val LightOnSecondaryColor = Color(0xFF282828) val LightOnSurfaceColor = Color(0xFF282828)  \/\/ \u0426\u0432\u0435\u0442\u0430 \u0434\u043b\u044f \u0442\u0435\u043c\u043d\u043e\u0439 \u0442\u0435\u043c\u044b val DarkBackground = Color(0xFF333333) val DarkSurface = Color(0xFF212121) val DarkPrimaryColor = Color(0xFF323232) val DarkSecondaryColor = Color(0xFF535353) val DarkOnPrimaryColor = Color(0xFFFFFFFF) val DarkOnSecondaryColor = Color(0xFFFFFFFF) val DarkOnSurfaceColor = Color(0xFFFFFFFF)<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<blockquote>\n<p>\u0426\u0432\u0435\u0442\u0430 \u043c\u044b \u0432\u0437\u044f\u043b\u0438 \u0438\u0437 \u0446\u0432\u0435\u0442\u043e\u0432\u043e\u0439 \u043f\u0430\u043b\u0438\u0442\u0440\u044b, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u043e\u0439 <a href=\"https:\/\/habr.com\/ru\/articles\/798755\/\" rel=\"noopener noreferrer nofollow\">\u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>.<\/p>\n<\/blockquote>\n<p><em>\u0428\u0430\u0433 1.2.<\/em> \u0412 \u0444\u0430\u0439\u043b\u0435 <code>Type.kt<\/code> \u043c\u0435\u043d\u044f\u0435\u043c \u043a\u043e\u0434 \u043d\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">val Typography = Typography(     bodyLarge = TextStyle(         fontFamily = FontFamily.Default,         fontWeight = FontWeight.Normal,         fontSize = 30.sp     ),     titleLarge = TextStyle(         fontFamily = FontFamily.Default,         fontWeight = FontWeight.Normal,         fontSize = 36.sp     ) )<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<blockquote>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u043d\u0430\u0441 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0441\u0442\u0438\u043b\u044c <code>\"bodyLarge\"<\/code> \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043a\u043d\u043e\u043f\u043e\u043a \u0438 \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u043c\u0430\u0442. \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0430 \u0441\u0442\u0438\u043b\u044c <code>\"titleLarge\"<\/code> \u0434\u043b\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0442. \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<\/blockquote>\n<p><em>\u0428\u0430\u0433 1.3.<\/em> \u0412 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u0444\u0430\u0439\u043b\u0430 <code>Theme.kt<\/code> \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u0446\u0432\u0435\u0442\u043e\u0432\u043e\u0439 \u0441\u0445\u0435\u043c\u044b \u0438\u0437 Material 3. \u041c\u044b \u0445\u043e\u0442\u0438\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0442\u0438\u043b\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443\u0434\u0430\u043b\u0438\u043c \u044d\u0442\u0443 \u0444\u0438\u0447\u0443 \u0438 \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u0446\u0432\u0435\u0442\u043e\u0432\u0443\u044e \u0441\u0445\u0435\u043c\u0443:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">private val DarkColorScheme = darkColorScheme(     primary = DarkPrimaryColor,     onPrimary = DarkOnPrimaryColor,     secondary = DarkSecondaryColor,     onSecondary = DarkOnSecondaryColor,     background = DarkBackground,     surface = DarkSurface,     onSurface = DarkOnSurfaceColor )  private val LightColorScheme = lightColorScheme(     primary = LightPrimaryColor,     onPrimary = LightOnPrimaryColor,     secondary = LightSecondaryColor,     onSecondary = LightOnSecondaryColor,     background = LightBackground,     surface = LightSurface,     onSurface = LightOnSurfaceColor )  @Composable fun MyTechCalculatorTheme(     darkTheme: Boolean = isSystemInDarkTheme(),     content: @Composable () -> Unit ) {     val colorScheme = when {         darkTheme -> DarkColorScheme         else -> LightColorScheme     }      MaterialTheme(         colorScheme = colorScheme,         typography = Typography,         content = content     ) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><strong>\u0428\u0430\u0433 2.<\/strong> \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0434\u0438\u0437\u0430\u0439\u043d-\u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0435\u0433\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u0432\u0435\u0442\u043b\u043e\u0439 \u0438 \u0442\u0435\u043c\u043d\u043e\u0439 \u0442\u0435\u043c\u044b:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ce0\/fa3\/c51\/ce0fa3c516ab493c6150d18419476103.png\" alt=\"\u041a\u043d\u043e\u043f\u043a\u0430 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043c\u044b\" title=\"\u041a\u043d\u043e\u043f\u043a\u0430 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043c\u044b\" width=\"198\" height=\"36\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ce0\/fa3\/c51\/ce0fa3c516ab493c6150d18419476103.png\"\/><\/p>\n<div><figcaption>\u041a\u043d\u043e\u043f\u043a\u0430 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043c\u044b<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0442\u043e\u0438\u0442 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0438\u0442\u044c &#171;best practices&#187; \u043f\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432:<\/p>\n<blockquote>\n<ul>\n<li>\n<p>\u0421\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c \u0438\u0437 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043f\u0435\u0440\u0432\u044b\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c \u0432 Composable-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>Modifier<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>onClick<\/code> (\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043a\u043b\u0438\u043a\u0430 \u043f\u043e UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443) \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 <code>content<\/code>  (\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f).<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f Composable-\u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u043e\u0439 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439 <code>@Preview<\/code> \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0435\u0439 \u0437\u0430 \u043f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 <code>private<\/code>.<\/p>\n<\/li>\n<\/ul>\n<\/blockquote>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">@Composable fun JetSwitchButton(     modifier: Modifier = Modifier,     isChecked: Boolean = false,     onValueChange: (Boolean) -> Unit ) {     val iconId = if (isChecked)         R.drawable.ic_day     else         R.drawable.ic_moon      Row(         modifier = modifier             .wrapContentWidth()             .background(                 MaterialTheme.colorScheme.secondary,                 RoundedCornerShape(topStart = 16.dp, bottomEnd = 16.dp)             )             .clip(                 RoundedCornerShape(topStart = 16.dp, bottomEnd = 16.dp)             )             .clickable(onClick = {                 onValueChange.invoke(!isChecked)             }),         verticalAlignment = Alignment.CenterVertically     ) {         Box(             modifier = Modifier                 .padding(horizontal = 8.dp, vertical = 4.dp)                 .size(48.dp, 24.dp)                 .background(MaterialTheme.colorScheme.onSecondary, RoundedCornerShape(16.dp)),             contentAlignment = Alignment.CenterStart         ) {             Box(                 modifier = Modifier                     .padding(horizontal = 8.dp)                     .size(14.dp)                     .background(MaterialTheme.colorScheme.secondary, CircleShape)             )         }          Icon(             modifier = Modifier.padding(horizontal = 8.dp),             imageVector = ImageVector.vectorResource(id = iconId), contentDescription = \"\",             tint = MaterialTheme.colorScheme.onSecondary         )     } }  \/\/ \u041f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 UI \u0434\u043b\u044f \u0441\u0432\u0435\u0442\u043b\u043e\u0439 \u0442\u0435\u043c\u044b @Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) \/\/ \u041f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 UI \u0434\u043b\u044f \u0442\u0435\u043c\u043d\u043e\u0439 \u0442\u0435\u043c\u044b @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable private fun ShowPreview2() {     MyTechCalculatorTheme {         Row {             JetSwitchButton(                 modifier = Modifier                     .fillMaxWidth()                     .height(32.dp), isChecked = true, {}             )         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435:<\/em> \u041e\u0441\u043e\u0431\u043e\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0443\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. \u041e\u0431\u044b\u0447\u043d\u043e \u043e\u043d\u043e \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0448\u0430\u0431\u043b\u043e\u043d\u0443 &#8212; <code>\"Jet{ComponentName}\"<\/code>, \u0433\u0434\u0435 &#171;Jet&#187; \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u043e\u0442 \u0441\u043b\u043e\u0432\u0430 &#171;Jetpack&#187;. <\/p>\n<p>\u041f\u0440\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0441\u0442\u043e\u0438\u0442 \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0439 \u0432 Jetpack Compose &#8212; Card, Button, Icon \u0438 \u0442.\u0434. <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<ul>\n<li>\n<p><code>JetImageLoader()<\/code> &#8212; \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p><code>JetRatingBar()<\/code> &#8212; \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0449\u0438\u0439 \u043f\u044f\u0442\u0438\u0437\u0432\u0435\u0437\u0434\u043e\u0447\u043d\u044b\u0439 \u0440\u0435\u0439\u0442\u0438\u043d\u0433;<\/p>\n<\/li>\n<li>\n<p><code>JetEditorLayout()<\/code> &#8212; \u043c\u0430\u043a\u0435\u0442 \u0434\u043b\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 &#171;Jet&#187; \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c, \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u043d\u0435\u0433\u043e \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043f\u0440\u0435\u0444\u0438\u043a\u0441 &#8212; \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0438\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0422\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044e \u043f\u043e \u0434\u0438\u0437\u0430\u0439\u043d-\u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0435\u0449\u0451 \u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e.<\/p>\n<p><strong>\u0428\u0430\u0433 3.<\/strong> \u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443, \u0443\u0436\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c\u0443, \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u043c\u0443 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443. \u0422\u0430\u043a\u0436\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0435\u0433\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u0432\u0435\u0442\u043b\u043e\u0439 \u0438 \u0442\u0435\u043c\u043d\u043e\u0439 \u0442\u0435\u043c\u044b:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2c9\/01f\/04e\/2c901f04e5a4cbc368b28c329fd8ceca.png\" alt=\"\u0421\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u043d\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430\" title=\"\u0421\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u043d\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430\" width=\"128\" height=\"64\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2c9\/01f\/04e\/2c901f04e5a4cbc368b28c329fd8ceca.png\"\/><\/p>\n<div><figcaption>\u0421\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u043d\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0442\u044c &#171;best practices&#187; \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f Jetpack Compose:<\/p>\n<blockquote>\n<ul>\n<li>\n<p>\u041f\u0440\u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0445 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0432\u044b\u043d\u043e\u0441\u0438\u0442\u044c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 <code>@Immutable<\/code> \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0443\u0445\u043e\u0434\u0430 \u043e\u0442 \u043b\u0438\u0448\u043d\u0438\u0445 \u0440\u0435\u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p>\u041b\u044e\u0431\u044b\u0435 \u0446\u0432\u0435\u0442\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0432 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0445, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0431\u0440\u0430\u0442\u044c \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438\u0437 <code>MaterialTheme<\/code>, \u0430 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u043a\u043e\u0434\u0435 (\u0432\u043d\u0443\u0442\u0440\u0438 Composable-\u0444\u0443\u043d\u043a\u0446\u0438\u0438).<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438 Composable-\u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0434\u043b\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<\/blockquote>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0441 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u043a:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">@Composable fun JetRoundedButton(     modifier: Modifier = Modifier,     text: String, \/\/ \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442     buttonColors: JetRoundedButtonColors,     onClick: () -> Unit ) {     Box(         modifier = modifier             .clip(CircleShape)             .background(buttonColors.containerColor(), CircleShape)             .innerShadow(                 shape = CircleShape, color = buttonColors.shadowContainerColor(),                 blur = 4.dp,                 offsetY = 4.dp, offsetX = 0.dp, spread = 0.dp             )             .clickable(onClick = onClick),         contentAlignment = Alignment.Center     ) {         Text(             text = text,             style = MaterialTheme.typography.bodyLarge,             color = buttonColors.contentColor()         )     } }  @Composable fun JetRoundedButton(     modifier: Modifier = Modifier,     text: AnnotatedString, \/\/ \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u0441 \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, x^y     buttonColors: JetRoundedButtonColors,     onClick: () -> Unit ) {     Box(         modifier = modifier             .clip(CircleShape)             .background(buttonColors.containerColor(), CircleShape)             .innerShadow(                 shape = CircleShape, color = buttonColors.shadowContainerColor(),                 blur = 4.dp,                 offsetY = 4.dp, offsetX = 0.dp, spread = 0.dp             )             .clickable(onClick = onClick),         contentAlignment = Alignment.Center     ) {         Text(             text = text,             style = MaterialTheme.typography.bodyLarge,             color = buttonColors.contentColor()         )     } }  @Composable fun JetRoundedButton(     modifier: Modifier = Modifier,     @DrawableRes iconId: Int, \/\/ \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u0443\u044e \u0438\u043a\u043e\u043d\u043a\u0443     buttonColors: JetRoundedButtonColors,     onClick: () -> Unit ) {     Box(         modifier = modifier             .clip(CircleShape)             .background(buttonColors.containerColor(), CircleShape)             .innerShadow(                 shape = CircleShape, color = buttonColors.shadowContainerColor(),                 blur = 4.dp,                 offsetY = 4.dp, offsetX = 0.dp, spread = 0.dp             )             .clickable(onClick = onClick),         contentAlignment = Alignment.Center     ) {         Icon(             imageVector = ImageVector.vectorResource(iconId),             contentDescription = null,             tint = buttonColors.contentColor()         )     } }  object JetRoundedButtonDefaults {      @Composable     fun numberButtonColors(         containerColor: Color = MaterialTheme.colorScheme.primary,         contentColor: Color = MaterialTheme.colorScheme.onPrimary,         shadowContainerColor: Color = Color.Black.copy(alpha = 0.6f),     ): JetRoundedButtonColors = JetRoundedButtonColors(         containerColor = containerColor,         contentColor = contentColor,         shadowContainerColor = shadowContainerColor     )      @Composable     fun operationButtonColors(         containerColor: Color = MaterialTheme.colorScheme.secondary,         contentColor: Color = MaterialTheme.colorScheme.onSecondary,         shadowContainerColor: Color = Color.Black.copy(alpha = 0.6f),     ): JetRoundedButtonColors = JetRoundedButtonColors(         containerColor = containerColor,         contentColor = contentColor,         shadowContainerColor = shadowContainerColor     ) }  @Immutable class JetRoundedButtonColors internal constructor(     private val containerColor: Color,     private val contentColor: Color,     private val shadowContainerColor: Color ) {     @Composable     internal fun containerColor(): Color {         return containerColor     }      @Composable     internal fun contentColor(): Color {         return contentColor     }      @Composable     internal fun shadowContainerColor(): Color {         return shadowContainerColor     }      override fun equals(other: Any?): Boolean {         if (this === other) return true         if (other == null || other !is JetRoundedButtonColors) return false          if (containerColor != other.containerColor) return false         if (contentColor != other.contentColor) return false         if (shadowContainerColor != other.shadowContainerColor) return false          return true     }      override fun hashCode(): Int {         var result = containerColor.hashCode()         result = 31 * result + contentColor.hashCode()         result = 31 * result + shadowContainerColor.hashCode()         return result     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0433\u0443\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0442\u044c &#8212; \u0442\u0435\u043a\u0441\u0442, \u0441\u0442\u0438\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u0430\u044f \u0438\u043a\u043e\u043d\u043a\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u044b \u0442\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 Composable-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>JetRoundedButton()<\/code>.<\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 <u>\u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e<\/u>, \u0447\u0442\u043e \u0432\u0438\u0434\u043e\u0432 \u0441\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u043d\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u0432\u0430 &#8212; \u0434\u043b\u044f \u043c\u0430\u0442. \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0438 \u0434\u043b\u044f \u0447\u0438\u0441\u0435\u043b (\u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e, \u043d\u043e \u0432\u0441\u0451 \u0436\u0435), \u0442\u043e \u0434\u043b\u044f \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043d\u0430 \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u044e UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 <code>JetRoundedButtonDefaults<\/code>, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0433\u043e\u0442\u043e\u0432\u044b\u0435 \u0441\u0442\u0438\u043b\u0438 \u0434\u043b\u044f \u044d\u0442\u0438\u0445 \u0432\u0438\u0434\u043e\u0432 \u043a\u043d\u043e\u043f\u043e\u043a.<\/p>\n<p>\u0414\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u0442\u0438\u043b\u044f \u043a\u043d\u043e\u043f\u043e\u043a \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 Immutable-\u043a\u043b\u0430\u0441\u0441 <code>JetRoundedButtonColors<\/code>. \u041a \u0434\u043e\u0441\u0442\u043e\u0438\u043d\u0441\u0442\u0432\u0430\u043c \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043d\u0435\u0441\u0442\u0438:<\/p>\n<ul>\n<li>\n<p>\u0423\u0434\u043e\u0431\u0441\u0442\u0432\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0430\u0446\u0438\u0438 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430;<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043b\u0438\u0448\u043d\u0438\u0445 \u0440\u0435\u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0439;<\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 &#171;\u0443\u0442\u0435\u0447\u0435\u043a \u043f\u0430\u043c\u044f\u0442\u0438&#187;.<\/p>\n<\/li>\n<\/ul>\n<p><em>\u0420\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435<\/em>: \u0412\u044b\u0448\u0435 \u043c\u044b \u0443\u0436\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b\u0438, \u0447\u0442\u043e \u0446\u0432\u0435\u0442\u0430 \u0441\u0442\u043e\u0438\u0442 \u0431\u0440\u0430\u0442\u044c \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438\u0437 <code>MaterialTheme<\/code>, \u0430 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u0445 \u0432\u043d\u0443\u0442\u0440\u0438 Composable-\u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u042d\u0442\u043e \u0441\u0432\u044f\u0437\u0430\u043d\u043e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e <code>CompositionLocalProvider<\/code>, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0439 \u0446\u0432\u0435\u0442\u043e\u0432\u0443\u044e \u0441\u0445\u0435\u043c\u0443 \u0438\u0437 <code>MaterialTheme<\/code>, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a \u043d\u0435\u0439 \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u0438\u0437 \u043b\u044e\u0431\u043e\u0439 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0439 Composable-\u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0442\u0438\u043f\u0430 <code>Color<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 Composable-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u0440\u0435\u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438, \u0447\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043b\u0438\u0448\u043d\u0435\u0435 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>\u0412 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u043e\u043c \u0432\u044b\u0448\u0435 \u043a\u043e\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f <code>innerShadow()<\/code> \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u0442\u0435\u043d\u0435\u0439 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 &#8212; \u043e\u0442 Kappdev:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">fun Modifier.innerShadow(     shape: Shape,     color: Color,     blur: Dp,     offsetY: Dp,     offsetX: Dp,     spread: Dp ) = drawWithContent {     drawContent() \/\/ Rendering the content      val rect = Rect(Offset.Zero, size)     val paint = Paint().apply {         this.color = color         this.isAntiAlias = true     }      val shadowOutline = shape.createOutline(size, layoutDirection, this)      drawIntoCanvas { canvas ->          \/\/ Save the current layer.         canvas.saveLayer(rect, paint)         \/\/ Draw the first layer of the shadow.         canvas.drawOutline(shadowOutline, paint)          \/\/ Convert the paint to a FrameworkPaint.         val frameworkPaint = paint.asFrameworkPaint()         \/\/ Set xfermode to DST_OUT to create the inner shadow effect.         frameworkPaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OUT)          \/\/ Apply blur if specified.         if (blur.toPx() > 0) {             frameworkPaint.maskFilter = BlurMaskFilter(blur.toPx(), BlurMaskFilter.Blur.NORMAL)         }          \/\/ Change paint color to black for the inner shadow.         paint.color = Color.Black          \/\/ Calculate offsets considering spread.         val spreadOffsetX = offsetX.toPx() + if (offsetX.toPx() &lt; 0) -spread.toPx() else spread.toPx()         val spreadOffsetY = offsetY.toPx() + if (offsetY.toPx() &lt; 0) -spread.toPx() else spread.toPx()          \/\/ Move the canvas to specific offsets.         canvas.translate(spreadOffsetX, spreadOffsetY)          \/\/ Draw the second layer of the shadow.         canvas.drawOutline(shadowOutline, paint)          \/\/ Restore the canvas to its original state.         canvas.restore()     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0415\u0451 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 &#171;utils&#187;, \u0441\u043e\u0437\u0434\u0430\u0432 \u0444\u0430\u0439\u043b <code>ComposeExt.kt<\/code>.<\/p>\n<hr\/>\n<h3>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c User Interface:<\/h3>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u0443\u044e \u0432\u044b\u0448\u0435 \u0434\u0438\u0437\u0430\u0439\u043d-\u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c UI \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0438 \u043d\u0435\u043f\u043e\u0432\u0442\u043e\u0440\u0438\u043c\u043e\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1f0\/317\/8c4\/1f03178c48c023f2e606e840721fea4b.png\" alt=\"\u0412\u0441\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u043a\u0430\u043a \u044d\u043a\u0440\u0430\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 ;)\" title=\"\u0412\u0441\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u043a\u0430\u043a \u044d\u043a\u0440\u0430\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 ;)\" width=\"824\" height=\"733\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1f0\/317\/8c4\/1f03178c48c023f2e606e840721fea4b.png\"\/><\/p>\n<div><figcaption>\u0412\u0441\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u043a\u0430\u043a \u044d\u043a\u0440\u0430\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \ud83d\ude09<\/figcaption><\/div>\n<\/figure>\n<p>\u0412 \u043f\u0430\u043f\u043a\u0435 &#171;screens&#187; \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u043e\u0434\u043f\u0430\u043f\u043a\u0443 &#171;home&#187;, \u0430 \u0432 \u043d\u0435\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435 MVI:<\/p>\n<ul>\n<li>\n<p><strong><em>models<\/em><\/strong><\/p>\n<ul>\n<li>\n<p><em>HomeEvent.kt <\/em>&#8212; \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f<\/p>\n<\/li>\n<li>\n<p><em>HomeAction.kt<\/em>  &#8212; \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u044b<\/p>\n<\/li>\n<li>\n<p><em>HomeViewState.kt<\/em> &#8212; \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u044d\u043a\u0440\u0430\u043d\u0430<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>views<\/strong><\/p>\n<ul>\n<li>\n<p><em>HomeViewInit.kt<\/em><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><em>HomeScreen.kt<\/em><\/p>\n<\/li>\n<li>\n<p><em>HomeViewModel.kt<\/em> <\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u0441\u0451 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f <code>\"home\"<\/code>, \u0430 \u043d\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043e \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u043c\u043e\u0434\u0443\u043b\u044f <code>\"models, views, viewmodels\"<\/code> \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430. <\/p>\n<blockquote>\n<p>\u041e\u0431\u043e\u0431\u0449\u0430\u044f, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u0430\u044f \u0432\u044b\u0448\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0441\u043e\u043a\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u0442\u0440\u0430\u0442\u044b \u043f\u0440\u0438 \u0432\u043d\u0435\u0441\u0435\u043d\u0438\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u043c\u043e\u0434\u0443\u043b\u044f.<\/p>\n<\/blockquote>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u0444\u0430\u0439\u043b\u043e\u0432:<\/p>\n<p><strong>\u0428\u0430\u0433 1.<\/strong> \u041f\u0440\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442:<\/p>\n<ul>\n<li>\n<p>\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0442\u0435\u043c\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f &#8212; \u0441\u0432\u0435\u0442\u043b\u0430\u044f \/ \u0442\u0435\u043c\u043d\u0430\u044f;<\/p>\n<\/li>\n<li>\n<p>\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 &#8212; \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0447\u0438\u0441\u043b\u043e, \u043c\u0430\u0442. \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0438\u043b\u0438 \u0441\u043a\u043e\u0431\u043a\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435;<\/p>\n<\/li>\n<li>\n<p>\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b;<\/p>\n<\/li>\n<li>\n<p>\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0435 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u044d\u0442\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0444\u0430\u0439\u043b <code>HomeEvent.kt<\/code>:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">sealed class HomeEvent {     data class ChangeTheme(val newValue: Boolean) : HomeEvent()     data class ChangeExpression(val newValue: ExpressionItem) : HomeEvent()     data object CalculateExpression : HomeEvent()     data object RemoveLastSymbol : HomeEvent()     data object ClearExpression : HomeEvent() }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <em>sealed<\/em> \u043a\u043b\u0430\u0441\u0441, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u0443\u044e \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044e \u043a\u043b\u0430\u0441\u0441\u043e\u0432. \u041e\u0434\u043d\u043e \u0438\u0437 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432 \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f &#8212; \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f <code>ClassCastException<\/code> \u043f\u0440\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0442\u0438\u043f\u0430 <code>HomeEvent<\/code>, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b \u0432\u0441\u0435 \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0438 sealed \u043a\u043b\u0430\u0441\u0441\u0430. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438, \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u043d\u043e\u0439 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0435.<\/p>\n<p><strong>\u0428\u0430\u0433 2.<\/strong> \u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435 \u043f\u0440\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0438 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b (\u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u0438\u0430\u043b\u043e\u0433\u043e\u0432\u043e\u0433\u043e \u043e\u043a\u043d\u0430, \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0435 \u044d\u043a\u0440\u0430\u043d\u0430 \u0438 \u0442.\u043f.) \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c <em>sealed<\/em> \u043a\u043b\u0430\u0441\u0441 \u0432 \u0444\u0430\u0439\u043b\u0435 <code>HomeAction<\/code> \u043f\u0443\u0441\u0442\u044b\u043c:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">sealed class HomeAction {      }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><strong>\u0428\u0430\u0433 3.<\/strong> \u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c \u043d\u0430 \u0448\u0430\u0433\u0435 1, \u0432 \u0441\u043e\u0431\u044b\u0442\u0438\u0438 <code>ChangeExpression<\/code> \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0442\u0438\u043f\u0430 <code>ExpressionItem<\/code>. \u042d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0443\u0431\u0440\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0442\u0438\u043f\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0432 \u0438\u0445 \u0432 \u043e\u0434\u0438\u043d \u043a\u043b\u0430\u0441\u0441:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">sealed class ExpressionItem(val type: ExpressionItemType, val value: String) {     \/\/ \u041c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438     data object OperationMul: ExpressionItem(ExpressionItemType.Operation, \"*\")     data object OperationDiv: ExpressionItem(ExpressionItemType.Operation, \"\/\")     data object OperationPlus: ExpressionItem(ExpressionItemType.Operation, \"+\")     data object OperationMinus: ExpressionItem(ExpressionItemType.Operation, \"-\")     data object OperationSqrt: ExpressionItem(ExpressionItemType.Operation, \"\u221a\")     data object OperationSqr: ExpressionItem(ExpressionItemType.Operation, \"^\")     data object OperationPercent: ExpressionItem(ExpressionItemType.Operation, \"%\")      \/\/ \u041a\u0440\u0443\u0433\u043b\u044b\u0435 \u0441\u043a\u043e\u0431\u043a\u0438     data object LeftBracket: ExpressionItem(ExpressionItemType.Bracket, \"(\")     data object RightBracket: ExpressionItem(ExpressionItemType.Bracket, \")\")      \/\/ \u0427\u0438\u0441\u043b\u0430 \u043e\u0442 0 \u0434\u043e 9, \u0430 \u0442\u0430\u043a\u0436\u0435 \".\"     data object Value0: ExpressionItem(ExpressionItemType.Value, \"0\")     data object Value1: ExpressionItem(ExpressionItemType.Value, \"1\")     data object Value2: ExpressionItem(ExpressionItemType.Value, \"2\")     data object Value3: ExpressionItem(ExpressionItemType.Value, \"3\")     data object Value4: ExpressionItem(ExpressionItemType.Value, \"4\")     data object Value5: ExpressionItem(ExpressionItemType.Value, \"5\")     data object Value6: ExpressionItem(ExpressionItemType.Value, \"6\")     data object Value7: ExpressionItem(ExpressionItemType.Value, \"7\")     data object Value8: ExpressionItem(ExpressionItemType.Value, \"8\")     data object Value9: ExpressionItem(ExpressionItemType.Value, \"9\")     data object ValuePoint: ExpressionItem(ExpressionItemType.Value, \".\")      \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0430\u0442. \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f     data object None: ExpressionItem(ExpressionItemType.Empty, \"\")      companion object {         fun convertToExpression(value: String): ExpressionItem {             return when(value){                 OperationMul.value -> OperationMul                 OperationDiv.value -> OperationDiv                 OperationPlus.value -> OperationPlus                 OperationMinus.value -> OperationMinus                 OperationSqrt.value -> OperationSqrt                 OperationSqr.value -> OperationSqr                 OperationPercent.value -> OperationPercent                 LeftBracket.value -> LeftBracket                 RightBracket.value -> RightBracket                 None.value -> None                 Value0.value -> Value0                 Value1.value -> Value1                 Value2.value -> Value2                 Value3.value -> Value3                 Value4.value -> Value4                 Value5.value -> Value5                 Value6.value -> Value6                 Value7.value -> Value7                 Value8.value -> Value8                 Value9.value -> Value9                 ValuePoint.value -> ValuePoint                 else -> throw Exception(\"Not found ExpressionItem with value\")             }         }     } }  sealed class ExpressionItemType{     data object Operation: ExpressionItemType()     data object Bracket: ExpressionItemType()     data object Value: ExpressionItemType()     data object Empty: ExpressionItemType() }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><strong>\u0428\u0430\u0433 4.<\/strong> \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438\u043b\u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u043e\u0434\u043d\u0438\u043c \u0435\u0434\u0438\u043d\u044b\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u044d\u043a\u0440\u0430\u043d\u0430. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>data class<\/code>, \u0430 \u043d\u0435 <em>sealed class<\/em>.<\/p>\n<p>\u041a \u0445\u0440\u0430\u043d\u0438\u043c\u044b\u043c \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u044d\u043a\u0440\u0430\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u043c \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f:<\/p>\n<ul>\n<li>\n<p><em>\u041c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435<\/em> &#8212; \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0435 \u0432\u0441\u0435 \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u044b;<\/p>\n<\/li>\n<li>\n<p><em>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0442. \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/em> &#8212; \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435;<\/p>\n<\/li>\n<li>\n<p><em>\u0422\u0438\u043f \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0442\u0435\u043c\u044b<\/em> &#8212; \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0433\u0434\u0435 <code>true<\/code> &#8212; \u0442\u0435\u043c\u043d\u0430\u044f \u0442\u0435\u043c\u0430, \u0430 <code>false<\/code> &#8212; \u0441\u0432\u0435\u0442\u043b\u0430\u044f \u0442\u0435\u043c\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435, \u0432 \u0444\u0430\u0439\u043b <code>HomeViewState.kt<\/code> \u0437\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">data class HomeViewState(     val displayExpression: StringBuilder = StringBuilder(), \/\/ \u0445\u0440\u0430\u043d\u0438\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u043c\u0430\u0442. \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435     val privateExpression: StringBuilder = StringBuilder(), \/\/ \u0445\u0440\u0430\u043d\u0438\u0442 \u0432\u0441\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b + \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u043c\u0430\u0442. \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435     val currentExpressionItem: ExpressionItem = ExpressionItem.None, \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043c\u0430\u0442.\u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439     val expressionResult: String = \"\", \/\/ \u0445\u0440\u0430\u043d\u0438\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043c\u0430\u0442. \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f     val isDarkTheme: Boolean = false )<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>StringBuilder<\/code> \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f (\u0432\u043c\u0435\u0441\u0442\u043e String), \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432.<\/p>\n<p><strong>\u0428\u0430\u0433 5.<\/strong> \u0422\u0430\u043a \u043a\u0430\u043a \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u044d\u043a\u0440\u0430\u043d\u0430 \u0443 \u043d\u0430\u0441 \u043e\u0434\u043d\u043e, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u043e\u0434\u043d\u043e. \u041e\u0431\u044b\u0447\u043d\u043e \u0435\u0433\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0448\u0430\u0431\u043b\u043e\u043d\u0443 &#8212; <code>\"{ScreenName}ViewInit\"<\/code>.<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f \u0444\u0430\u0439\u043b\u0430 <code>HomeViewInit.kt<\/code>:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">@Composable fun HomeViewInit(     viewState: HomeViewState,     onChangeTheme: (Boolean) -> Unit,     onChangeExpression: (ExpressionItem) -> Unit,     onClearExpression: () -> Unit,     onRemoveLastSymbol: () -> Unit,     onCalculateExpression: () -> Unit ) {      val scrollState = rememberScrollState()      Column(         modifier = Modifier             .fillMaxSize()             .background(MaterialTheme.colorScheme.background)     ) {         Box(             modifier = Modifier                 .padding(horizontal = 24.dp, vertical = 24.dp)                 .fillMaxWidth()                 .height(208.dp)                 .background(MaterialTheme.colorScheme.surface, RoundedCornerShape(16.dp))                 .clip(RoundedCornerShape(16.dp))         ) {             Column(                 modifier = Modifier                     .verticalScroll(scrollState)                     .padding(start = 32.dp, end = 64.dp, top = 32.dp, bottom = 16.dp)                     .fillMaxSize()                     .align(Alignment.BottomCenter)             ) {                 Text(                     modifier = Modifier.fillMaxWidth(),                     text = viewState.displayExpression.toString(),                     textAlign = TextAlign.End,                     color = MaterialTheme.colorScheme.onSurface,                     style = MaterialTheme.typography.bodyLarge                 )                 Text(                     modifier = Modifier.fillMaxWidth(),                     text = if (viewState.expressionResult.isEmpty()) \"0\" else \"=${viewState.expressionResult}\",                     textAlign = TextAlign.End,                     color = MaterialTheme.colorScheme.onSurface,                     style = MaterialTheme.typography.titleLarge                 )             }              JetSwitchButton(                 modifier = Modifier.align(Alignment.TopStart),                 isChecked = false,                 onValueChange = onChangeTheme             )         }          Row(             modifier = Modifier                 .padding(horizontal = 24.dp, vertical = 12.dp)                 .fillMaxSize(),             horizontalArrangement = Arrangement.SpaceBetween         ) {             Column(                 modifier = Modifier.fillMaxHeight(),                 verticalArrangement = Arrangement.spacedBy(16.dp)             ) {                 JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"C\",                     buttonColors = JetRoundedButtonDefaults.operationButtonColors(),                     onClick = {                         onClearExpression.invoke()                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"\u221a\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.OperationSqrt)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"1\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.Value1)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"4\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.Value4)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"7\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.Value7)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \".\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.ValuePoint)                     })             }              Column(                 modifier = Modifier.fillMaxHeight(),                 verticalArrangement = Arrangement.spacedBy(16.dp)             ) {                 JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"(\",                     buttonColors = JetRoundedButtonDefaults.operationButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.LeftBracket)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"%\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.OperationPercent)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"2\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.Value2)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"5\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.Value5)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"8\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.Value8)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"0\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.Value0)                     })             }              Column(                 modifier = Modifier.fillMaxHeight(),                 verticalArrangement = Arrangement.spacedBy(16.dp)             ) {                 JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \")\",                     buttonColors = JetRoundedButtonDefaults.operationButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.RightBracket)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = buildAnnotatedString {                         append(\"x\")                         withStyle(                             SpanStyle(                                 baselineShift = BaselineShift.Superscript,                                 fontSize = 16.sp,                                 fontWeight = FontWeight.Medium,                                 color = Color.White                             )                         ) {                             append(\"y\")                         }                     },                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.OperationSqr)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"3\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.Value3)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"6\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.Value6)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"9\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.Value9)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     iconId = R.drawable.ic_backspace,                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onRemoveLastSymbol.invoke()                     })             }              Column(                 modifier = Modifier.fillMaxHeight(),                 verticalArrangement = Arrangement.spacedBy(16.dp)             ) {                 JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"\u00d7\",                     buttonColors = JetRoundedButtonDefaults.operationButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.OperationMul)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"\u00f7\",                     buttonColors = JetRoundedButtonDefaults.operationButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.OperationDiv)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"+\",                     buttonColors = JetRoundedButtonDefaults.operationButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.OperationPlus)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp),                     text = \"-\",                     buttonColors = JetRoundedButtonDefaults.operationButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.OperationMinus)                     })                  JetRoundedButton(modifier = Modifier.size(64.dp, 144.dp),                     text = \"=\",                     buttonColors = JetRoundedButtonDefaults.operationButtonColors(),                     onClick = {                         onCalculateExpression.invoke()                     })             }         }     } }  \/\/ \u041f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 UI \u0434\u043b\u044f \u0441\u0432\u0435\u0442\u043b\u043e\u0439 \u0442\u0435\u043c\u044b @Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) \/\/ \u041f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 UI \u0434\u043b\u044f \u0442\u0435\u043c\u043d\u043e\u0439 \u0442\u0435\u043c\u044b @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable private fun ShowPreview2() {     MyTechCalculatorTheme {         HomeViewInit(viewState = HomeViewState(), {}, {}, {}, {}, {})     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0430\u043b\u0438\u0442\u0440\u044b \u043a\u043d\u043e\u043f\u043e\u043a \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 <strong><em>Row+Column<\/em><\/strong>, \u0430\u00a0\u043d\u0435\u00a0<strong><em>ConstraintLayout<\/em><\/strong>. \u041d\u0430 \u044d\u0442\u043e \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u044b:<\/p>\n<ul>\n<li>\n<p>\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0432 Jetpack Compose \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432;<\/p>\n<\/li>\n<li>\n<p>\u0412 Compose Multiplatform \u0435\u0449\u0451 \u043d\u0435\u0442 ConstraintLayout \ud83d\ude09<\/p>\n<\/p>\n<\/li>\n<\/ul>\n<p><strong><em>\u0412\u0430\u0436\u043d\u043e\u0435 \u043f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435:<\/em><\/strong> \u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f UI \u0438\u043c\u0435\u0435\u0442 \u043e\u0434\u0438\u043d \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u043a &#8212; \u043d\u0430 \u043f\u043b\u0430\u043d\u0448\u0435\u0442\u0430\u0445 \u0438 \u043d\u0430 \u041f\u041a, \u0435\u0441\u043b\u0438 \u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435, \u043a\u043d\u043e\u043f\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u043d\u0435\u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u043a\u0430\u043a \u043f\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438, \u0442\u0430\u043a \u0438 \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438. \u0422.\u0435. \u043a\u043d\u043e\u043f\u043a\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440, \u0430 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u0431\u0443\u0434\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u043a, \u0447\u0442\u043e \u0443\u0441\u043b\u043e\u0436\u043d\u0438\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/5c5\/ada\/490\/5c5ada490be7d2ca136a44c7aaea857c.png\" alt=\"\u041f\u0440\u0438\u043c\u0435\u0440 &quot;\u043f\u043e\u0435\u0445\u0430\u0432\u0448\u0435\u0439&quot; \u0432\u0435\u0440\u0441\u0442\u043a\u0438 \u043d\u0430 \u043f\u043b\u0430\u043d\u0448\u0435\u0442\u0435\" title=\"\u041f\u0440\u0438\u043c\u0435\u0440 &quot;\u043f\u043e\u0435\u0445\u0430\u0432\u0448\u0435\u0439&quot; \u0432\u0435\u0440\u0441\u0442\u043a\u0438 \u043d\u0430 \u043f\u043b\u0430\u043d\u0448\u0435\u0442\u0435\" width=\"1871\" height=\"1169\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5c5\/ada\/490\/5c5ada490be7d2ca136a44c7aaea857c.png\"\/><\/p>\n<div><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 &#171;\u043f\u043e\u0435\u0445\u0430\u0432\u0448\u0435\u0439&#187; \u0432\u0435\u0440\u0441\u0442\u043a\u0438 \u043d\u0430 \u043f\u043b\u0430\u043d\u0448\u0435\u0442\u0435<\/figcaption><\/div>\n<\/figure>\n<p>\u0420\u0435\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0442\u043a\u0438 \u043f\u043e\u0434 \u043f\u043b\u0430\u043d\u0448\u0435\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0448\u0438\u0440\u0438\u043d\u0435 \u044d\u043a\u0440\u0430\u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 <code>400dp<\/code>.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">BoxWithConstraints(   modifier = Modifier.fillMaxSize(),   contentAlignment = Alignment.Center ) {     \/\/ UI \u0434\u043b\u044f \u043f\u043b\u0430\u043d\u0448\u0435\u0442\u043e\u0432     if (this.maxWidth > 400.dp) {         val marginBetweenElements = 16.dp         val elementWidth = this.maxWidth \/ 4 - marginBetweenElements         val elementHeight = this.maxHeight \/ 6 - marginBetweenElements                  Row(             modifier = Modifier                 .padding(horizontal = 24.dp, vertical = 12.dp),             horizontalArrangement = Arrangement.spacedBy(marginBetweenElements)         ) {             Column(                 modifier = Modifier.fillMaxHeight(),                 verticalArrangement = Arrangement.spacedBy(marginBetweenElements)             ) {                 JetRoundedTextButton(modifier = Modifier.size(elementWidth, elementHeight),                     text = \"C\",                     buttonColors = JetRoundedButtonDefaults.operationButtonColors(),                     onClick = {                         onClearExpression.invoke()                     })                  JetRoundedTextButton(modifier = Modifier.size(elementWidth, elementHeight),                     text = \"\u221a\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.OperationSqrt)                     })                  JetRoundedTextButton(modifier = Modifier.size(elementWidth, elementHeight),                     text = \"1\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.Value1)                     })                  JetRoundedTextButton(modifier = Modifier.size(elementWidth, elementHeight),                     text = \"4\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.Value4)                     })                  JetRoundedTextButton(modifier = Modifier.size(elementWidth, elementHeight),                     text = \"7\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.Value7)                     })                  JetRoundedTextButton(modifier = Modifier.size(elementWidth, elementHeight),                     text = \".\",                     buttonColors = JetRoundedButtonDefaults.numberButtonColors(),                     onClick = {                         onChangeExpression.invoke(ExpressionItem.ValuePoint)                     })             }              \/* ... *\/         }     } else {         \/* UI \u0434\u043b\u044f \u0441\u043c\u0430\u0440\u0442\u0444\u043e\u043d\u043e\u0432*\/     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435:<\/em> \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 <code>BoxWithConstraints()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0437\u043c\u0435\u0440\u044f\u0435\u0442 \u0441\u0432\u043e\u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f, \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u044d\u0442\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 UI-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u0438 UI \u043f\u0440\u0438\u043c\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d05\/973\/87f\/d0597387f3a2df444f9786820e69e255.png\" alt=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u0438 UI \u043d\u0430 \u043f\u043b\u0430\u043d\u0448\u0435\u0442\u0435\" title=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u0438 UI \u043d\u0430 \u043f\u043b\u0430\u043d\u0448\u0435\u0442\u0435\" width=\"1871\" height=\"1169\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d05\/973\/87f\/d0597387f3a2df444f9786820e69e255.png\"\/><\/p>\n<div><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u0438 UI \u043d\u0430 \u043f\u043b\u0430\u043d\u0448\u0435\u0442\u0435<\/figcaption><\/div>\n<\/figure>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/em>: \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u0438 UI \u043f\u043e\u0434 \u0440\u0430\u0437\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u043c \u0438 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c (\u0432\u0441\u0435\u0433\u0434\u0430 \u0435\u0441\u0442\u044c \u0447\u0442\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c), \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u043b\u0438\u0448\u044c \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0430\u043a\u0446\u0435\u043d\u0442 \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b.<\/p>\n<p><strong>\u0428\u0430\u0433 6.<\/strong> \u0412\u043d\u0435\u0441\u0451\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0444\u0430\u0439\u043b <code>HomeScreen.kt<\/code>:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">@Composable fun HomeScreen() {      HomeViewInit(         viewState = HomeViewState(),         onChangeTheme = {          },         onChangeExpression = {          },         onCalculateExpression = {          },         onClearExpression = {          },         onRemoveLastSymbol = {          }     ) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435:<\/em> \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430 \u0435\u0449\u0451 \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430, \u043e\u0441\u0442\u0430\u0432\u0438\u043c \u0435\u0433\u043e \u0432 \u0442\u0430\u043a\u043e\u043c \u0432\u0438\u0434\u0435. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0438 \u0434\u043e\u043f\u0438\u0448\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435.<\/p>\n<p><strong>\u0428\u0430\u0433 7.<\/strong> \u041e\u0431\u043d\u043e\u0432\u0438\u043c \u043a\u043e\u0434 \u0432 <code>MainActivity.kt<\/code>, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u043c\u0438 \u044d\u043a\u0440\u0430\u043d\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">class MainActivity : ComponentActivity() {      override fun onCreate(savedInstanceState: Bundle?) {         super.onCreate(savedInstanceState)         setContent {             MyTechCalculatorTheme {                 HomeScreen()             }         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 UI \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430. \u041c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440 Android \u0438 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \ud83d\ude09<\/p>\n<hr\/>\n<h3>\u0410 \u0433\u0434\u0435 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438?<\/h3>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439: <a href=\"https:\/\/github.com\/alekseyHunter\/compose-tech-calculator\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/alekseyHunter\/compose-tech-calculator<\/a><\/p>\n<p>\u0415\u0441\u043b\u0438 \u0443 \u0412\u0430\u0441 \u0431\u0443\u0434\u0443\u0442 \u0438\u0434\u0435\u0438 \u043f\u043e \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044e UI \u0438\u043b\u0438 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e \u043d\u043e\u0432\u043e\u043c\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443, \u0441\u043c\u0435\u043b\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0439\u0442\u0435 Pull Request \ud83d\ude09 \u0414\u043b\u044f \u0435\u0433\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044f \u0430\u0432\u0442\u043e\u0440\u043e\u043c \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043a \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0441 \u0441\u0441\u044b\u043b\u043a\u043e\u0439 \u043d\u0430 PR.<\/p>\n<hr\/>\n<h3>\u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u0430\u0432\u0442\u043e\u0440\u043e\u0432 \u043f\u043e Jetpack Compose \u043d\u0430 \u0425\u0430\u0431\u0440\u0435:<\/h3>\n<ul>\n<li>\n<p>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0432 Jetpack Compose: <a href=\"https:\/\/habr.com\/ru\/news\/734876\/\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/ru\/news\/734876\/<\/a><\/p>\n<\/li>\n<li>\n<p>\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0432 Compose: <a href=\"https:\/\/habr.com\/ru\/companies\/otus\/articles\/656231\/\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/ru\/companies\/otus\/articles\/656231\/<\/a><\/p>\n<\/li>\n<li>\n<p>\u041e\u0441\u043e\u0437\u043d\u0430\u043d\u043d\u0430\u044f \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f Compose: <a href=\"https:\/\/habr.com\/ru\/companies\/ozontech\/articles\/742854\/\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/ru\/companies\/ozontech\/articles\/742854\/<\/a><\/p>\n<\/li>\n<\/ul>\n<hr\/>\n<p><strong>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435:<\/strong><\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e &#8212; \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c ViewModel, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0434\u0443\u043b\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0433\u043e \u0441\u043f\u0443\u0441\u043a\u0430.<\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435!<\/p>\n<div class=\"persona\"><img decoding=\"async\" class=\"image persona__image\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/f99\/2c5\/84d\/f992c584d8761dc6cda7dfebc5eef0b7.jpg\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f99\/2c5\/84d\/f992c584d8761dc6cda7dfebc5eef0b7.jpg\" data-blurred=\"true\"\/><\/p>\n<h5 class=\"persona__heading\">\u0410\u043b\u0435\u043a\u0441\u0435\u0439 \u041e\u0445\u043e\u0442\u043d\u0438\u0447\u0435\u043d\u043a\u043e<\/h5>\n<p>\u0410\u0432\u0442\u043e\u0440 \u0422\u0435\u043b\u0435\u0433\u0440\u0430\u043c-\u043a\u0430\u043d\u0430\u043b\u0430 &#171;<a href=\"https:\/\/t.me\/android_for_juniors\" rel=\"noopener noreferrer nofollow\">Android \u0434\u043b\u044f Junior&#8217;\u043e\u0432&#187;<\/a> (@android_for_juniors)<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/798981\/\"> https:\/\/habr.com\/ru\/articles\/798981\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><\/figure>\n<p>\u0417\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439, \u0434\u043e\u0440\u043e\u0433\u043e\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c!<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u043e\u044d\u0442\u0430\u043f\u043d\u0443\u044e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u0438\u0437\u0430\u0439\u043d-\u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0438 UI \u0434\u043b\u044f Android-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f &#171;\u041a\u0430\u043b\u044c\u043a\u0443\u043b\u044f\u0442\u043e\u0440&#187;, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 Jetpack Compose. \u041d\u0430\u0447\u043d\u0451\u043c \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u044d\u043c\u0443\u043b\u044f\u0442\u043e\u0440\u0435.<\/p>\n<p><strong>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f \u043f\u043e\u00a0\u0446\u0438\u043a\u043b\u0443 \u0441\u0442\u0430\u0442\u0435\u0439:<\/strong><\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/798755\/\" rel=\"noopener noreferrer nofollow\">\u0427\u0430\u0441\u0442\u044c 1 &#8212; \u041f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/a><\/p>\n<\/li>\n<li>\n<p>\u0427\u0430\u0441\u0442\u044c 2 &#8212; UI (\u0412\u044b \u0437\u0434\u0435\u0441\u044c)<\/p>\n<\/li>\n<li>\n<p>\u0427\u0430\u0441\u0442\u044c 3 &#8212; \u0411\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0430 (\u0412 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435)<\/p>\n<\/li>\n<\/ul>\n<h3>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/h3>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0435\u0449\u0451 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d \u043f\u0440\u043e\u0435\u043a\u0442, \u0430 Android Studio \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u0430\u0441\u044c \u0432\u043f\u0435\u0440\u0432\u044b\u0435.<\/p>\n<p><strong>\u0428\u0430\u0433 1.<\/strong> \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d &#171;Empty Compose Activity&#187;:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041f\u0435\u0440\u0432\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430, \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u0442\u043e\u043b\u0431\u0435\u0446, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f &#171;Empty Activity&#187;, \u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443 \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0439 \u0448\u0435\u0441\u0442\u0438\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a \ud83d\ude09<\/figcaption><\/div>\n<\/figure>\n<p><strong>\u0428\u0430\u0433 2.<\/strong> \u0412\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (1), \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u0430 (2), \u043c\u0435\u0441\u0442\u043e\u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (3) \u0438 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e Android (4):<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0412 \u043f\u043e\u043b\u0435 (1) \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c &#171;My Tech Calculator&#187;, \u0432 \u043f\u043e\u043b\u0435 (2) \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c &#171;my.tech.calculator&#187;, \u0430 \u043f\u043e\u043b\u044f 3 \u0438 4 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c\u0438.<\/figcaption><\/div>\n<\/figure>\n<p>\u0421\u0442\u043e\u0438\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0430 \u044d\u0442\u043e\u043c \u0448\u0430\u0433\u0435 \u0438 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u043e\u0435 \u043f\u043e\u043b\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e:<\/p>\n<ul>\n<li>\n<p><em>Application name<\/em> &#8212; \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0443\u0432\u0438\u0434\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435 \u0441\u043c\u0430\u0440\u0442\u0444\u043e\u043d\u0430;<\/p>\n<\/li>\n<li>\n<p><em>Package name<\/em> &#8212; \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0438\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0437\u043d\u0430\u043a\u043e\u043c &#171;.&#187; (\u0442\u043e\u0447\u043a\u0430);<\/p>\n<\/li>\n<li>\n<p><em>Save location<\/em> &#8212; \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 \u0412\u0430\u0448\u0435\u043c \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0435;<\/p>\n<\/li>\n<li>\n<p><em>Minimum SDK<\/em> &#8212; \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f Android, \u0442.\u0435. \u043d\u0438\u0436\u0435 \u044d\u0442\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043d\u0435 \u0441\u043c\u043e\u0433\u0443\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e \u0433\u043e\u0442\u043e\u0432\u043d\u043e\u0441\u0442\u0438 \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u043c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 &#171;Finish&#187; \u0432 \u043d\u0438\u0436\u043d\u0435\u043c \u043b\u0435\u0432\u043e\u043c \u0443\u0433\u043b\u0443 \u0434\u0438\u0430\u043b\u043e\u0433\u043e\u0432\u043e\u0433\u043e \u043e\u043a\u043d\u0430.<\/p>\n<p><strong>\u0428\u0430\u0433 3.<\/strong> \u041f\u043e\u0441\u043b\u0435 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0430\u0435\u043c \u043a \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<figure class=\"\">\n<div><figcaption>Domain-\u043c\u043e\u0434\u0443\u043b\u044c \u043e\u043f\u0443\u0441\u0442\u0438\u043b\u0438, \u0442.\u043a. \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435 \u043e\u043d \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u0435\u043d<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u043f\u044b\u0442\u043d\u044b\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u0441\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u043e \u043c\u043d\u0435\u043d\u0438\u0438, \u0447\u0442\u043e \u043d\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0432 \u043f\u0440\u043e\u0441\u0442\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e\u043c\u043e\u0434\u0443\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0438\u0437\u044b\u0441\u043a\u0430\u043d\u043d\u044b\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d\u0438 \u043b\u0438\u0448\u044c \u0443\u0441\u043b\u043e\u0436\u043d\u044f\u044e\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u044e\u0442 \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e.<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044f \u044d\u0442\u0438\u043c \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u044f\u043c \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<ul>\n<li>\n<p><strong><em>base<\/em><\/strong> &#8212; \u0445\u0440\u0430\u043d\u0438\u0442 \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p><strong><em>ui<\/em><\/strong> &#8212; \u0445\u0440\u0430\u043d\u0438\u0442 \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f;<\/p>\n<ul>\n<li>\n<p><em>theme &#8212; \u0444\u0430\u0439\u043b\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u0434\u0438\u0437\u0430\u0439\u043d-\u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f;<\/em><\/p>\n<ul>\n<li>\n<p>components &#8212; <em>\u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b;<\/em><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><em>screens &#8212; \u0444\u0430\u0439\u043b\u044b, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u044d\u043a\u0440\u0430\u043d\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f;<\/em><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong><em>data<\/em><\/strong> &#8212; \u0445\u0440\u0430\u043d\u0438\u0442 \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435\u043c \u0438 \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0445;<\/p>\n<ul>\n<li>\n<p><em>datasource &#8212; \u043a\u043b\u0430\u0441\u0441\u044b, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c \u0434\u0430\u043d\u043d\u044b\u043c;<\/em><\/p>\n<\/li>\n<li>\n<p><em>repository &#8212; \u043a\u043b\u0430\u0441\u0441\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0435 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438;<\/em><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong><em>utils<\/em><\/strong> &#8212; \u0445\u0440\u0430\u043d\u0438\u0442 \u0432\u0441\u0435 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c\u0441\u044f \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u043e\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0448\u0430\u0433\u0443.<\/p>\n<hr\/>\n<h3>\u041f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0434\u0438\u0437\u0430\u0439\u043d-\u0441\u0438\u0441\u0442\u0435\u043c\u0443:<\/h3>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0434\u0438\u0437\u0430\u0439\u043d-\u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u043e\u0432 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0434 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u0435\u0435, \u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u0440\u0438 \u0441\u043e\u043f\u0440\u043e\u0432\u043e\u0436\u0434\u0435\u043d\u0438\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u043a\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p><strong>\u0428\u0430\u0433 1.<\/strong> \u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e Material-\u0442\u0435\u043c\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041e\u043d\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e \u043f\u0443\u0442\u0438 <code>\"ui\/theme\"<\/code>.<\/p>\n<figure class=\"\">\n<div><figcaption>\u0412 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f 3 \u0444\u0430\u0439\u043b\u0430, \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0437\u0430 \u0446\u0432\u0435\u0442\u043e\u0432\u0443\u044e \u0441\u0445\u0435\u043c\u0443, \u0442\u0435\u043c\u0443 \u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0441\u0442\u0438\u043b\u0438<\/figcaption><\/div>\n<\/figure>\n<p><em>\u0428\u0430\u0433 1.1.<\/em> \u0412 \u0444\u0430\u0439\u043b\u0435 <code>Color.kt<\/code> \u043c\u0435\u043d\u044f\u0435\u043c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">\/\/ \u0426\u0432\u0435\u0442\u0430 \u0434\u043b\u044f \u0441\u0432\u0435\u0442\u043b\u043e\u0439 \u0442\u0435\u043c\u044b val LightBackground = Color(0xFFC6C6C6) val LightSurface = Color(0xFFF2F2F2) val LightPrimaryColor = Color(0xFF575757) val LightSecondaryColor = Color(0xFFE1E1E1) val LightOnPrimaryColor = Color(0xFFFFFFFF) val LightOnSecondaryColor = Color(0xFF282828) val LightOnSurfaceColor = Color(0xFF282828)  \/\/ \u0426\u0432\u0435\u0442\u0430 \u0434\u043b\u044f \u0442\u0435\u043c\u043d\u043e\u0439 \u0442\u0435\u043c\u044b val DarkBackground = Color(0xFF333333) val DarkSurface = Color(0xFF212121) val DarkPrimaryColor = Color(0xFF323232) val DarkSecondaryColor = Color(0xFF535353) val DarkOnPrimaryColor = Color(0xFFFFFFFF) val DarkOnSecondaryColor = Color(0xFFFFFFFF) val DarkOnSurfaceColor = Color(0xFFFFFFFF)<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<blockquote>\n<p>\u0426\u0432\u0435\u0442\u0430 \u043c\u044b \u0432\u0437\u044f\u043b\u0438 \u0438\u0437 \u0446\u0432\u0435\u0442\u043e\u0432\u043e\u0439 \u043f\u0430\u043b\u0438\u0442\u0440\u044b, \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u043e\u0439 <a href=\"https:\/\/habr.com\/ru\/articles\/798755\/\" rel=\"noopener noreferrer nofollow\">\u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>.<\/p>\n<\/blockquote>\n<p><em>\u0428\u0430\u0433 1.2.<\/em> \u0412 \u0444\u0430\u0439\u043b\u0435 <code>Type.kt<\/code> \u043c\u0435\u043d\u044f\u0435\u043c \u043a\u043e\u0434 \u043d\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">val Typography = Typography(     bodyLarge = TextStyle(         fontFamily = FontFamily.Default,         fontWeight = FontWeight.Normal,         fontSize = 30.sp     ),     titleLarge = TextStyle(         fontFamily = FontFamily.Default,         fontWeight = FontWeight.Normal,         fontSize = 36.sp     ) )<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<blockquote>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0443 \u043d\u0430\u0441 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0441\u0442\u0438\u043b\u044c <code>\"bodyLarge\"<\/code> \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043a\u043d\u043e\u043f\u043e\u043a \u0438 \u0432\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u043c\u0430\u0442. \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0430 \u0441\u0442\u0438\u043b\u044c <code>\"titleLarge\"<\/code> \u0434\u043b\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0442. \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f.<\/p>\n<\/blockquote>\n<p><em>\u0428\u0430\u0433 1.3.<\/em> \u0412 \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u0444\u0430\u0439\u043b\u0430 <code>Theme.kt<\/code> \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u0446\u0432\u0435\u0442\u043e\u0432\u043e\u0439 \u0441\u0445\u0435\u043c\u044b \u0438\u0437 Material 3. \u041c\u044b \u0445\u043e\u0442\u0438\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0442\u0438\u043b\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443\u0434\u0430\u043b\u0438\u043c \u044d\u0442\u0443 \u0444\u0438\u0447\u0443 \u0438 \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u0446\u0432\u0435\u0442\u043e\u0432\u0443\u044e \u0441\u0445\u0435\u043c\u0443:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u043e\u0434<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">private val DarkColorScheme = darkColorScheme(     primary = DarkPrimaryColor,     onPrimary = DarkOnPrimaryColor,     secondary = DarkSecondaryColor,     onSecondary = DarkOnSecondaryColor,     background = DarkBackground,     surface = DarkSurface,     onSurface = DarkOnSurfaceColor )  private val LightColorScheme = lightColorScheme(     primary = LightPrimaryColor,     onPrimary = LightOnPrimaryColor,     secondary = LightSecondaryColor,     onSecondary = LightOnSecondaryColor,     background = LightBackground,     surface = LightSurface,     onSurface = LightOnSurfaceColor )  @Composable fun MyTechCalculatorTheme(     darkTheme: Boolean = isSystemInDarkTheme(),     content: @Composable () -> Unit ) {     val colorScheme = when {         darkTheme -> DarkColorScheme         else -> LightColorScheme     }      MaterialTheme(         colorScheme = colorScheme,         typography = Typography,         content = content     ) }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><strong>\u0428\u0430\u0433 2.<\/strong> \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0434\u0438\u0437\u0430\u0439\u043d-\u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0435\u0433\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u0432\u0435\u0442\u043b\u043e\u0439 \u0438 \u0442\u0435\u043c\u043d\u043e\u0439 \u0442\u0435\u043c\u044b:<\/p>\n<figure class=\"\">\n<div><figcaption>\u041a\u043d\u043e\u043f\u043a\u0430 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043c\u044b<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0442\u043e\u0438\u0442 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0438\u0442\u044c &#171;best practices&#187; \u043f\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432:<\/p>\n<blockquote>\n<ul>\n<li>\n<p>\u0421\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c \u0438\u0437 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u043f\u0435\u0440\u0432\u044b\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c \u0432 Composable-\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>Modifier<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>onClick<\/code> (\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043a\u043b\u0438\u043a\u0430 \u043f\u043e UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443) \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c, \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 <code>content<\/code>  (\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f).<\/p>\n<\/li>\n<li>\n<p>\u0414\u043b\u044f Composable-\u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u043e\u043c\u0435\u0447\u0435\u043d\u043d\u043e\u0439 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439 <code>@Preview<\/code> \u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0435\u0439 \u0437\u0430 \u043f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 <code>private<\/code>.<\/p>\n<\/li>\n<\/ul>\n<\/blockquote>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">@Composable fun JetSwitchButton(     modifier: Modifier = Modifier,     isChecked: Boolean = false,     onValueChange: (Boolean) -> Unit ) {     val iconId = if (isChecked)         R.drawable.ic_day     else         R.drawable.ic_moon      Row(         modifier = modifier             .wrapContentWidth()             .background(                 MaterialTheme.colorScheme.secondary,                 RoundedCornerShape(topStart = 16.dp, bottomEnd = 16.dp)             )             .clip(                 RoundedCornerShape(topStart = 16.dp, bottomEnd = 16.dp)             )             .clickable(onClick = {                 onValueChange.invoke(!isChecked)             }),         verticalAlignment = Alignment.CenterVertically     ) {         Box(             modifier = Modifier                 .padding(horizontal = 8.dp, vertical = 4.dp)                 .size(48.dp, 24.dp)                 .background(MaterialTheme.colorScheme.onSecondary, RoundedCornerShape(16.dp)),             contentAlignment = Alignment.CenterStart         ) {             Box(                 modifier = Modifier                     .padding(horizontal = 8.dp)                     .size(14.dp)                     .background(MaterialTheme.colorScheme.secondary, CircleShape)             )         }          Icon(             modifier = Modifier.padding(horizontal = 8.dp),             imageVector = ImageVector.vectorResource(id = iconId), contentDescription = \"\",             tint = MaterialTheme.colorScheme.onSecondary         )     } }  \/\/ \u041f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 UI \u0434\u043b\u044f \u0441\u0432\u0435\u0442\u043b\u043e\u0439 \u0442\u0435\u043c\u044b @Preview(uiMode = Configuration.UI_MODE_NIGHT_NO) \/\/ \u041f\u0440\u0435\u0434\u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 UI \u0434\u043b\u044f \u0442\u0435\u043c\u043d\u043e\u0439 \u0442\u0435\u043c\u044b @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable private fun ShowPreview2() {     MyTechCalculatorTheme {         Row {             JetSwitchButton(                 modifier = Modifier                     .fillMaxWidth()                     .height(32.dp), isChecked = true, {}             )         }     } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435:<\/em> \u041e\u0441\u043e\u0431\u043e\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0443\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. \u041e\u0431\u044b\u0447\u043d\u043e \u043e\u043d\u043e \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0448\u0430\u0431\u043b\u043e\u043d\u0443 &#8212; <code>\"Jet{ComponentName}\"<\/code>, \u0433\u0434\u0435 &#171;Jet&#187; \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u043e\u0442 \u0441\u043b\u043e\u0432\u0430 &#171;Jetpack&#187;. <\/p>\n<p>\u041f\u0440\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0441\u0442\u043e\u0438\u0442 \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0439 \u0432 Jetpack Compose &#8212; Card, Button, Icon \u0438 \u0442.\u0434. <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<ul>\n<li>\n<p><code>JetImageLoader()<\/code> &#8212; \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p><code>JetRatingBar()<\/code> &#8212; \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0449\u0438\u0439 \u043f\u044f\u0442\u0438\u0437\u0432\u0435\u0437\u0434\u043e\u0447\u043d\u044b\u0439 \u0440\u0435\u0439\u0442\u0438\u043d\u0433;<\/p>\n<\/li>\n<li>\n<p><code>JetEditorLayout()<\/code> &#8212; \u043c\u0430\u043a\u0435\u0442 \u0434\u043b\u044f \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 &#171;Jet&#187; \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u043c, \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u043d\u0435\u0433\u043e \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043f\u0440\u0435\u0444\u0438\u043a\u0441 &#8212; \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0438\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u0422\u0430\u043a\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044e \u043f\u043e \u0434\u0438\u0437\u0430\u0439\u043d-\u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u0435\u0449\u0451 \u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e.<\/p>\n<p><strong>\u0428\u0430\u0433 3.<\/strong> \u041f\u0435\u0440\u0435\u0439\u0434\u0435\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443, \u0443\u0436\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c\u0443, \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u043c\u0443 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443. \u0422\u0430\u043a\u0436\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0435\u0433\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u0432\u0435\u0442\u043b\u043e\u0439 \u0438 \u0442\u0435\u043c\u043d\u043e\u0439 \u0442\u0435\u043c\u044b:<\/p>\n<figure class=\"\">\n<div><figcaption>\u0421\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u043d\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u044f\u0442\u044c &#171;best practices&#187; \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f Jetpack Compose:<\/p>\n<blockquote>\n<ul>\n<li>\n<p>\u041f\u0440\u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0445 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0432\u044b\u043d\u043e\u0441\u0438\u0442\u044c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 <code>@Immutable<\/code> \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u0443\u0445\u043e\u0434\u0430 \u043e\u0442 \u043b\u0438\u0448\u043d\u0438\u0445 \u0440\u0435\u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0439.<\/p>\n<\/li>\n<li>\n<p>\u041b\u044e\u0431\u044b\u0435 \u0446\u0432\u0435\u0442\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0432 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0445, \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0431\u0440\u0430\u0442\u044c \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438\u0437 <code>MaterialTheme<\/code>, \u0430 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u043a\u043e\u0434\u0435 (\u0432\u043d\u0443\u0442\u0440\u0438 Composable-\u0444\u0443\u043d\u043a\u0446\u0438\u0438).<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0438 Composable-\u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0434\u043b\u044f \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<\/blockquote>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e UI-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0441 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u043f\u0440\u0430\u043a\u0442\u0438\u043a:<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"kotlin\">@Composable fun JetRoundedButton(     modifier: Modifier = Modifier,     text: String, \/\/ \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442     buttonColors: JetRoundedButtonColors,     onClick: () -> Unit ) {     Box(         modifier = modifier             .clip(CircleShape)             .background(buttonColors.containerColor(), CircleShape)             .innerShadow(<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-370320","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/370320","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=370320"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/370320\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=370320"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=370320"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=370320"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}