{"id":382936,"date":"2024-06-29T04:35:40","date_gmt":"2024-06-29T04:35:40","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=382936"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=382936","title":{"rendered":"<span>\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e \u043f\u043e Jetpack Compose: \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0430\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043a\u043d\u043e\u043f\u043a\u0443-\u0441\u0447\u0435\u0442\u0447\u0438\u043a<\/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<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0434\u043b\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0411\u043e\u0440\u043e\u0437\u0434\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0440\u044b \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430 \u0432 \u043f\u043e\u0438\u0441\u043a\u0430\u0445 \u0445\u043e\u0440\u043e\u0448\u0438\u0445 \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439, \u044f \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u044d\u0442\u043e\u0442 \u0434\u0438\u0437\u0430\u0439\u043d \u043e\u0442 <a href=\"https:\/\/dribbble.com\/ehsancinematic\"><u>\u042d\u0445\u0441\u0430\u043d\u0430 \u0420\u0430\u0445\u0438\u043c\u0438<\/u><\/a> (Ehsan Rahimi) \u043d\u0430 Dribble. \u041f\u0440\u0438\u0434\u044f \u043a \u0432\u044b\u0432\u043e\u0434\u0443, \u0447\u0442\u043e \u0432\u043e\u0441\u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0433\u043e \u0432 Compose \u2014 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0430\u044f, \u044f \u0437\u0430\u043a\u0430\u0442\u0430\u043b \u0440\u0443\u043a\u0430\u0432\u0430 \u0438 \u043f\u0440\u0438\u043d\u044f\u043b\u0441\u044f \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0412 \u044d\u0442\u043e\u043c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435 \u044f \u043f\u043e\u0434\u0435\u043b\u044e\u0441\u044c \u0441 \u0432\u0430\u043c\u0438 \u043a\u0430\u0436\u0434\u044b\u043c \u0448\u0430\u0433\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u044f\u043b \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u0434\u0438\u0437\u0430\u0439\u043d\u0430 \u0432 Jetpack Compose.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b8b\/9ca\/065\/b8b9ca065c67dd4ae7d0b57b2683f47e.gif\" alt=\"\u0414\u0438\u0437\u0430\u0439\u043d \u043a\u043d\u043e\u043f\u043a\u0438-\u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u043e\u0442 \u042d\u0445\u0441\u0430\u043d\u0430 \u0420\u0430\u0445\u0438\u043c\u0438.\" title=\"\u0414\u0438\u0437\u0430\u0439\u043d \u043a\u043d\u043e\u043f\u043a\u0438-\u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u043e\u0442 \u042d\u0445\u0441\u0430\u043d\u0430 \u0420\u0430\u0445\u0438\u043c\u0438.\" width=\"1600\" height=\"1200\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b8b\/9ca\/065\/b8b9ca065c67dd4ae7d0b57b2683f47e.gif\"\/><\/p>\n<div><figcaption>\u0414\u0438\u0437\u0430\u0439\u043d \u043a\u043d\u043e\u043f\u043a\u0438-\u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u043e\u0442 <a href=\"https:\/\/dribbble.com\/ehsancinematic\"><u>\u042d\u0445\u0441\u0430\u043d\u0430 \u0420\u0430\u0445\u0438\u043c\u0438<\/u><\/a>.<\/figcaption><\/div>\n<\/figure>\n<p><em>\u0421\u0440\u0430\u0437\u0443 \u043e\u0433\u043e\u0432\u043e\u0440\u044e\u0441\u044c, \u0447\u0442\u043e \u0445\u043e\u0442\u044c \u043c\u044b \u0438 \u0431\u0443\u0434\u0435\u043c \u0441\u0442\u0430\u0440\u0430\u0442\u044c\u0441\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0442\u043e\u0447\u043d\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u0434\u0438\u0437\u0430\u0439\u043d\u0443, \u0432 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0435\u0449\u0435 \u0435\u0441\u0442\u044c \u043d\u0430\u0434 \u0447\u0435\u043c \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u2014 \u043a\u043d\u043e\u043f\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0435 \u0435\u0449\u0435 \u0431\u043e\u043b\u0435\u0435 \u043f\u043b\u0430\u0432\u043d\u043e\u0439 \u0438 \u0431\u043b\u0438\u0437\u043a\u043e\u0439 \u043a \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u0443.<\/em><\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043c\u0430\u043a\u0435\u0442\u0430<\/h3>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u043c\u044b \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043c\u0430\u043a\u0435\u0442\u0430 \u0431\u0435\u0437 \u043a\u0430\u043a\u0438\u0445-\u043b\u0438\u0431\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u0438\u043b\u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u0435\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0434\u0438\u0437\u0430\u0439\u043d \u043d\u0430 \u0434\u0432\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430: \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u0438 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u043d\u044b\u0439 \u043c\u0430\u043a\u0435\u0442 \u043a\u043d\u043e\u043f\u043a\u0438 \u0441 \u0438\u043a\u043e\u043d\u043a\u0430\u043c\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f, \u0441\u0431\u0440\u043e\u0441\u0430 \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u0435\u043d \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u043c\u0430\u043a\u0435\u0442 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u0434\u0432\u0443\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u043d\u043e\u043f\u043a\u0430 \u0441\u0431\u0440\u043e\u0441\u0430 \u0441\u043a\u0440\u044b\u0442\u0430 \u043f\u043e\u0434 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u044b\u043c \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u043e\u043c, \u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044b \u043a\u043d\u043e\u043f\u043a\u0438, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>Box<\/code>, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 1: Composable \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0433\u043e \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043c\u0430\u043a\u0435\u0442\u0430<\/h4>\n<pre><code class=\"kotlin\">@Composable private fun CounterButton(     value: String,     modifier: Modifier = Modifier ) {     Box(         contentAlignment = Alignment.Center,         modifier = modifier             .width(200.dp)             .height(80.dp)     ) {          ButtonContainer(             onValueDecreaseClick = { \/*TODO*\/ },             onValueIncreaseClick = { \/*TODO*\/ },             onValueClearClick = { \/*TODO*\/ },             modifier = Modifier         )          DraggableThumbButton(             value = value,             onClick = { \/*TODO*\/ },             modifier = Modifier.align(Alignment.Center)         )     } }<\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f \u0441 composable <code>ButtonContainer<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0430\u0448\u0438 \u043a\u043d\u043e\u043f\u043a\u0438-\u0438\u043a\u043e\u043d\u043a\u0438. \u0422\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u0438 \u0442\u0440\u0438 \u043a\u043d\u043e\u043f\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>Row<\/code>. \u0413\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0438 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435, \u0432 \u0446\u0435\u043d\u0442\u0440\u0435 \u0438 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043c\u0430\u043a\u0435\u0442\u0430 \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0436\u0435\u0442 <code>Arrangement.SpaceBetween<\/code>. \u041a\u043d\u043e\u043f\u043a\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e composable <code>IconControlButton<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043f\u0440\u043e\u0441\u0442\u0443 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u0435\u0440\u0442\u043a\u043e\u0439 <code>IconButton<\/code>.<\/p>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0436\u0435 \u0438\u043a\u043e\u043d\u043a\u0438, \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043b\u0438\u0431\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c <\/em><code>androidx.compose.material:material-icons-extended<\/code><em>, \u043b\u0438\u0431\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u0445 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/em><\/p>\n<p>\u0424\u043e\u043d \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u0444\u043e\u0440\u043c\u044b \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 <code>clip(RoundedCornerShape()<\/code>), \u0438 \u043d\u0430\u043c \u0435\u0449\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0446\u0432\u0435\u0442 \u0444\u043e\u043d\u0430. \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u0435\u043d\u044f\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0430\u043b\u044c\u0444\u0430-\u043a\u0430\u043d\u0430\u043b\u0430 \u0446\u0432\u0435\u0442\u0430 \u0444\u043e\u043d\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u0437\u0436\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0430\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430. \u0418 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c tint\u0421olor \u043d\u0430\u0448\u0438\u0445 \u043a\u043d\u043e\u043f\u043e\u043a-\u0438\u043a\u043e\u043d\u043e\u043a. \u041a\u043d\u043e\u043f\u043a\u0443 \u0441\u0431\u0440\u043e\u0441\u0430 \u043c\u044b \u043f\u043e\u043a\u0430 \u0441\u043a\u0440\u043e\u0435\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u0435\u0435 \u043b\u043e\u0433\u0438\u043a\u043e\u0439 \u043c\u044b \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043d\u0446\u0435.<\/p>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0412\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0442\u0430\u043a \u0445\u0430\u0440\u0434\u043a\u043e\u0434\u0438\u0442\u044c \u0446\u0432\u0435\u0442\u0430, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u044d\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441\u043e \u0441\u0432\u0435\u0442\u043b\u043e\u0439\/\u0442\u0435\u043c\u043d\u043e\u0439 \u0442\u0435\u043c\u043e\u0439. \u0417\u0434\u0435\u0441\u044c \u0434\u0435\u043b\u0430\u044e \u044d\u0442\u043e \u0442\u0430\u043a \u0442\u043e\u043f\u043e\u0440\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u0434 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0431\u044b\u043b \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043b\u0430\u043a\u043e\u043d\u0438\u0447\u043d\u044b\u043c.<\/em><\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 2: Composable \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043d\u0430\u0448\u0435\u0439 \u043a\u043d\u043e\u043f\u043a\u0438<\/h4>\n<pre><code class=\"kotlin\">private const val ICON_BUTTON_ALPHA_INITIAL = 0.3f private const val CONTAINER_BACKGROUND_ALPHA_INITIAL = 0.6f  @Composable private fun ButtonContainer(     onValueDecreaseClick: () -> Unit,     onValueIncreaseClick: () -> Unit,     onValueClearClick: () -> Unit,     modifier: Modifier = Modifier,     clearButtonVisible: Boolean = false, ) {     Row(         horizontalArrangement = Arrangement.SpaceBetween,         verticalAlignment = Alignment.CenterVertically,         modifier = modifier             .fillMaxSize()             .clip(RoundedCornerShape(64.dp))             .background(Color.Black.copy(alpha = CONTAINER_BACKGROUND_ALPHA_INITIAL))             .padding(horizontal = 8.dp)     ) {         \/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f         IconControlButton(             icon = Icons.Outlined.Remove,             contentDescription = \"Decrease count\",             onClick = onValueDecreaseClick,             tintColor = Color.White.copy(alpha = ICON_BUTTON_ALPHA_INITIAL)         )          \/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0441\u0431\u0440\u043e\u0441\u0430         if (clearButtonVisible) {             IconControlButton(                 icon = Icons.Outlined.Clear,                 contentDescription = \"Clear count\",                 onClick = onValueClearClick,                 tintColor = Color.White.copy(alpha = ICON_BUTTON_ALPHA_INITIAL)             )         }          \/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f         IconControlButton(             icon = Icons.Outlined.Add,             contentDescription = \"Increase count\",             onClick = onValueIncreaseClick,             tintColor = Color.White.copy(alpha = ICON_BUTTON_ALPHA_INITIAL)         )     } }  @Composable private fun IconControlButton(     icon: ImageVector,     contentDescription: String,     onClick: () -> Unit,     modifier: Modifier = Modifier,     tintColor: Color = Color.White, ) {     IconButton(         onClick = onClick,         modifier = modifier             .size(48.dp)     ) {         Icon(             imageVector = icon,             contentDescription = contentDescription,             tint = tintColor,             modifier = Modifier.size(32.dp)         )     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438-\u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c composable <code>Text<\/code>, \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044b\u0439 \u0432 Box, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u043e\u0431\u0440\u0435\u0437\u043a\u0443 <code>CircleShape<\/code> \u0438 \u0442\u0435\u043d\u044c, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442 \u043a\u0440\u0443\u0433\u043b\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438. \u0414\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043a\u043b\u0438\u043a\u043e\u0432 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>.clickable {}<\/code>.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 3: \u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 composable \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430<\/h4>\n<pre><code class=\"kotlin\">@Composable private fun DraggableThumbButton(     value: String,     onClick: () -> Unit,     modifier: Modifier = Modifier ) {     Box(         contentAlignment = Alignment.Center,         modifier = modifier             .shadow(8.dp, shape = CircleShape)             .size(64.dp)             .clip(CircleShape)             .clickable { onClick() }             .background(Color.Gray)     ) {         Text(             text = value,             color = Color.White,             style = MaterialTheme.typography.headlineLarge,             textAlign = TextAlign.Center,         )     } }<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e composable <code>CounterButton<\/code>.<\/p>\n<pre><code class=\"kotlin\">Column(     modifier = Modifier.wrapContentSize(),     verticalArrangement = Arrangement.Center,     horizontalAlignment = Alignment.CenterHorizontally ) {     CounterButton(value = \"0\") }<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430\u0448 \u043a\u043e\u0434, \u0442\u043e \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0438 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/022\/622\/1a4\/0226221a4c86121340498e4a6c24e5aa.png\" alt=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430\u0448\u0438\u0445 composable.\" title=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430\u0448\u0438\u0445 composable.\" width=\"346\" height=\"159\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/022\/622\/1a4\/0226221a4c86121340498e4a6c24e5aa.png\"\/><\/p>\n<div><figcaption>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430\u0448\u0438\u0445 composable.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u043e\u0433\u0438\u043a\u0438 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430<\/h3>\n<p>\u0412 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0445 \u043c\u0430\u043a\u0435\u0442\u0430\u0445 \u043c\u044b \u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e TODO \u043f\u043e\u0434 \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u0438 \u043a\u043b\u0438\u043a\u043e\u0432. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0434\u043b\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430. \u041c\u044b \u0431\u044b \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u0438, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0431\u044b\u043b\u043e \u0432\u043d\u0443\u0442\u0440\u0438 composable \u043a\u043d\u043e\u043f\u043a\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u044b\u043d\u0435\u0441\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u0438 \u043a\u043b\u0438\u043a\u043e\u0432 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 <code>CounterButton<\/code>.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 4: Composable \u043a\u043d\u043e\u043f\u043a\u0438-\u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0441\u043e \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044f\u043c\u0438 \u043a\u043b\u0438\u043a\u043e\u0432<\/h4>\n<pre><code class=\"kotlin\">@Composable private fun CounterButton(     value: String,     onValueDecreaseClick: () -> Unit,     onValueIncreaseClick: () -> Unit,     onValueClearClick: () -> Unit,     modifier: Modifier = Modifier ) {     Box(         contentAlignment = Alignment.Center,         modifier = modifier             .width(200.dp)             .height(80.dp)     ) {          ButtonContainer(             onValueDecreaseClick = onValueDecreaseClick,             onValueIncreaseClick = onValueIncreaseClick,             onValueClearClick = onValueClearClick,             modifier = Modifier         )          DraggableThumbButton(             value = value,             onClick = onValueIncreaseClick,             modifier = Modifier.align(Alignment.Center)         )     } }<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438. \u041c\u044b \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0435\u0433\u043e \u043d\u0430 \u0432\u0435\u0440\u0445\u043d\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c, \u0433\u0434\u0435 \u043e\u043d\u043e, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u043b\u043e\u0441\u044c \u0431\u044b \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0432\u0430\u0448\u0435\u0439 ViewModel.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 5: Composable \u043a\u043d\u043e\u043f\u043a\u0438-\u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c<\/h4>\n<pre><code class=\"kotlin\">var valueCounter by remember {     mutableStateOf(0) }  CounterButton(     value = valueCounter.toString(),     onValueIncreaseClick = {         valueCounter += 1     },     onValueDecreaseClick = {         valueCounter = maxOf(valueCounter - 1, 0)     },     onValueClearClick = {         valueCounter = 0     } )<\/code><\/pre>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c \u043d\u0430\u0448\u0430 \u043a\u043d\u043e\u043f\u043a\u0430-\u0441\u0447\u0435\u0442\u0447\u0438\u043a \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u043e\u0436\u0438\u043b\u0430. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0436\u0438\u043c\u0430\u0442\u044c \u043d\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u0438\u043b\u0438 \u043a\u043d\u043e\u043f\u043a\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f, \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f. \u041a\u043d\u043e\u043f\u043a\u0430 \u0441\u0431\u0440\u043e\u0441\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0435 \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0430 \u0441\u043a\u0440\u044b\u0442\u0430 \u0437\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u043e\u043c. \u041c\u044b \u0432\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u043d\u0435\u0439 \u043f\u043e\u0437\u0436\u0435, \u043a\u043e\u0433\u0434\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/107\/015\/59e\/10701559e0643d85f1de737c0feb4287.gif\" alt=\"\u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430-\u0441\u0447\u0435\u0442\u0447\u0438\u043a.\" title=\"\u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430-\u0441\u0447\u0435\u0442\u0447\u0438\u043a.\" width=\"400\" height=\"220\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/107\/015\/59e\/10701559e0643d85f1de737c0feb4287.gif\"\/><\/p>\n<div><figcaption>\u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430-\u0441\u0447\u0435\u0442\u0447\u0438\u043a.<\/figcaption><\/div>\n<\/figure>\n<h3>\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f<\/h3>\n<p>\u041a\u043d\u043e\u043f\u043a\u0430-\u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0445\u0443\u0434\u043e-\u0431\u0435\u0434\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0444\u0438\u0447\u0443 \u044d\u0442\u043e\u0433\u043e \u0434\u0438\u0437\u0430\u0439\u043d\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u0431\u0435\u0433\u0443\u043d\u043a\u0430 \u0434\u043b\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0434\u0432\u0435 \u043d\u043e\u0432\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 <code>DraggableThumbButton<\/code>. \u041f\u0435\u0440\u0432\u0430\u044f \u0438\u0437 \u043d\u0438\u0445 \u2014 <code>thumbOffsetX: Animatable<\/code>. \u041e\u043d\u0430 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043c \u0441 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0435\u0439 \u043a\u043d\u043e\u043f\u043a\u0438-\u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0435\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c. \u0412\u0442\u043e\u0440\u0430\u044f \u2014 \u044d\u0442\u043e scope \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f <code>thumbOffsetX<\/code> \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438.<\/p>\n<pre><code class=\"kotlin\">val thumbOffsetX = remember { Animatable(0f) } val scope = rememberCoroutineScope()<\/code><\/pre>\n<p>\u0414\u0432\u0435 \u043d\u043e\u0432\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 composable <code>DraggableThumbButton<\/code>.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 Box \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>.offset<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 <code>composable<\/code> \u043f\u043e \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044e \u043a \u0435\u0433\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044e. \u0414\u043b\u044f \u043e\u0441\u0438 x \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>thumbOffsetX<\/code>, \u0430 \u0434\u043b\u044f \u043e\u0441\u0438 y \u043f\u043e\u043a\u0430 \u043e\u0441\u0442\u0430\u0432\u0438\u043c 0.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 5: \u041c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 offset \u0432 DraggableThumbButton.Box<\/h4>\n<pre><code class=\"kotlin\">Box(     contentAlignment = Alignment.Center,     modifier = modifier         \/\/ \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u044e x composable         .offset {             IntOffset(                 thumbOffsetX.value.toInt(),                 0             )         }         ...         ...<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043a\u0430\u043a-\u0442\u043e \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u0436\u0435\u0441\u0442 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f. \u041e\u0434\u0438\u043d \u0438\u0437 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>.pointerInput<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <code>PointerInputScope<\/code>, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>forEachGesture<\/code> \u0438 <code>awaitPointEventScope<\/code>. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043a\u0430\u0441\u0430\u043d\u0438\u044f, \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043d\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442. \u0414\u043e\u0436\u0434\u0430\u0442\u044c\u0441\u044f \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043a\u0430\u0441\u0430\u043d\u0438\u044f \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>awaitFirstDown()<\/code>. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0446\u0438\u043a\u043b do-while \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e\u0441\u0442\u0443\u043f\u0430\u044e\u0449\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043f\u043e\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0443\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043a\u043d\u043e\u043f\u043a\u0443. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438\u0437 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 x, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043a \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0443 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>.snapTo(value)<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0446\u0435\u043b\u0435\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0431\u0435\u0437 \u043a\u0430\u043a\u0438\u0445-\u043b\u0438\u0431\u043e \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0439.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 6. \u041c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 pointerInput \u0432 DraggableThumbButton.Box<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 DraggableThumbButton.Box .pointerInput(Unit) {     forEachGesture {         awaitPointerEventScope {             awaitFirstDown()                          do {                 val event = awaitPointerEvent()                 event.changes.forEach { pointerInputChange ->                     scope.launch {                         val targetValue =                             thumbOffsetX.value + pointerInputChange.positionChange().x                         thumbOffsetX.snapTo(targetValue)                     }                 }             } while (event.changes.any { it.pressed })         }     } }<\/code><\/pre>\n<p>\u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u0432\u043b\u0435\u0432\u043e \u0438 \u0432\u043f\u0440\u0430\u0432\u043e. \u041e\u0434\u043d\u0430\u043a\u043e, \u043a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u043d\u0430\u043c \u0435\u0449\u0435 \u0435\u0441\u0442\u044c \u043d\u0430\u0434 \u0447\u0435\u043c \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u041f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044b \u043a\u043d\u043e\u043f\u043a\u0438, \u043e\u043d \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0430 \u043f\u0440\u0438\u043a\u043e\u0441\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u043a \u043d\u0435\u043c\u0443 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c08\/743\/e95\/c08743e950b474ff218d1f6a2dd36747.gif\" alt=\"\u041f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f.\" title=\"\u041f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f.\" width=\"480\" height=\"138\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c08\/743\/e95\/c08743e950b474ff218d1f6a2dd36747.gif\"\/><\/p>\n<div><figcaption>\u041f\u0435\u0440\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u043d\u0430 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435<\/h3>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u0442\u043e, \u043a\u0430\u043a \u0434\u0430\u043b\u0435\u043a\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a. \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0433\u043e \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u044f\u0445. \u0412 \u0446\u0435\u043b\u044f\u0445 \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043c\u044b \u0437\u0430\u0445\u0430\u0440\u0434\u043a\u043e\u0434\u0438\u043c \u044d\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435, \u043d\u043e \u0432 \u0438\u0434\u0435\u0430\u043b\u0435 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0435\u0433\u043e \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0448\u0438\u0440\u0438\u043d\u044b <code>ButtonContainer<\/code>. \u0421\u0435\u0439\u0447\u0430\u0441 \u0436\u0435 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u043a\u0430\u0436\u0435\u043c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 dp \u0438 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e \u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>Density.toPx()<\/code>, \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 <code>LocalDensity.current<\/code> \u0438\u0437 <code>CompositionLocalProvider<\/code>.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 7: \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0434\u0435\u043b\u043e\u0432 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u0441 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c dp \u0432 px<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0432 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 composable DraggableThumbButton val dragLimitHorizontalPx = 60.dp.dpToPx()  \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0432\u043d\u0438\u0437\u0443 \u0444\u0430\u0439\u043b\u0430 @Composable private fun Dp.dpToPx() = with(LocalDensity.current) { this@dpToPx.toPx() }<\/code><\/pre>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u043c\u0438\u043d\u0438\u043c\u0443\u043c\u0430 \u0438 \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c\u0430 <code>targetValue<\/code>, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u043b\u0441\u044f \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 <code>[-dragLimitHorizontalPx, dragLimitHorizontalPx]<\/code>. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>coerceIn(minimumValue: Float, maximumValue: Float)<\/code> \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0439 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 Kotlin, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0430.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 8: \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0446\u0435\u043b\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 pointerInput val targetValue =     thumbOffsetX.value + pointerInputChange.positionChange().x      val targetValueWithinBounds = targetValue.coerceIn(     -dragLimitHorizontalPx,     dragLimitHorizontalPx )  thumbOffsetX.snapTo(targetValueWithinBounds)<\/code><\/pre>\n<p>\u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u0438\u0445 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0434\u0430\u0434\u0443\u0442 \u043d\u0430\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/126\/c24\/d44\/126c24d44bd4f0318be9084ab3a40f75.gif\" alt=\"\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f.\" title=\"\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f.\" width=\"400\" height=\"184\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/126\/c24\/d44\/126c24d44bd4f0318be9084ab3a40f75.gif\"\/><\/p>\n<div><figcaption>\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0423\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f<\/h3>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u044c \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043a \u0433\u0440\u0430\u043d\u0438\u0446\u0435 \u043a\u043d\u043e\u043f\u043a\u0438, \u043d\u043e \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043a\u0430 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043c \u044d\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0438 \u043b\u0438\u0431\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043c, \u043b\u0438\u0431\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u0430\u043a \u0435\u0441\u043b\u0438 \u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0436\u0438\u043c\u0430\u043b \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043a\u043d\u043e\u043f\u043a\u0438.<\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 <code>DraggableThumbButton<\/code> \u0434\u0432\u0430 \u043d\u043e\u0432\u044b\u0445 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430: \u043e\u0434\u043d\u0443 \u043b\u044f\u043c\u0431\u0434\u0443 \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 \u0435\u0449\u0435 \u043e\u0434\u043d\u0443 \u0434\u043b\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 9: \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u044f\u043c\u0431\u0434\u0430-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0432 DraggableThumbButton<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u0432\u0430 \u043d\u043e\u0432\u044b\u0445 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 @Composable private fun DraggableThumbButton(     value: String,     onClick: () -> Unit,     onValueDecreaseClick: () -> Unit,     onValueIncreaseClick: () -> Unit,     modifier: Modifier = Modifier )  \/\/ \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0435\u043c CounterButton  DraggableThumbButton(     value = value,     onClick = onValueIncreaseClick,     onValueDecreaseClick = onValueDecreaseClick,     onValueIncreaseClick = onValueIncreaseClick,     modifier = Modifier.align(Alignment.Center) )<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u0431\u044b\u043b \u043f\u0435\u0440\u0435\u0434\u0432\u0438\u043d\u0443\u0442 \u0434\u043e \u043f\u0440\u0435\u0434\u0435\u043b\u0430, \u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f: \u0432\u043b\u0435\u0432\u043e \u0438\u043b\u0438 \u0432\u043f\u0440\u0430\u0432\u043e.<\/p>\n<p>\u041a\u0430\u043a \u043d\u0430\u043c \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u043f\u0443\u0441\u0442\u0438\u043b \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043e? \u0423\u0441\u043b\u043e\u0432\u0438\u0435 \u0446\u0438\u043a\u043b\u0430 do-while \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u0442\u0438\u043d\u043d\u044b\u043c. \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043b\u044e\u0431\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u043f\u043e \u0435\u0433\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044e.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 10: \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0435\u043b\u0430 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f<\/h4>\n<pre><code class=\"kotlin\">... } while (event.changes.any { it.pressed })  \/\/ \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u0434\u043e \u043f\u0440\u0435\u0434\u0435\u043b\u0430 if (thumbOffsetX.value.absoluteValue >= dragLimitHorizontalPx) {     if (thumbOffsetX.value.sign > 0) {         onValueIncreaseClick()     } else {         onValueDecreaseClick()     } }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a, \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u043b\u0438\u0437\u043a\u043e \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u043a \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u0435\u043b\u0443 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/765\/0ee\/434\/7650ee434b653f2983768bbf62eb4132.gif\" alt=\"\u0423\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430.\" title=\"\u0423\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430.\" width=\"400\" height=\"193\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/765\/0ee\/434\/7650ee434b653f2983768bbf62eb4132.gif\"\/><\/p>\n<div><figcaption>\u0423\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435 \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430.<\/figcaption><\/div>\n<\/figure>\n<p>\u0421\u0447\u0435\u0442\u0447\u0438\u043a \u043d\u0430\u0447\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u043d\u043e \u043f\u043e\u043a\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u043c, \u0433\u0434\u0435 \u043c\u044b \u0435\u0433\u043e \u043e\u0442\u043f\u0443\u0441\u0442\u0438\u043b\u0438. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u043c.<\/p>\n<h3>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/h3>\n<p>\u041c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b\u0441\u044f \u0432 \u0446\u0435\u043d\u0442\u0440, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0435\u0442 \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c. \u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043c\u044b \u0432\u044b\u044f\u0441\u043d\u0438\u043b\u0438, \u0447\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u0446\u0438\u043a\u043b do-while \u043f\u0440\u0435\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u044d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u043f\u0443\u0441\u0442\u0438\u043b \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0432\u0441\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c <code>thumbOffsetX.value<\/code> \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a 0, \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442.<\/p>\n<p>\u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0432 \u043d\u043e\u0432\u0443\u044e \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u0443 \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0435\u043b\u0430, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 <code>thumbOffsetX<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>animateTo()<\/code>. \u041e\u043d\u0430 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0446\u0435\u043b\u0438 \u0438 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u043c\u044b \u0432\u044b\u0431\u0435\u0440\u0435\u043c \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e <code>spring<\/code>, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u044d\u0444\u0444\u0435\u043a\u0442 \u043e\u0442\u0441\u043a\u043e\u043a\u0430 \u0438\u0437 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0434\u0438\u0437\u0430\u0439\u043d\u0430.<\/p>\n<pre><code class=\"kotlin\">\/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 scope.launch {     if (thumbOffsetX.value != 0f) {         thumbOffsetX.animateTo(             targetValue = 0f,             animationSpec = spring(                 dampingRatio = Spring.DampingRatioMediumBouncy,                 stiffness = StiffnessLow             )         )     } }<\/code><\/pre>\n<p>\u0412\u043e\u0437\u0432\u0440\u0430\u0442 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441 \u043f\u0440\u0443\u0436\u0438\u043d\u044f\u0449\u0435\u0439 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0435\u0439.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e70\/798\/d32\/e70798d32c3eaae7e89489c6860b48d0.gif\" alt=\"\u0410\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f.\" title=\"\u0410\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f.\" width=\"400\" height=\"198\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e70\/798\/d32\/e70798d32c3eaae7e89489c6860b48d0.gif\"\/><\/p>\n<div><figcaption>\u0410\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435 \u043e\u043a\u043e\u043d\u0447\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f.<\/figcaption><\/div>\n<\/figure>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0449\u0435 \u0431\u043e\u043b\u0435\u0435 \u043f\u043b\u0430\u0432\u043d\u044b\u0439 \u044d\u0444\u0444\u0435\u043a\u0442.<\/p>\n<h3>\u0421\u0434\u0432\u0438\u0433 \u0432\u0441\u0435\u0439 \u043a\u043d\u043e\u043f\u043a\u0438<\/h3>\n<p>\u0412 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u0434\u0438\u0437\u0430\u0439\u043d\u0435 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u0432\u0441\u044f \u043a\u043d\u043e\u043f\u043a\u0430 \u0441\u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c \u0436\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0441\u043e\u043a\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u044b\u043d\u0435\u0441\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 <code>thumbOffsetX<\/code> \u0438\u0437 <code>DraggableThumbButton<\/code> \u0432 <code>CounterButton<\/code> \u0438 \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 <code>ButtonContainer<\/code>, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043a\u043d\u043e\u043f\u043a\u0438.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 11: \u041c\u044b \u0432\u044b\u043d\u0435\u0441\u043b\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e thumbOffsetX \u043d\u0430 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432\u044b\u0448\u0435<\/h4>\n<pre><code class=\"kotlin\">@Composable private fun CounterButton(     ... ) {     Box(         contentAlignment = Alignment.Center,         modifier = modifier             .width(200.dp)             .height(80.dp)     ) {         \/\/ \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0435\u043d\u043e \u0438\u0437 DraggableThumbButton         val thumbOffsetX = remember { Animatable(0f) }          ButtonContainer(             onValueDecreaseClick = onValueDecreaseClick,             onValueIncreaseClick = onValueIncreaseClick,             onValueClearClick = onValueClearClick,             modifier = Modifier         )          DraggableThumbButton(             value = value,             \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430             thumbOffsetX = thumbOffsetX,             onClick = onValueIncreaseClick,             onValueDecreaseClick = onValueDecreaseClick,             onValueIncreaseClick = onValueIncreaseClick,             modifier = Modifier.align(Alignment.Center)         )     } }  @Composable private fun DraggableThumbButton(     value: String,     \/\/ \u043d\u043e\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442     thumbOffsetX: Animatable&lt;Float, AnimationVector1D>,     onClick: () -> Unit,     onValueDecreaseClick: () -> Unit,     onValueIncreaseClick: () -> Unit,     modifier: Modifier = Modifier ) {     ... }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u043b\u0438 <code>thumbOffsetX<\/code> \u0432 <code>CounterButton<\/code>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 <code>ButtonContainer<\/code> \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0435 <code>.offset {}<\/code> \u0434\u043b\u044f \u0441\u0434\u0432\u0438\u0433\u0430 \u0432\u0441\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 Box \u043d\u0430\u0448\u0435\u0439 \u043a\u043d\u043e\u043f\u043a\u0438. \u0423\u043c\u043d\u043e\u0436\u0438\u043c \u044d\u0442\u043e \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 0.1f, \u0447\u0442\u043e\u0431\u044b \u043a\u043d\u043e\u043f\u043a\u0430 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u043e\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u043b\u0430\u0441\u044c \u0441\u043e\u0432\u0441\u0435\u043c \u0447\u0443\u0442\u044c-\u0447\u0443\u0442\u044c.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 12: \u0421\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0433\u043e ButtonContainer<\/h4>\n<pre><code class=\"kotlin\">@Composable private fun CounterButton(     ... ) {     Box(         ...     ) {         \/\/ \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0435\u043d\u043e \u0438\u0437 DraggableThumbButton         val thumbOffsetX = remember { Animatable(0f) }          ButtonContainer(             \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430             thumbOffsetX = thumbOffsetX.value,             onValueDecreaseClick = onValueDecreaseClick,             onValueIncreaseClick = onValueIncreaseClick,             onValueClearClick = onValueClearClick,             modifier = Modifier         )          DraggableThumbButton(             ...         )     } }  private const val CONTAINER_OFFSET_FACTOR = 0.1f  @Composable private fun ButtonContainer(     \/\/ \u043d\u043e\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442     thumbOffsetX: Float,     onValueDecreaseClick: () -> Unit,     onValueIncreaseClick: () -> Unit,     onValueClearClick: () -> Unit,     modifier: Modifier = Modifier ) {     Row(         horizontalArrangement = Arrangement.SpaceBetween,         verticalAlignment = Alignment.CenterVertically,         modifier = modifier             \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f             .offset {                 IntOffset(                     (thumbOffsetX * CONTAINER_OFFSET_FACTOR).toInt(),                     0                 )             }             .fillMaxSize()             ...       ){       ...     } }<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>dragLimitHorizontalPx<\/code> \u0432 <code>DraggableThumbButton<\/code> \u0441 60.dp \u043d\u0430 72.dp \u0438 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0435\u0433\u043e \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443. \u041d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u043d\u0435\u0441\u0442\u0438 \u044d\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u043c \u0432\u0441\u044e \u043a\u043d\u043e\u043f\u043a\u0443, \u0438\u0437-\u0437\u0430 \u0447\u0435\u0433\u043e \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u043e\u0440\u043e\u043d.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 13: \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0435\u043b\u0430 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b<\/h4>\n<pre><code class=\"kotlin\">private const val DRAG_LIMIT_HORIZONTAL_DP = 72  @Composable private fun DraggableThumbButton(     ... ) {     \/\/ \u043c\u0435\u043d\u044f\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441 60 \u043d\u0430 72 \u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u043c \u0435\u0433\u043e \u0432 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443     val dragLimitHorizontalPx = DRAG_LIMIT_HORIZONTAL_DP.dp.dpToPx()     ... }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u044d\u0442\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3c3\/378\/e5b\/3c3378e5be92ab041deb2e854147f036.gif\" alt=\"\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043a\u043d\u043e\u043f\u043a\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u043b\u0435\u0434 \u0437\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u043e\u043c.\" title=\"\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043a\u043d\u043e\u043f\u043a\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u043b\u0435\u0434 \u0437\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u043e\u043c.\" width=\"400\" height=\"206\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3c3\/378\/e5b\/3c3378e5be92ab041deb2e854147f036.gif\"\/><\/p>\n<div><figcaption>\u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043a\u043d\u043e\u043f\u043a\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u043b\u0435\u0434 \u0437\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u043e\u043c.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0418\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0435\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043b\u0438\u043a\u043e\u0432<\/h3>\n<p>\u0412 composable \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043c\u0430\u043a\u0435\u0442\u043e\u043c \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043d\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>.clickable<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b \u043d\u0430\u043c \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u0438\u043a\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u043b\u044e\u0431\u043e\u0435 \u043f\u0440\u0438\u043a\u043e\u0441\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u043a \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0443 \u0432\u0441\u0435 \u0435\u0449\u0435 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043a\u043b\u0438\u043a\u043e\u043c.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/457\/78f\/f98\/45778ff9855d938302e52a6b6003e134.gif\" alt=\"\u041d\u0435\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043a\u043b\u0438\u043a\u043e\u0432 \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0442 \u043a \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438.\" title=\"\u041d\u0435\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043a\u043b\u0438\u043a\u043e\u0432 \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0442 \u043a \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438.\" width=\"400\" height=\"194\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/457\/78f\/f98\/45778ff9855d938302e52a6b6003e134.gif\"\/><\/p>\n<div><figcaption>\u041d\u0435\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043a\u043b\u0438\u043a\u043e\u0432 \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0442 \u043a \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438.<\/figcaption><\/div>\n<\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443, \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u044e\u0449\u0443\u044e \u043a\u043b\u0438\u043a\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043d\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043f\u043e\u0440\u043e\u0433 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0435\u0439.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 14: \u0418\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 .clickable {} \u0432 DraggableThumbButton<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0440\u044f\u0434\u043e\u043c \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438 private const val START_DRAG_THRESHOLD_DP = 2  \/\/ \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 composable DraggableThumbButton  val startDragThreshold = START_DRAG_THRESHOLD_DP.dp.dpToPx()  \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 clickable \u0432 DraggableThumbButton .clickable {     \/\/ \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043a\u043b\u0438\u043a\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043d\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f     if (thumbOffsetX.value.absoluteValue &lt;= startDragThreshold) {         onClick()     } }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430, \u0438 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043a\u043b\u0438\u043a\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0438:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a80\/772\/655\/a80772655a5df450740e2b337ef526b9.gif\" alt=\"\u041b\u0435\u0433\u043a\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043d\u0435\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u043c\u0443 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.\" title=\"\u041b\u0435\u0433\u043a\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043d\u0435\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u043c\u0443 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.\" width=\"400\" height=\"188\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a80\/772\/655\/a80772655a5df450740e2b337ef526b9.gif\"\/><\/p>\n<div><figcaption>\u041b\u0435\u0433\u043a\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043a \u043d\u0435\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u043c\u0443 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u043f\u0440\u043e\u0442\u0438\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044e<\/h3>\n<p>\u0422\u0435\u043a\u0443\u0449\u0430\u044f \u043b\u043e\u0433\u0438\u043a\u0430 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043d\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043f\u043e\u0441\u0442\u043d\u043e. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0433\u043b\u0430\u0434\u0438\u0442\u044c \u044d\u0442\u043e \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u0435, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043e\u043f\u0440\u043e\u0442\u0438\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0435\u0440\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u043a \u0442\u0435\u043a\u0443\u0449\u0435\u043c\u0443 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044e \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430, \u0438\u0437-\u0437\u0430 \u0447\u0435\u0433\u043e \u043e\u043d \u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043b\u0438\u043d\u0435\u0439\u043d\u043e. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u043c\u043d\u043e\u0436\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442, \u043c\u0435\u043d\u044c\u0448\u0438\u0439 1, \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0447\u0435\u0433\u043e \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u044d\u0444\u0444\u0435\u043a\u0442 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0441\u043e\u043f\u0440\u043e\u0442\u0438\u0432\u043b\u0435\u043d\u0438\u044f. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0435\u043c \u0431\u043b\u0438\u0436\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043a \u043a\u0440\u0430\u044e, \u0442\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u0443\u0441\u0438\u043b\u0438\u0439 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u044c \u0435\u0433\u043e \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 15: \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u043e\u0433\u0438\u043a\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0432\u043d\u0443\u0442\u0440\u0438 DraggableThumbButton.Modifier.pointerInput scope.launch {     \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u0441\u043e\u043f\u0440\u043e\u0442\u0438\u0432\u043b\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u0447\u0435\u043c \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a     \/\/ \u0431\u043b\u0438\u0436\u0435 \u043a \u0433\u0440\u0430\u043d\u0438\u0446\u0435, \u0442\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u0443\u0441\u0438\u043b\u0438\u0439 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0434\u043b\u044f \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f     val dragFactor =         1 - (thumbOffsetX.value \/ dragLimitHorizontalPx).absoluteValue     val delta =         pointerInputChange.positionChange().x * dragFactor          val targetValue = thumbOffsetX.value + delta     val targetValueWithinBounds =         targetValue.coerceIn(             -dragLimitHorizontalPx,             dragLimitHorizontalPx         )          thumbOffsetX.snapTo(targetValueWithinBounds) }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0434\u043e\u0441\u0442\u0438\u0447\u044c \u043a\u0440\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u0442\u0440\u0443\u0434\u043d\u0435\u0435, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443, \u0433\u0434\u0435 \u043c\u044b \u0440\u0435\u0448\u0430\u0435\u043c, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043b\u0438 \u0431\u043b\u0438\u0437\u043a\u043e \u043a \u043d\u0435\u043c\u0443 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a, \u0447\u0442\u043e\u0431\u044b \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u0438\u043b\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u043c\u043d\u043e\u0436\u0438\u0442\u044c <code>dragLimitHorizontalPx<\/code> \u043d\u0430 \u0442\u043e\u0442 \u0436\u0435 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0437\u043e\u0440.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 16: \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0437\u0430\u0437\u043e\u0440\u0430 \u0432 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0438 \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u043e\u0432<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0432 \u0444\u0430\u0439\u043b\u0435 \u0441 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438 private const val DRAG_LIMIT_HORIZONTAL_THRESHOLD_FACTOR = 0.9f  \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0435 DraggableThumbButton.pointerInput if (thumbOffsetX.value.absoluteValue >= (dragLimitHorizontalPx * DRAG_LIMIT_HORIZONTAL_THRESHOLD_FACTOR)) {     ... }<\/code><\/pre>\n<p>\u0421 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0440\u0430\u0441\u0447\u0435\u0442\u043e\u043c \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u0443\u0441\u0438\u043b\u0438\u0439, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u044c \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u0434\u043e \u0441\u0430\u043c\u043e\u0439 \u0433\u0440\u0430\u043d\u0438\u0446\u044b:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/966\/856\/f1a\/966856f1a0c415d7211cc847fee5a43e.gif\" alt=\"\u041f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u043a \u0433\u0440\u0430\u043d\u0438\u0446\u0435.\" title=\"\u041f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u043a \u0433\u0440\u0430\u043d\u0438\u0446\u0435.\" width=\"400\" height=\"189\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/966\/856\/f1a\/966856f1a0c415d7211cc847fee5a43e.gif\"\/><\/p>\n<div><figcaption>\u041f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u043a \u0433\u0440\u0430\u043d\u0438\u0446\u0435.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0410\u043a\u0446\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u043a\u043e\u043d\u043e\u043a \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0418\u043a\u043e\u043d\u043a\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0435\u0434\u0432\u0430 \u0437\u0430\u043c\u0435\u0442\u043d\u044b\u043c\u0438 \u0438 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u044f\u0440\u0447\u0435 \u043f\u043e \u043c\u0435\u0440\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043a \u043d\u0438\u043c \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0432 <code>ButtonContainer<\/code> \u043d\u043e\u0432\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0443\u044e \u0442\u043e\u0447\u043a\u0443, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u043a\u043e\u043d\u043a\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u0442\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u0438\u0434\u0438\u043c\u043e\u0439. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u0438 \u043d\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u043d\u0442 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u043b\u044c\u0444\u0430-\u043a\u0430\u043d\u0430\u043b\u0430 tintColor. \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0434\u043b\u044f \u0430\u043b\u044c\u0444\u044b \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0432 30%. \u041b\u043e\u0433\u0438\u043a\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438 \u0441\u0431\u0440\u043e\u0441\u0430 \u043c\u044b \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f \u043f\u043e\u0437\u0436\u0435.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 17: \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u044f\u0440\u043a\u043e\u0441\u0442\u0438 \u0438\u043a\u043e\u043d\u043a\u0438<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c private const val DRAG_HORIZONTAL_ICON_HIGHLIGHT_LIMIT_DP = 36  \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0432\u0435\u0440\u0445\u043d\u044e\u044e \u0447\u0430\u0441\u0442\u044c ButtonContainer \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c, \u0432 \u043a\u0430\u043a\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438\u043a\u043e\u043d\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u0438\u0434\u0438\u043c\u043e\u0439 val horizontalHighlightLimitPx = DRAG_HORIZONTAL_ICON_HIGHLIGHT_LIMIT_DP.dp.dpToPx()  \/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f IconControlButton(     icon = Icons.Outlined.Remove,     contentDescription = \"Decrease count\",     onClick = onValueDecreaseClick,     \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0440\u0430\u0441\u0447\u0435\u0442 \u0430\u043b\u044c\u0444\u0430-\u043a\u0430\u043d\u0430\u043b\u0430     tintColor = Color.White.copy(         alpha = if (thumbOffsetX &lt; 0) {             (thumbOffsetX.absoluteValue \/ horizontalHighlightLimitPx).coerceIn(                 ICON_BUTTON_ALPHA_INITIAL,                 1f             )         } else {             ICON_BUTTON_ALPHA_INITIAL         }     ) )  ...  \/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f IconControlButton(     icon = Icons.Outlined.Add,     contentDescription = \"Increase count\",     onClick = onValueIncreaseClick,     tintColor = Color.White.copy(         alpha = if (thumbOffsetX > 0) {             (thumbOffsetX.absoluteValue \/ horizontalHighlightLimitPx).coerceIn(                 ICON_BUTTON_ALPHA_INITIAL,                 1f             )         } else {             ICON_BUTTON_ALPHA_INITIAL         }     ) )<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0438\u043a\u043e\u043d\u043a\u0438 \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u0437\u0430\u043c\u0435\u0442\u043d\u044b\u043c\u0438, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u0431\u043b\u0438\u0436\u0435 \u043a \u043a\u0440\u0430\u044e:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f5b\/746\/819\/f5b746819160795f989c2bf213a25443.gif\" alt=\"\u041f\u043e\u0434\u0441\u0432\u0435\u0442\u043a\u0430 \u0438\u043a\u043e\u043d\u043e\u043a \u043f\u043e \u043c\u0435\u0440\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430.\" title=\"\u041f\u043e\u0434\u0441\u0432\u0435\u0442\u043a\u0430 \u0438\u043a\u043e\u043d\u043e\u043a \u043f\u043e \u043c\u0435\u0440\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430.\" width=\"400\" height=\"188\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f5b\/746\/819\/f5b746819160795f989c2bf213a25443.gif\"\/><\/p>\n<div><figcaption>\u041f\u043e\u0434\u0441\u0432\u0435\u0442\u043a\u0430 \u0438\u043a\u043e\u043d\u043e\u043a \u043f\u043e \u043c\u0435\u0440\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0410\u043a\u0446\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0444\u043e\u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0438<\/h3>\n<p>\u041f\u043e\u0434\u043e\u0431\u043d\u043e \u0438\u043a\u043e\u043d\u043a\u0430\u043c, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0444\u043e\u043d\u0430 <code>ButtonContainer<\/code>, \u0447\u0442\u043e\u0431\u044b \u0435\u0433\u043e \u0446\u0432\u0435\u0442 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0441\u044f \u0442\u0435\u043c\u043d\u0435\u0435 \u043f\u043e \u043c\u0435\u0440\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u043a \u043a\u0440\u0430\u044e \u043a\u043d\u043e\u043f\u043a\u0438. \u041c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0430\u043b\u044c\u0444\u0430-\u043a\u0430\u043d\u0430\u043b\u0430 \u0440\u0430\u0432\u043d\u044b\u043c \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e \u043f\u043b\u044e\u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043c\u043d\u043e\u0436\u0438\u0442\u0435\u043b\u044c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u0438\u044f.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 18: \u0412\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0430\u043b\u044c\u0444\u0430-\u043a\u0430\u043d\u0430\u043b\u0430 \u0446\u0432\u0435\u0442\u0430 \u0444\u043e\u043d\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0434\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 ButtonContainer.background .background(     Color.Black.copy(         alpha = CONTAINER_BACKGROUND_ALPHA_INITIAL +                 ((thumbOffsetX.absoluteValue \/ horizontalHighlightLimitPx) \/ 10f)     ) )<\/code><\/pre>\n<p>\u0418 \u0432\u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u044d\u0442\u043e\u0433\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u041d\u0435 \u0431\u043e\u0439\u0442\u0435\u0441\u044c \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u0430\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u043b\u0443\u0447\u0448\u0435\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/10f\/a14\/972\/10fa14972f86a1e3bc3ce03b5ea2a49b.gif\" alt=\"\u041f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u0431\u043b\u0438\u0436\u0435 \u043a \u0433\u0440\u0430\u043d\u0438\u0446\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u0437\u0430\u0442\u0435\u043c\u043d\u044f\u0435\u0442 \u0444\u043e\u043d.\" title=\"\u041f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u0431\u043b\u0438\u0436\u0435 \u043a \u0433\u0440\u0430\u043d\u0438\u0446\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u0437\u0430\u0442\u0435\u043c\u043d\u044f\u0435\u0442 \u0444\u043e\u043d.\" width=\"400\" height=\"198\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/10f\/a14\/972\/10fa14972f86a1e3bc3ce03b5ea2a49b.gif\"\/><\/p>\n<div><figcaption>\u041f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u0431\u043b\u0438\u0436\u0435 \u043a \u0433\u0440\u0430\u043d\u0438\u0446\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u0437\u0430\u0442\u0435\u043c\u043d\u044f\u0435\u0442 \u0444\u043e\u043d.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f<\/h3>\n<p>\u041c\u044b \u0434\u043e\u0431\u0438\u043b\u0438\u0441\u044c \u0442\u043e\u0433\u043e, \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a, \u043a\u0430\u043a \u043c\u044b \u0445\u043e\u0442\u0435\u043b\u0438. \u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>thumbOffsetY: Animatable<\/code> \u0432 <code>CounterButton<\/code>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435\u043c y \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c\u0443 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0443 <code>thumbOffsetX<\/code>.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 19: \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 thumbOffsetY \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 DraggableThumbButton<\/h4>\n<pre><code class=\"kotlin\">\/\/ 1. \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c CounterButton val thumbOffsetY = remember { Animatable(0f) }  DraggableThumbButton(     value = value,     thumbOffsetX = thumbOffsetX,     thumbOffsetY = thumbOffsetY,     onClick = onValueIncreaseClick,     onValueDecreaseClick = onValueDecreaseClick,     onValueIncreaseClick = onValueIncreaseClick,     onValueReset = onValueClearClick,     modifier = Modifier.align(Alignment.Center) )  \/\/ 2. \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c DraggableThumbButton @Composable private fun DraggableThumbButton(     value: String,     thumbOffsetX: Animatable&lt;Float, AnimationVector1D>,     thumbOffsetY: Animatable&lt;Float, AnimationVector1D>,     onClick: () -> Unit,     onValueDecreaseClick: () -> Unit,     onValueIncreaseClick: () -> Unit,     onValueReset: () -> Unit,     modifier: Modifier = Modifier ) {   ... }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u043c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>.offset<\/code> \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u044c \u0437\u0430 <code>thumbOffsetY<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u043c\u043e\u0433\u043b\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438. \u0418 \u0435\u0449\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>.clickable<\/code>, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043d\u0435\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043b\u0438\u043a\u043e\u0432 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 20: \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0432 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b .offset \u0438 .clickable \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u043e\u0441\u0438 y<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 composable \u043f\u043e x \u0438 y .offset {     IntOffset(         thumbOffsetX.value.toInt(),         thumbOffsetY.value.toInt(),     ) }  \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 clickable, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0442\u0430\u043a\u0436\u0435 \u0440\u0435\u0433\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043b \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 .clickable {     \/\/ \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043a\u043b\u0438\u043a\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043d\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f     if (thumbOffsetX.value.absoluteValue &lt;= startDragThreshold &amp;&amp;         thumbOffsetY.value.absoluteValue &lt;= startDragThreshold     ) {         onClick()     } }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043d\u043e\u0432\u043e\u0435 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 <code>DragDirection<\/code> \u0438 \u043d\u043e\u0432\u043e\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>dragDirection: DragDirection<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u043e\u0441\u0438, \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0430\u044f \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438 \u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 21: \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f DragDirection<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u0432 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 DraggableThumbButton val dragDirection = remember {     mutableStateOf(DragDirection.NONE) }  \/\/ \u0432 \u043d\u0438\u0436\u043d\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0444\u0430\u0439\u043b\u0430 private enum class DragDirection {     NONE, HORIZONTAL, VERTICAL }<\/code><\/pre>\n<p>\u041d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>dragLimitVerticalPx<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u0430\u043b\u0435\u043a\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 22: \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0432 DraggableThumbButton<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0444\u0430\u0439\u043b \u0441 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438 private const val DRAG_LIMIT_VERTICAL_DP = 64  \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 DraggableThumbButton val dragLimitVerticalPx = DRAG_LIMIT_VERTICAL_DP.dp.dpToPx()<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 <code>.pointerInput<\/code>.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0448\u0430\u0433 \u2014 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u0432 \u043a\u0430\u043a\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435: \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u0438\u043b\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u043c. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e, \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0432, \u0447\u0442\u043e \u0438\u0437 <code>pointerInputChange.positionChange().x<\/code> \u0438 <code>pointerInputChange.positionChange().y<\/code> \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u043e\u0441\u044c. \u041d\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u044f x \u043c\u043e\u0436\u0435\u0442 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c\u0441\u044f (\u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442), \u043d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0440\u043e\u0433 \u0434\u043b\u044f \u044d\u0442\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u0447\u0442\u043e\u0431\u044b \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e\u0441\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0433\u043e \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043b\u0438\u0431\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>thumbOffsetX<\/code>, \u043b\u0438\u0431\u043e <code>thumbOffsetY<\/code> \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430.<\/p>\n<p>\u041d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>dragDirection<\/code>, \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u044e\u0449\u0443\u044e \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u043e\u0441\u0438 \u0437\u0430 \u0440\u0430\u0437.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 23: \u00a0\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043e\u0441\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f<\/h4>\n<pre><code class=\"kotlin\">.pointerInput(Unit) {     forEachGesture {         awaitPointerEventScope {             awaitFirstDown()                          \/\/ \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f             dragDirection.value = DragDirection.NONE                        do {                 val event = awaitPointerEvent()                 event.changes.forEach { pointerInputChange ->                     scope.launch {                         if ((dragDirection.value == DragDirection.NONE &amp;&amp;                                     pointerInputChange.positionChange().x.absoluteValue >= startDragThreshold) ||                             dragDirection.value == DragDirection.HORIZONTAL                         ) {                             \/\/ \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435, \u043f\u043e\u043a\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0443\u0449\u0435\u043d                             dragDirection.value = DragDirection.HORIZONTAL                                                        \/\/ \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u0441\u043e\u043f\u0440\u043e\u0442\u0438\u0432\u043b\u0435\u043d\u0438\u044f,\u00a0 \u0447\u0442\u043e\u0431\u044b \u0447\u0435\u043c \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a                             \/\/ \u0431\u043b\u0438\u0436\u0435 \u043a \u0433\u0440\u0430\u043d\u0438\u0446\u0435, \u0442\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u0443\u0441\u0438\u043b\u0438\u0439 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0434\u043b\u044f \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f                             val dragFactor =                                 1 - (thumbOffsetX.value \/ dragLimitHorizontalPx).absoluteValue                             val delta =                                 pointerInputChange.positionChange().x * dragFactor                                                          val targetValue = thumbOffsetX.value + delta                             val targetValueWithinBounds =                                 targetValue.coerceIn(                                     -dragLimitHorizontalPx,                                     dragLimitHorizontalPx                                 )                                                          thumbOffsetX.snapTo(targetValueWithinBounds)                         } else if (                             (dragDirection.value != DragDirection.HORIZONTAL &amp;&amp;                                     pointerInputChange.positionChange().y >= startDragThreshold)                         ) {                             \/\/ \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435, \u043f\u043e\u043a\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0443\u0449\u0435\u043d                             dragDirection.value = DragDirection.VERTICAL                                                          val dragFactor =                                 1 - (thumbOffsetY.value \/ dragLimitVerticalPx).absoluteValue                             val delta =                                 pointerInputChange.positionChange().y * dragFactor                                                          val targetValue = thumbOffsetY.value + delta                             val targetValueWithinBounds =                                 targetValue.coerceIn(                                     -dragLimitVerticalPx,                                     dragLimitVerticalPx                                 )                                                         thumbOffsetY.snapTo(targetValueWithinBounds)                         }                     }                 }             } while (event.changes.any { it.pressed })         }                  ...     } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u043e\u0431\u043e\u0438\u0445 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0434\u043b\u044f \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u0434\u043e \u043f\u0440\u0435\u0434\u0435\u043b\u0430. \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>thumbOffsetY<\/code> \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>dragLimitVerticalPx<\/code> (\u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0437\u0430\u0437\u043e\u0440\u043e\u043c), \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043a\u043e\u043b\u043b\u0431\u044d\u043a <code>onValueReset()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u0441\u0447\u0435\u0442\u0447\u0438\u043a.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 24: \u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u0434\u043e \u043f\u0440\u0435\u0434\u0435\u043b\u0430<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0441 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438 private const val DRAG_LIMIT_VERTICAL_THRESHOLD_FACTOR = 0.9f  \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0435 DraggableThumbButton.pointerInput  .pointerInput(Unit) {     forEachGesture {         awaitPointerEventScope {            ...         }                  \/\/ \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435 \u0434\u043e \u043f\u0440\u0435\u0434\u0435\u043b\u0430         if (thumbOffsetX.value.absoluteValue >= (dragLimitHorizontalPx * DRAG_LIMIT_HORIZONTAL_THRESHOLD_FACTOR)) {             if (thumbOffsetX.value.sign > 0) {                 onValueIncreaseClick()             } else {                 onValueDecreaseClick()             }         } else if (thumbOffsetY.value.absoluteValue >= (dragLimitVerticalPx * DRAG_LIMIT_VERTICAL_THRESHOLD_FACTOR)) {             onValueReset()         }    } }<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f, \u0430 \u0437\u0430\u0442\u0435\u043c \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u043b\u0438\u0431\u043e <code>thumbOffsetX<\/code> \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f, \u043b\u0438\u0431\u043e <code>thumbOffsetY<\/code> \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u0432\u0435\u0440\u043d\u0443\u043b\u0441\u044f \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 25: \u0412\u043e\u0437\u0432\u0440\u0430\u0442 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0435 DraggableThumbButton.pointerInput scope.launch {     if (dragDirection.value == DragDirection.HORIZONTAL &amp;&amp; thumbOffsetX.value != 0f) {         thumbOffsetX.animateTo(             targetValue = 0f,             animationSpec = spring(                 dampingRatio = Spring.DampingRatioMediumBouncy,                 stiffness = StiffnessLow             )         )     } else if (dragDirection.value == DragDirection.VERTICAL &amp;&amp; thumbOffsetY.value != 0f) {         thumbOffsetY.animateTo(             targetValue = 0f,             animationSpec = spring(                 dampingRatio = Spring.DampingRatioMediumBouncy,                 stiffness = StiffnessLow             )         )     } }<\/code><\/pre>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0432 \u043d\u043e\u043b\u044c:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/944\/b7c\/75a\/944b7c75ad642618a927e971275744ae.gif\" alt=\"\u0420\u0430\u0431\u043e\u0447\u0435\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435.\" title=\"\u0420\u0430\u0431\u043e\u0447\u0435\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435.\" width=\"400\" height=\"400\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/944\/b7c\/75a\/944b7c75ad642618a927e971275744ae.gif\"\/><\/p>\n<div><figcaption>\u0420\u0430\u0431\u043e\u0447\u0435\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435.<\/figcaption><\/div>\n<\/figure>\n<h3>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u043a\u043e\u043d\u043a\u0438 \u0441\u0431\u0440\u043e\u0441\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0435\u0449\u0435 \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0438\u043a\u043e\u043d\u043a\u0443 \u0441\u0431\u0440\u043e\u0441\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430. \u041c\u044b \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0442\u043e\u0447\u043a\u0438, \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u043e\u044f\u0432\u0438\u0442\u044c\u0441\u044f \u0438\u043a\u043e\u043d\u043a\u0430, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0435\u0435 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f. \u0418 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 <code>ClearButtonVisible<\/code> \u0432 <code>ButtonContainer<\/code>.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 26: \u0414\u0435\u043b\u0430\u0435\u043c \u0438\u043a\u043e\u043d\u043a\u0443 \u0441\u0431\u0440\u043e\u0441\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u0438\u0434\u0438\u043c\u043e\u0439<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438 private const val DRAG_CLEAR_ICON_REVEAL_DP = 2  \/\/ \u0432 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 CounterButton val verticalDragButtonRevealPx = DRAG_CLEAR_ICON_REVEAL_DP.dp.dpToPx()  ButtonContainer(     offsetX = thumbOffsetX.value,     onValueDecreaseClick = onValueDecreaseClick,     onValueIncreaseClick = onValueIncreaseClick,     onValueClearClick = onValueClearClick,     clearButtonVisible = thumbOffsetY.value >= verticalDragButtonRevealPx,     modifier = Modifier )<\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0ec\/7c2\/01f\/0ec7c201fc04bfc3f6671855612e53f9.gif\" alt=\"\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u043a\u043e\u043d\u043a\u0438 \u0441\u0431\u0440\u043e\u0441\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.\" title=\"\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u043a\u043e\u043d\u043a\u0438 \u0441\u0431\u0440\u043e\u0441\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.\" width=\"400\" height=\"307\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0ec\/7c2\/01f\/0ec7c201fc04bfc3f6671855612e53f9.gif\"\/><\/p>\n<div><figcaption>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u043a\u043e\u043d\u043a\u0438 \u0441\u0431\u0440\u043e\u0441\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/figcaption><\/div>\n<\/figure>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c \u0438\u043a\u043e\u043d\u043a\u0430 \u0441\u0431\u0440\u043e\u0441\u0430 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0432\u0438\u0434\u0438\u043c\u043e\u0439 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438 \u0438 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0441\u043a\u0440\u044b\u0442\u043e\u0439 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438 \u043f\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u0443 \u0438\u043a\u043e\u043d\u043a\u0443 \u0431\u043e\u043b\u0435\u0435 \u044f\u0440\u043a\u043e\u0439 \u043f\u043e \u043c\u0435\u0440\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>thumbOffsetY<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 <code>ButtonContainer<\/code>, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043d\u043e\u0432\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>verticalHightlightLimitPx<\/code> \u0438 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 <code>thumbOffsetY<\/code>, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>tintColor<\/code> \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 27: \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 thumbOffsetY \u0432 ButtonContainer, \u0447\u0442\u043e\u0431\u044b \u043c\u0435\u043d\u044f\u0442\u044c \u044f\u0440\u043a\u043e\u0441\u0442\u044c \u0438\u043a\u043e\u043d\u043a\u0438 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0441 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438 private const val DRAG_VERTICAL_ICON_HIGHLIGHT_LIMIT_DP = 60  \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c ButtonContainer @Composable private fun ButtonContainer(     thumbOffsetX: Float,     \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442     thumbOffsetY: Float,     onValueDecreaseClick: () -> Unit,     onValueIncreaseClick: () -> Unit,     onValueClearClick: () -> Unit,     modifier: Modifier = Modifier,     clearButtonVisible: Boolean = false, ) {     \/\/ \u0432 \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438\u043a\u043e\u043d\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u044f\u0440\u043a\u043e\u0441\u0442\u0438     val verticalHighlightLimitPx = DRAG_VERTICAL_ICON_HIGHLIGHT_LIMIT_DP.dp.dpToPx()      Row(         ...     ) {         ...                  \/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0441\u0431\u0440\u043e\u0441\u0430         if (clearButtonVisible) {             IconControlButton(                 icon = Icons.Outlined.Clear,                 contentDescription = \"Clear count\",                 onClick = onValueClearClick,                 tintColor = Color.White.copy(                     alpha = (thumbOffsetY.absoluteValue \/ verticalHighlightLimitPx).coerceIn(                         ICON_BUTTON_ALPHA_INITIAL,                         1f                     )                 )             )         }          ...     } }  \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c CounterButton, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u043b thumbOffsetY \u0432 ButtonContainer ButtonContainer(     thumbOffsetX = thumbOffsetX.value,     thumbOffsetY = thumbOffsetY.value,     onValueDecreaseClick = onValueDecreaseClick,     onValueIncreaseClick = onValueIncreaseClick,     onValueClearClick = onValueClearClick,     clearButtonVisible = thumbOffsetY.value >= verticalDragButtonRevealPx,     modifier = Modifier )<\/code><\/pre>\n<p>\u0418\u043a\u043e\u043d\u043a\u0430 \u0441\u0431\u0440\u043e\u0441\u0430 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u044f\u0440\u043a\u043e\u0439, \u043f\u043e \u043c\u0435\u0440\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u043a \u043f\u0440\u0435\u0434\u0435\u043b\u0443.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cdb\/77a\/e3d\/cdb77ae3de3b74f10b23c5e8a9f5fcea.gif\" alt=\"\u0422\u0435\u043f\u0435\u0440\u044c \u0438\u043a\u043e\u043d\u043a\u0430 \u0441\u0431\u0440\u043e\u0441\u0430 \u0431\u043e\u043b\u0435\u0435 \u0437\u0430\u043c\u0435\u0442\u043d\u0430.\" title=\"\u0422\u0435\u043f\u0435\u0440\u044c \u0438\u043a\u043e\u043d\u043a\u0430 \u0441\u0431\u0440\u043e\u0441\u0430 \u0431\u043e\u043b\u0435\u0435 \u0437\u0430\u043c\u0435\u0442\u043d\u0430.\" width=\"400\" height=\"368\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/cdb\/77a\/e3d\/cdb77ae3de3b74f10b23c5e8a9f5fcea.gif\"\/><\/p>\n<div><figcaption>\u0422\u0435\u043f\u0435\u0440\u044c \u0438\u043a\u043e\u043d\u043a\u0430 \u0441\u0431\u0440\u043e\u0441\u0430 \u0431\u043e\u043b\u0435\u0435 \u0437\u0430\u043c\u0435\u0442\u043d\u0430.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0421\u0434\u0432\u0438\u0433 \u0432\u0441\u0435\u0439 \u043a\u043d\u043e\u043f\u043a\u0438 \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438<\/h3>\n<p>\u041f\u043e\u0434\u043e\u0431\u043d\u043e \u0442\u043e\u043c\u0443, \u043a\u0430\u043a \u0432\u0435\u0441\u044c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u043a\u043d\u043e\u043f\u043a\u0438 \u0441\u043b\u0435\u0433\u043a\u0430 \u0441\u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f, \u043e\u043d \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>.offset<\/code> \u0432 <code>ButtonContainer<\/code> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>thumbOffsetY<\/code>, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u044f \u043a\u043d\u043e\u043f\u043a\u0430 \u0434\u0432\u0438\u0433\u0430\u043b\u0430\u0441\u044c \u0432\u0441\u043b\u0435\u0434 \u0437\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u043e\u043c \u043f\u0440\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438. \u0410 \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>.background<\/code>, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0442\u0435\u043c\u043d\u044f\u0442\u044c \u0444\u043e\u043d \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044e. \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u043c \u0437\u0434\u0435\u0441\u044c \u043d\u0430\u0448\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u044b \u0434\u043b\u044f \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b <code>CONTAINER_BACKGROUND_ALPHA_MAX<\/code>.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 28: \u041f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438 \u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0430\u043b\u044c\u0444\u0430-\u043a\u0430\u043d\u0430\u043b\u0430 \u0446\u0432\u0435\u0442\u0430 \u0444\u043e\u043d\u0430<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0441 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438 private const val CONTAINER_BACKGROUND_ALPHA_MAX = 0.7f  \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c ButtonContainer .offset {     IntOffset(         (thumbOffsetX * CONTAINER_OFFSET_FACTOR).toInt(),         (thumbOffsetY * CONTAINER_OFFSET_FACTOR).toInt(),     ) } ... .background(     Color.Black.copy(         alpha = if (thumbOffsetX.absoluteValue > 0.0f) {             \/\/ \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u0430\u044f             (CONTAINER_BACKGROUND_ALPHA_INITIAL + ((thumbOffsetX.absoluteValue \/ horizontalHighlightLimitPx) \/ 20f))                 .coerceAtMost(CONTAINER_BACKGROUND_ALPHA_MAX)         } else if (thumbOffsetY.absoluteValue > 0.0f) {             \/\/ \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u0430\u044f             (CONTAINER_BACKGROUND_ALPHA_INITIAL + ((thumbOffsetY.absoluteValue \/ verticalHighlightLimitPx) \/ 10f))                 .coerceAtMost(CONTAINER_BACKGROUND_ALPHA_MAX)         } else {             CONTAINER_BACKGROUND_ALPHA_INITIAL         }     ) )<\/code><\/pre>\n<p>\u0412\u0441\u044f \u043a\u043d\u043e\u043f\u043a\u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e \u0432\u0441\u043b\u0435\u0434 \u0437\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u043e\u043c.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bd8\/b0a\/0eb\/bd8b0a0eb93d1d55944871bafa7cc9b9.gif\" alt=\"\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438.\" title=\"\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438.\" width=\"400\" height=\"291\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bd8\/b0a\/0eb\/bd8b0a0eb93d1d55944871bafa7cc9b9.gif\"\/><\/p>\n<div><figcaption>\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0421\u043a\u0440\u044b\u0442\u0438\u0435 \u043a\u043d\u043e\u043f\u043e\u043a \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438<\/h3>\n<p>\u041d\u0430\u043c \u043d\u0435 \u043c\u0435\u0448\u0430\u043b\u043e \u0431\u044b \u0441\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0440\u0430\u0441\u0447\u0435\u0442 \u0446\u0432\u0435\u0442\u0430 \u0434\u043b\u044f \u044d\u0442\u0438\u0445 \u0434\u0432\u0443\u0445 \u043a\u043d\u043e\u043f\u043e\u043a, \u0447\u0442\u043e\u0431\u044b \u0434\u0435\u043b\u0430\u0442\u044c \u0438\u0445 \u043d\u0435\u0432\u0438\u0434\u0438\u043c\u044b\u043c\u0438, \u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 29: \u0421\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f IconControlButton(     icon = Icons.Outlined.Remove,     contentDescription = \"Decrease count\",     onClick = onValueDecreaseClick,     tintColor = Color.White.copy(         alpha = if (clearButtonVisible) {             0.0f         } else if (thumbOffsetX &lt; 0) {             (thumbOffsetX.absoluteValue \/ horizontalHighlightLimitPx).coerceIn(                 ICON_BUTTON_ALPHA_INITIAL,                 1f             )         } else {             ICON_BUTTON_ALPHA_INITIAL         }     ) )  \/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f IconControlButton(     icon = Icons.Outlined.Add,     contentDescription = \"Increase count\",     onClick = onValueIncreaseClick,     tintColor = Color.White.copy(         alpha = if (clearButtonVisible) {             0.0f         } else if (thumbOffsetX > 0) {             (thumbOffsetX.absoluteValue \/ horizontalHighlightLimitPx).coerceIn(                 ICON_BUTTON_ALPHA_INITIAL,                 1f             )         } else {             ICON_BUTTON_ALPHA_INITIAL         }     ) )<\/code><\/pre>\n<p>\u0421 \u044d\u0442\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u0438\u043a\u043e\u043d\u043a\u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u043d\u0435\u0432\u0438\u0434\u0438\u043c\u044b\u043c\u0438 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/86a\/0e1\/37a\/86a0e137ab3cf3a9c3b9f97c5ca9dead.gif\" alt=\"\u041a\u043d\u043e\u043f\u043a\u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u043f\u0440\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438. \" title=\"\u041a\u043d\u043e\u043f\u043a\u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u043f\u0440\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438. \" width=\"400\" height=\"320\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/86a\/0e1\/37a\/86a0e137ab3cf3a9c3b9f97c5ca9dead.gif\"\/><\/p>\n<div><figcaption>\u041a\u043d\u043e\u043f\u043a\u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u043f\u0440\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438. <\/figcaption><\/div>\n<\/figure>\n<h3>\u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a\u043d\u043e\u043f\u043e\u043a \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438<\/h3>\n<p>\u0425\u043e\u0442\u044f \u043a\u043d\u043e\u043f\u043a\u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u043e\u043f\u0430\u0434\u0430\u044e\u0442, \u043d\u0430 \u043d\u0438\u0445 \u0432\u0441\u0435 \u0435\u0449\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0436\u0438\u043c\u0430\u0442\u044c. \u0418\u0442\u0430\u043a, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 <code>enabled<\/code> \u0434\u043b\u044f <code>IconControlButton<\/code> \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c \u0435\u0433\u043e \u0432 <code>false<\/code> \u0434\u043b\u044f \u043a\u043d\u043e\u043f\u043a\u0438 \u0441\u0431\u0440\u043e\u0441\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0430 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043a\u043b\u0438\u043a\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0439. \u0410 \u043a\u043d\u043e\u043f\u043a\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 30: \u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a\u043d\u043e\u043f\u043e\u043a \u043f\u0440\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438<\/h4>\n<pre><code class=\"kotlin\">@Composable private fun IconControlButton(     ...     \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442     enabled: Boolean = true ) {      IconButton(         onClick = onClick,         \/\/ \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e         enabled = enabled,         modifier = modifier             .size(48.dp)     ) {        ...     } }  \/\/ \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0432\u044b\u0437\u043e\u0432\u044b \u0432 ButtonContainer.Row \/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f enabled = !clearButtonVisible  \/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0441\u0431\u0440\u043e\u0441\u0430 enabled = false,  \/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f enabled = !clearButtonVisible,<\/code><\/pre>\n<h3>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0431\u044b\u0441\u0442\u0440\u043e\u0439 \u043d\u0430\u043a\u0440\u0443\u0442\u043a\u0438 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0442\u0430\u043f\u043d\u0443\u0432 \u043f\u043e \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0443, \u0442\u0430\u043f\u043d\u0443\u0432 \u043a\u043d\u043e\u043f\u043a\u0443 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0432 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043a \u043f\u0440\u0430\u0432\u043e\u043c\u0443 \u043a\u0440\u0430\u044e. \u041d\u043e \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u043c \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0438 \u043d\u0430 \u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e?<\/p>\n<p>\u0420\u0430\u0434\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0430 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0431\u044b\u0441\u0442\u0440\u043e\u0439 \u043d\u0430\u043a\u0440\u0443\u0442\u043a\u0438 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043a \u043f\u0440\u0430\u0432\u043e\u043c\u0443 \u0438\u043b\u0438 \u043b\u0435\u0432\u043e\u043c\u0443 \u043a\u0440\u0430\u044e \u0438 \u043f\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0435\u0433\u043e \u0442\u0430\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<p>\u041c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 delay, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043b\u0438 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0438.<\/p>\n<p>\u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0441\u043b\u0435\u0434\u0438\u043c \u0437\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c Job \u0438 \u043e\u0442\u043c\u0435\u043d\u044f\u0435\u043c \u0435\u0433\u043e \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043e\u0442\u043f\u0443\u0441\u0442\u0438\u0442 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 31: \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u043e\u0433\u0438\u043a\u0438 \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f<\/h4>\n<pre><code class=\"kotlin\">\/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0433\u0434\u0435-\u0442\u043e \u0432 \u0444\u0430\u0439\u043b\u0435 private const val COUNTER_DELAY_INITIAL_MS = 500L private const val COUNTER_DELAY_FAST_MS = 100L  awaitPointerEventScope {     ...          var counterJob: Job? = null          do {         val event = awaitPointerEvent()         event.changes.forEach { pointerInputChange ->             scope.launch {                 \/\/ \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u0441\u043e\u043f\u0440\u043e\u0442\u0438\u0432\u043b\u0435\u043d\u0438\u044f,\u00a0 \u0447\u0442\u043e\u0431\u044b \u0447\u0435\u043c \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a                 \/\/ \u0431\u043b\u0438\u0436\u0435 \u043a \u0433\u0440\u0430\u043d\u0438\u0446\u0435, \u0442\u0435\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u0443\u0441\u0438\u043b\u0438\u0439 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0434\u043b\u044f \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f                 if ((dragDirection.value == DragDirection.NONE &amp;&amp;                             pointerInputChange.positionChange().x.absoluteValue                      dragDirection.value == DragDirection.HORIZONTAL                 ) {                     \/\/ \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f                     if (dragDirection.value == DragDirection.NONE) {                         counterJob = scope.launch {                             delay(COUNTER_DELAY_INITIAL_MS)                                                          var elapsed = COUNTER_DELAY_INITIAL_MS                             while (isActive &amp;&amp; thumbOffsetX.value.absoluteValue >= (dragLimitHorizontalPx * DRAG_LIMIT_HORIZONTAL_THRESHOLD_FACTOR)) {                                 if (thumbOffsetX.value.sign > 0) {                                     onValueIncreaseClick()                                 } else {                                     onValueDecreaseClick()                                 }                                                                  delay(COUNTER_DELAY_FAST_MS)                                 elapsed += COUNTER_DELAY_FAST_MS                             }                         }                     }                                          \/\/ \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435, \u043f\u043e\u043a\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043f\u0443\u0449\u0435\u043d                     dragDirection.value = DragDirection.HORIZONTAL                                          ...                 } else if (...) {                     ...                 }             }         }     } while (event.changes.any { it.pressed })          counterJob?.cancel()          ... }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0435\u0441\u043b\u0438 \u043c\u044b \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u043c \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043a \u043a\u0440\u0430\u044e \u0438 \u0437\u0430\u0434\u0435\u0440\u0436\u0438\u043c \u0435\u0433\u043e \u0442\u0430\u043c, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043d\u0430\u0447\u0430\u0442\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u043b\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0442\u044c\u0441\u044f.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/139\/3c5\/c03\/1393c5c03308c06c85cde6aab86a523d.gif\" width=\"480\" height=\"266\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/139\/3c5\/c03\/1393c5c03308c06c85cde6aab86a523d.gif\"\/><\/figure>\n<h3>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0446\u0432\u0435\u0442\u0430 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0430\u0445-\u0438\u043a\u043e\u043d\u043a\u0430\u0445<\/h3>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0448\u0430\u0433\u0430 \u043c\u044b \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u043c \u043a\u043d\u043e\u043f\u043a\u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u0446\u0432\u0435\u0442 \u0438\u043a\u043e\u043d\u043a\u0438 \u043d\u0430 \u0431\u0435\u043b\u044b\u0439. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430\u0448 interactionSource \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438\u0437 \u043d\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <code>isPressed<\/code>. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f <code>tintColor<\/code> \u0438\u043a\u043e\u043d\u043a\u0438.<\/p>\n<h4> \u041b\u0438\u0441\u0442\u0438\u043d\u0433 32: \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0446\u0432\u0435\u0442\u0430 \u0438\u043a\u043e\u043d\u043a\u0438 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443<\/h4>\n<pre><code class=\"kotlin\">@Composable private fun IconControlButton(     icon: ImageVector,     contentDescription: String,     onClick: () -> Unit,     modifier: Modifier = Modifier,     tintColor: Color = Color.White,     \/\/ \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442     clickTintColor: Color = Color.White,     enabled: Boolean = true ) {     val interactionSource = remember { MutableInteractionSource() }     val isPressed by interactionSource.collectIsPressedAsState()      IconButton(         onClick = onClick,         \/\/ \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f         interactionSource = interactionSource,         enabled = enabled,         modifier = modifier             .size(48.dp)     ) {         Icon(             imageVector = icon,             contentDescription = contentDescription,             \/\/ \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043e\u0442\u0442\u0435\u043d\u043e\u043a \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438             tint = if (isPressed) clickTintColor else tintColor,             modifier = Modifier.size(32.dp)         )     } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043d\u043e\u043f\u043e\u043a \u0438\u043a\u043e\u043d\u043a\u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0442\u0441\u044f \u0431\u0435\u043b\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0d4\/539\/f9f\/0d4539f9f881d803dbcd8643b8f38994.gif\" alt=\"\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0446\u0432\u0435\u0442\u0430 \u0438\u043a\u043e\u043d\u043a\u0438 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438.\" title=\"\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0446\u0432\u0435\u0442\u0430 \u0438\u043a\u043e\u043d\u043a\u0438 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438.\" width=\"400\" height=\"192\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0d4\/539\/f9f\/0d4539f9f881d803dbcd8643b8f38994.gif\"\/><\/p>\n<div><figcaption>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0446\u0432\u0435\u0442\u0430 \u0438\u043a\u043e\u043d\u043a\u0438 \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438.<\/figcaption><\/div>\n<\/figure>\n<h3>\u041a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/h3>\n<p>\u0412\u043e\u0442 \u043c\u044b \u0438 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u043d\u0430\u0448\u0443 \u0430\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043a\u043d\u043e\u043f\u043a\u0443-\u0441\u0447\u0435\u0442\u0447\u0438\u043a, \u0438 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bbc\/1db\/da1\/bbc1dbda1e589d16a65491baec1d14b4.gif\" alt=\"\u0413\u043e\u0442\u043e\u0432\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430-\u0441\u0447\u0435\u0442\u0447\u0438\u043a.\" title=\"\u0413\u043e\u0442\u043e\u0432\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430-\u0441\u0447\u0435\u0442\u0447\u0438\u043a.\" width=\"480\" height=\"270\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bbc\/1db\/da1\/bbc1dbda1e589d16a65491baec1d14b4.gif\"\/><\/p>\n<div><figcaption>\u0413\u043e\u0442\u043e\u0432\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430-\u0441\u0447\u0435\u0442\u0447\u0438\u043a.<\/figcaption><\/div>\n<\/figure>\n<p>\u042d\u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u0438\u043d\u043d\u043e\u0435 \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043f\u0430\u0441\u0438\u0431\u043e, \u0447\u0442\u043e \u0432\u044b\u0434\u0435\u0440\u0436\u0430\u043b\u0438 \u0435\u0433\u043e \u0434\u043e \u043a\u043e\u043d\u0446\u0430, \u0438, \u044f \u043d\u0430\u0434\u0435\u044e\u0441\u044c, \u0447\u0442\u043e \u0432\u044b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u044b \u043d\u0430\u0448\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c. \u041d\u0435 \u0441\u0442\u0435\u0441\u043d\u044f\u0439\u0442\u0435\u0441\u044c \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0435\u0439, \u0447\u0442\u043e\u0431\u044b \u0435\u0449\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u044c\u0441\u044f \u043a \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u0434\u0438\u0437\u0430\u0439\u043d\u0443 \u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e.<\/p>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0439\u0442\u0438 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u043a\u043e\u0434\u0430 \u0432 <a href=\"https:\/\/gist.github.com\/landomen\/5efa5386f21f674ec97a85cbe006a33d\"><u>\u044d\u0442\u043e\u043c \u0433\u0438\u0441\u0442\u0435 \u043d\u0430 GitHub<\/u><\/a>.<\/p>\n<p><strong>\u041d\u0430\u0434 \u0447\u0435\u043c \u0435\u0449\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c<\/strong><\/p>\n<ul>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0442\u0430\u043a\u0442\u0438\u043b\u044c\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e \u0441\u0432\u044f\u0437\u044c, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u0435\u0442 \u043f\u0440\u0435\u0434\u0435\u043b\u0430 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u0443\u0432\u0435\u0434\u043e\u043c\u0438\u0442\u044c \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u0443\u0439\u0442\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c composable \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Layout Inspector.<\/p>\n<\/li>\n<\/ul>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0412 \u044d\u0442\u043e\u043c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u043b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0433\u043e \u0435\u0449\u0435 \u0431\u043e\u043b\u044c\u0448\u0435. \u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0441\u0440\u0435\u0434\u0435, \u0432\u0430\u043c \u0441\u0442\u043e\u0438\u0442 \u0441\u043b\u0435\u0433\u043a\u0430 \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u0434\u0443 \u043d\u0430\u043f\u0438\u043b\u044c\u043d\u0438\u043a\u043e\u043c.<\/em><\/p>\n<hr\/>\n<p>\u0412\u0441\u0435\u0445, \u043a\u0442\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043b \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u0434\u043e \u043a\u043e\u043d\u0446\u0430, \u043f\u0440\u0438\u0433\u043b\u0430\u0448\u0430\u0435\u043c \u043d\u0430 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0435 \u0443\u0440\u043e\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u043e\u0439\u0434\u0443\u0442 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u043d\u043b\u0430\u0439\u043d-\u043a\u0443\u0440\u0441\u043e\u0432 OTUS \u0432 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0435 \u0432\u0440\u0435\u043c\u044f:<\/p>\n<ul>\n<li>\n<p><strong>\u0424\u043e\u043d\u043e\u0432\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0432 Android \u2014 Service \u0438 WorkManager:<\/strong> \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0444\u043e\u043d\u043e\u0432\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0432 Android \u0438 \u043d\u0430\u0443\u0447\u0438\u043c\u0441\u044f \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438. <a href=\"https:\/\/otus.pw\/ZTyd\/\">\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043d\u0430 \u0443\u0440\u043e\u043a<\/a><\/p>\n<\/li>\n<li>\n<p><strong>\u0410\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u043c\u043e\u0434\u0443\u043b\u044c \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438.<\/strong> \u041d\u0430 \u0437\u0430\u043d\u044f\u0442\u0438\u0438 \u043e\u0431\u0441\u0443\u0434\u0438\u043c, \u043a\u0430\u043a \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u0447\u0438\u0441\u0442\u0443\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u043c\u043e \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u0418\u0441\u0441\u043b\u0435\u0434\u0443\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u0443\u044e \u043d\u0430 Kotlin. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0434\u0443\u043b\u044f \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u043a\u043e\u043d\u0446\u0435\u043d\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0432\u0441\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u0430. <a href=\"https:\/\/otus.pw\/3PzO\/\">\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f \u043d\u0430 \u0443\u0440\u043e\u043a<\/a><\/p>\n<\/li>\n<\/ul>\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\/740190\/\"> https:\/\/habr.com\/ru\/articles\/740190\/<\/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<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0434\u043b\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0411\u043e\u0440\u043e\u0437\u0434\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0440\u044b \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0430 \u0432 \u043f\u043e\u0438\u0441\u043a\u0430\u0445 \u0445\u043e\u0440\u043e\u0448\u0438\u0445 \u0433\u043e\u0442\u043e\u0432\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439, \u044f \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0441\u044f \u043d\u0430 \u044d\u0442\u043e\u0442 \u0434\u0438\u0437\u0430\u0439\u043d \u043e\u0442 <a href=\"https:\/\/dribbble.com\/ehsancinematic\"><u>\u042d\u0445\u0441\u0430\u043d\u0430 \u0420\u0430\u0445\u0438\u043c\u0438<\/u><\/a> (Ehsan Rahimi) \u043d\u0430 Dribble. \u041f\u0440\u0438\u0434\u044f \u043a \u0432\u044b\u0432\u043e\u0434\u0443, \u0447\u0442\u043e \u0432\u043e\u0441\u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0435\u0433\u043e \u0432 Compose \u2014 \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0430\u044f, \u044f \u0437\u0430\u043a\u0430\u0442\u0430\u043b \u0440\u0443\u043a\u0430\u0432\u0430 \u0438 \u043f\u0440\u0438\u043d\u044f\u043b\u0441\u044f \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0412 \u044d\u0442\u043e\u043c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435 \u044f \u043f\u043e\u0434\u0435\u043b\u044e\u0441\u044c \u0441 \u0432\u0430\u043c\u0438 \u043a\u0430\u0436\u0434\u044b\u043c \u0448\u0430\u0433\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u044f\u043b \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u0434\u0438\u0437\u0430\u0439\u043d\u0430 \u0432 Jetpack Compose.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0414\u0438\u0437\u0430\u0439\u043d \u043a\u043d\u043e\u043f\u043a\u0438-\u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u043e\u0442 <a href=\"https:\/\/dribbble.com\/ehsancinematic\"><u>\u042d\u0445\u0441\u0430\u043d\u0430 \u0420\u0430\u0445\u0438\u043c\u0438<\/u><\/a>.<\/figcaption><\/div>\n<\/figure>\n<p><em>\u0421\u0440\u0430\u0437\u0443 \u043e\u0433\u043e\u0432\u043e\u0440\u044e\u0441\u044c, \u0447\u0442\u043e \u0445\u043e\u0442\u044c \u043c\u044b \u0438 \u0431\u0443\u0434\u0435\u043c \u0441\u0442\u0430\u0440\u0430\u0442\u044c\u0441\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0442\u043e\u0447\u043d\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u0434\u0438\u0437\u0430\u0439\u043d\u0443, \u0432 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0435\u0449\u0435 \u0435\u0441\u0442\u044c \u043d\u0430\u0434 \u0447\u0435\u043c \u043f\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u2014 \u043a\u043d\u043e\u043f\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0435 \u0435\u0449\u0435 \u0431\u043e\u043b\u0435\u0435 \u043f\u043b\u0430\u0432\u043d\u043e\u0439 \u0438 \u0431\u043b\u0438\u0437\u043a\u043e\u0439 \u043a \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u0443.<\/em><\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043c\u0430\u043a\u0435\u0442\u0430<\/h3>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u043c\u044b \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043c\u0430\u043a\u0435\u0442\u0430 \u0431\u0435\u0437 \u043a\u0430\u043a\u0438\u0445-\u043b\u0438\u0431\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u0438\u043b\u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u0435\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0434\u0438\u0437\u0430\u0439\u043d \u043d\u0430 \u0434\u0432\u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430: \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u0438 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u043d\u044b\u0439 \u043c\u0430\u043a\u0435\u0442 \u043a\u043d\u043e\u043f\u043a\u0438 \u0441 \u0438\u043a\u043e\u043d\u043a\u0430\u043c\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f, \u0441\u0431\u0440\u043e\u0441\u0430 \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041d\u0430\u043c \u0442\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u0435\u043d \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u043c\u0430\u043a\u0435\u0442 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u0434\u0432\u0443\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u043d\u043e\u043f\u043a\u0430 \u0441\u0431\u0440\u043e\u0441\u0430 \u0441\u043a\u0440\u044b\u0442\u0430 \u043f\u043e\u0434 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u044b\u043c \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u043e\u043c, \u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044b \u043a\u043d\u043e\u043f\u043a\u0438, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>Box<\/code>, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 1: Composable \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0433\u043e \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u043c\u0430\u043a\u0435\u0442\u0430<\/h4>\n<pre><code class=\"kotlin\">@Composable private fun CounterButton(     value: String,     modifier: Modifier = Modifier ) {     Box(         contentAlignment = Alignment.Center,         modifier = modifier             .width(200.dp)             .height(80.dp)     ) {          ButtonContainer(             onValueDecreaseClick = { \/*TODO*\/ },             onValueIncreaseClick = { \/*TODO*\/ },             onValueClearClick = { \/*TODO*\/ },             modifier = Modifier         )          DraggableThumbButton(             value = value,             onClick = { \/*TODO*\/ },             modifier = Modifier.align(Alignment.Center)         )     } }<\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c\u0441\u044f \u0441 composable <code>ButtonContainer<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0430\u0448\u0438 \u043a\u043d\u043e\u043f\u043a\u0438-\u0438\u043a\u043e\u043d\u043a\u0438. \u0422\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u0438 \u0442\u0440\u0438 \u043a\u043d\u043e\u043f\u043a\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>Row<\/code>. \u0413\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0438 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435, \u0432 \u0446\u0435\u043d\u0442\u0440\u0435 \u0438 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043c\u0430\u043a\u0435\u0442\u0430 \u043d\u0430\u043c \u043f\u043e\u043c\u043e\u0436\u0435\u0442 <code>Arrangement.SpaceBetween<\/code>. \u041a\u043d\u043e\u043f\u043a\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e composable <code>IconControlButton<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043f\u0440\u043e\u0441\u0442\u0443 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u0435\u0440\u0442\u043a\u043e\u0439 <code>IconButton<\/code>.<\/p>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0436\u0435 \u0438\u043a\u043e\u043d\u043a\u0438, \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043b\u0438\u0431\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c <\/em><code>androidx.compose.material:material-icons-extended<\/code><em>, \u043b\u0438\u0431\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u0445 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/em><\/p>\n<p>\u0424\u043e\u043d \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u0444\u043e\u0440\u043c\u044b \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 <code>clip(RoundedCornerShape()<\/code>), \u0438 \u043d\u0430\u043c \u0435\u0449\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0446\u0432\u0435\u0442 \u0444\u043e\u043d\u0430. \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u0435\u043d\u044f\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0430\u043b\u044c\u0444\u0430-\u043a\u0430\u043d\u0430\u043b\u0430 \u0446\u0432\u0435\u0442\u0430 \u0444\u043e\u043d\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u0437\u0436\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0430\u043d\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430. \u0418 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c tint\u0421olor \u043d\u0430\u0448\u0438\u0445 \u043a\u043d\u043e\u043f\u043e\u043a-\u0438\u043a\u043e\u043d\u043e\u043a. \u041a\u043d\u043e\u043f\u043a\u0443 \u0441\u0431\u0440\u043e\u0441\u0430 \u043c\u044b \u043f\u043e\u043a\u0430 \u0441\u043a\u0440\u043e\u0435\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u0435\u0435 \u043b\u043e\u0433\u0438\u043a\u043e\u0439 \u043c\u044b \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043d\u0446\u0435.<\/p>\n<p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0412\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0442\u0430\u043a \u0445\u0430\u0440\u0434\u043a\u043e\u0434\u0438\u0442\u044c \u0446\u0432\u0435\u0442\u0430, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u044d\u0442\u043e \u0432\u044b\u0437\u043e\u0432\u0435\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441\u043e \u0441\u0432\u0435\u0442\u043b\u043e\u0439\/\u0442\u0435\u043c\u043d\u043e\u0439 \u0442\u0435\u043c\u043e\u0439. \u0417\u0434\u0435\u0441\u044c \u0434\u0435\u043b\u0430\u044e \u044d\u0442\u043e \u0442\u0430\u043a \u0442\u043e\u043f\u043e\u0440\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u0434 \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0431\u044b\u043b \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043b\u0430\u043a\u043e\u043d\u0438\u0447\u043d\u044b\u043c.<\/em><\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 2: Composable \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 \u043d\u0430\u0448\u0435\u0439 \u043a\u043d\u043e\u043f\u043a\u0438<\/h4>\n<pre><code class=\"kotlin\">private const val ICON_BUTTON_ALPHA_INITIAL = 0.3f private const val CONTAINER_BACKGROUND_ALPHA_INITIAL = 0.6f  @Composable private fun ButtonContainer(     onValueDecreaseClick: () -> Unit,     onValueIncreaseClick: () -> Unit,     onValueClearClick: () -> Unit,     modifier: Modifier = Modifier,     clearButtonVisible: Boolean = false, ) {     Row(         horizontalArrangement = Arrangement.SpaceBetween,         verticalAlignment = Alignment.CenterVertically,         modifier = modifier             .fillMaxSize()             .clip(RoundedCornerShape(64.dp))             .background(Color.Black.copy(alpha = CONTAINER_BACKGROUND_ALPHA_INITIAL))             .padding(horizontal = 8.dp)     ) {         \/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f         IconControlButton(             icon = Icons.Outlined.Remove,             contentDescription = \"Decrease count\",             onClick = onValueDecreaseClick,             tintColor = Color.White.copy(alpha = ICON_BUTTON_ALPHA_INITIAL)         )          \/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0441\u0431\u0440\u043e\u0441\u0430         if (clearButtonVisible) {             IconControlButton(                 icon = Icons.Outlined.Clear,                 contentDescription = \"Clear count\",                 onClick = onValueClearClick,                 tintColor = Color.White.copy(alpha = ICON_BUTTON_ALPHA_INITIAL)             )         }          \/\/ \u043a\u043d\u043e\u043f\u043a\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f         IconControlButton(             icon = Icons.Outlined.Add,             contentDescription = \"Increase count\",             onClick = onValueIncreaseClick,             tintColor = Color.White.copy(alpha = ICON_BUTTON_ALPHA_INITIAL)         )     } }  @Composable private fun IconControlButton(     icon: ImageVector,     contentDescription: String,     onClick: () -> Unit,     modifier: Modifier = Modifier,     tintColor: Color = Color.White, ) {     IconButton(         onClick = onClick,         modifier = modifier             .size(48.dp)     ) {         Icon(             imageVector = icon,             contentDescription = contentDescription,             tint = tintColor,             modifier = Modifier.size(32.dp)         )     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438-\u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c composable <code>Text<\/code>, \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044b\u0439 \u0432 Box, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u043e\u0431\u0440\u0435\u0437\u043a\u0443 <code>CircleShape<\/code> \u0438 \u0442\u0435\u043d\u044c, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442 \u043a\u0440\u0443\u0433\u043b\u043e\u0439 \u043a\u043d\u043e\u043f\u043a\u0438. \u0414\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043a\u043b\u0438\u043a\u043e\u0432 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>.clickable {}<\/code>.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 3: \u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 composable \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430<\/h4>\n<pre><code class=\"kotlin\">@Composable private fun DraggableThumbButton(     value: String,     onClick: () -> Unit,     modifier: Modifier = Modifier ) {     Box(         contentAlignment = Alignment.Center,         modifier = modifier             .shadow(8.dp, shape = CircleShape)             .size(64.dp)             .clip(CircleShape)             .clickable { onClick() }             .background(Color.Gray)     ) {         Text(             text = value,             color = Color.White,             style = MaterialTheme.typography.headlineLarge,             textAlign = TextAlign.Center,         )     } }<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e composable <code>CounterButton<\/code>.<\/p>\n<pre><code class=\"kotlin\">Column(     modifier = Modifier.wrapContentSize(),     verticalArrangement = Arrangement.Center,     horizontalAlignment = Alignment.CenterHorizontally ) {     CounterButton(value = \"0\") }<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430\u0448 \u043a\u043e\u0434, \u0442\u043e \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0438 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f.<\/p>\n<figure class=\"\">\n<div><figcaption>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430\u0448\u0438\u0445 composable.<\/figcaption><\/div>\n<\/figure>\n<h3>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043b\u043e\u0433\u0438\u043a\u0438 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430<\/h3>\n<p>\u0412 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0445 \u043c\u0430\u043a\u0435\u0442\u0430\u0445 \u043c\u044b \u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e TODO \u043f\u043e\u0434 \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u0438 \u043a\u043b\u0438\u043a\u043e\u0432. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0434\u043b\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430. \u041c\u044b \u0431\u044b \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u0438, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0431\u044b\u043b\u043e \u0432\u043d\u0443\u0442\u0440\u0438 composable \u043a\u043d\u043e\u043f\u043a\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u044b\u043d\u0435\u0441\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u0438 \u043a\u043b\u0438\u043a\u043e\u0432 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 <code>CounterButton<\/code>.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 4: Composable \u043a\u043d\u043e\u043f\u043a\u0438-\u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0441\u043e \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044f\u043c\u0438 \u043a\u043b\u0438\u043a\u043e\u0432<\/h4>\n<pre><code class=\"kotlin\">@Composable private fun CounterButton(     value: String,     onValueDecreaseClick: () -> Unit,     onValueIncreaseClick: () -> Unit,     onValueClearClick: () -> Unit,     modifier: Modifier = Modifier ) {     Box(         contentAlignment = Alignment.Center,         modifier = modifier             .width(200.dp)             .height(80.dp)     ) {          ButtonContainer(             onValueDecreaseClick = onValueDecreaseClick,             onValueIncreaseClick = onValueIncreaseClick,             onValueClearClick = onValueClearClick,             modifier = Modifier         )          DraggableThumbButton(             value = value,             onClick = onValueIncreaseClick,             modifier = Modifier.align(Alignment.Center)         )     } }<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438. \u041c\u044b \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043c \u0435\u0433\u043e \u043d\u0430 \u0432\u0435\u0440\u0445\u043d\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c, \u0433\u0434\u0435 \u043e\u043d\u043e, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u043b\u043e\u0441\u044c \u0431\u044b \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0432\u0430\u0448\u0435\u0439 ViewModel.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 5: Composable \u043a\u043d\u043e\u043f\u043a\u0438-\u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c<\/h4>\n<pre><code class=\"kotlin\">var valueCounter by remember {     mutableStateOf(0) }  CounterButton(     value = valueCounter.toString(),     onValueIncreaseClick = {         valueCounter += 1     },     onValueDecreaseClick = {         valueCounter = maxOf(valueCounter - 1, 0)     },     onValueClearClick = {         valueCounter = 0     } )<\/code><\/pre>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c \u043d\u0430\u0448\u0430 \u043a\u043d\u043e\u043f\u043a\u0430-\u0441\u0447\u0435\u0442\u0447\u0438\u043a \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u043e\u0436\u0438\u043b\u0430. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0436\u0438\u043c\u0430\u0442\u044c \u043d\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043e\u043a \u0438\u043b\u0438 \u043a\u043d\u043e\u043f\u043a\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f, \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f. \u041a\u043d\u043e\u043f\u043a\u0430 \u0441\u0431\u0440\u043e\u0441\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0435 \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u0430 \u0441\u043a\u0440\u044b\u0442\u0430 \u0437\u0430 \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u043e\u043c. \u041c\u044b \u0432\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u043d\u0435\u0439 \u043f\u043e\u0437\u0436\u0435, \u043a\u043e\u0433\u0434\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0435.<\/p>\n<figure class=\"\">\n<div><figcaption>\u041d\u0430\u0436\u0438\u043c\u0430\u0435\u043c\u0430\u044f \u043a\u043d\u043e\u043f\u043a\u0430-\u0441\u0447\u0435\u0442\u0447\u0438\u043a.<\/figcaption><\/div>\n<\/figure>\n<h3>\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f<\/h3>\n<p>\u041a\u043d\u043e\u043f\u043a\u0430-\u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0445\u0443\u0434\u043e-\u0431\u0435\u0434\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0444\u0438\u0447\u0443 \u044d\u0442\u043e\u0433\u043e \u0434\u0438\u0437\u0430\u0439\u043d\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u0431\u0435\u0433\u0443\u043d\u043a\u0430 \u0434\u043b\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0434\u0432\u0435 \u043d\u043e\u0432\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 <code>DraggableThumbButton<\/code>. \u041f\u0435\u0440\u0432\u0430\u044f \u0438\u0437 \u043d\u0438\u0445 \u2014 <code>thumbOffsetX: Animatable<\/code>. \u041e\u043d\u0430 \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043c \u0441 \u043f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0435\u0439 \u043a\u043d\u043e\u043f\u043a\u0438-\u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0435\u0435 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c. \u0412\u0442\u043e\u0440\u0430\u044f \u2014 \u044d\u0442\u043e scope \u043a\u043e\u0440\u0443\u0442\u0438\u043d\u044b, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f <code>thumbOffsetX<\/code> \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438.<\/p>\n<pre><code class=\"kotlin\">val thumbOffsetX = remember { Animatable(0f) } val scope = rememberCoroutineScope()<\/code><\/pre>\n<p>\u0414\u0432\u0435 \u043d\u043e\u0432\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 composable <code>DraggableThumbButton<\/code>.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 Box \u043f\u043e\u043b\u0437\u0443\u043d\u043a\u0430 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>.offset<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 <code>composable<\/code> \u043f\u043e \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044e \u043a \u0435\u0433\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044e. \u0414\u043b\u044f \u043e\u0441\u0438 x \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>thumbOffsetX<\/code>, \u0430 \u0434\u043b\u044f \u043e\u0441\u0438 y \u043f\u043e\u043a\u0430 \u043e\u0441\u0442\u0430\u0432\u0438\u043c 0.<\/p>\n<h4>\u041b\u0438\u0441\u0442\u0438\u043d\u0433 5: \u041c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 offset \u0432 DraggableThumbButton.Box<\/h4>\n<pre><code class=\"kotlin\">Box(     contentAlignment = Alignment.Center,     modifier = modifier         \/\/ \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u044e x composable         .offset {             IntOffset(                 thumbOffsetX.value.toInt(),                 0             )         }         ...         ...<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043a\u0430\u043a-\u0442\u043e<\/p>\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-382936","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/382936","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=382936"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/382936\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=382936"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=382936"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=382936"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}