{"id":370859,"date":"2024-05-21T04:35:10","date_gmt":"2024-05-21T04:35:10","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=370859"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=370859","title":{"rendered":"<span>Drag and Drop \u0432 Jetpack Compose<\/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<h2>\u0412\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0412 \u044f\u043d\u0432\u0430\u0440\u0435 2024, \u043a\u0440\u0443\u043f\u043d\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 Jetpack Compose \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u043e \u0434\u0432\u0430 \u043d\u043e\u0432\u044b\u0445 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430: <code>dragAndDropSource<\/code>\u00a0\u0438\u00a0<code>dragAndDropTarget<\/code>. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442 Drag and Drop \u0432 Jetpack Compose.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/65f39894d1b5b66d8d9d61d6\" data-style=\"\" id=\"65f39894d1b5b66d8d9d61d6\" width=\"\"><\/div>\n<h2>Composable \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0435\u0434\u044b<\/h2>\n<p>\u0421\u043f\u0435\u0440\u0432\u0430 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0435\u0434\u044b.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/888\/4d9\/b5b\/8884d9b5b4b1ac091ab77658494a4024.png\" width=\"1000\" height=\"374\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/888\/4d9\/b5b\/8884d9b5b4b1ac091ab77658494a4024.png\"\/><\/figure>\n<pre><code class=\"kotlin\">fun FoodItemCard(foodItem: FoodItem) {     Card(         elevation = CardDefaults.elevatedCardElevation(defaultElevation = 10.dp),         colors = CardDefaults.elevatedCardColors(             containerColor = Color.White,         ), shape = RoundedCornerShape(24.dp),         modifier = Modifier.padding(8.dp)     ) {         Row(             verticalAlignment = Alignment.CenterVertically,             modifier = Modifier.padding(10.dp)         ) {             Image(                 painter = painterResource(id = foodItem.image),                 contentDescription = null,                 contentScale = ContentScale.Crop,                 modifier = Modifier                     .size(130.dp)                     .clip(RoundedCornerShape(16.dp))              )                       Spacer(modifier = Modifier.width(20.dp))             Column(modifier = Modifier.weight(1f)) {                 Text(                     text = foodItem.name,                     fontSize = 22.sp,                     color = Color.DarkGray                 )                 Spacer(modifier = Modifier.height(6.dp))                 Text(                     text = \"$${foodItem.price}\",                     fontSize = 18.sp,                     color = Color.Black,                     fontWeight = FontWeight.ExtraBold                 )             }         }     } }  LazyColumn(     modifier = Modifier.fillMaxSize(),     contentPadding = PaddingValues(horizontal = 10.dp) ) {     items(items = foodList) { food ->         FoodItemCard(foodItem = food)     } }<\/code><\/pre>\n<h3>Composable \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430<\/h3>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/138\/686\/f9d\/138686f9de89731c5e6a020e112e1a5c.png\" width=\"1000\" height=\"396\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/138\/686\/f9d\/138686f9de89731c5e6a020e112e1a5c.png\"\/><\/figure>\n<pre><code class=\"kotlin\">@Composable fun PersonCard(person: Person) {         Column(             modifier = Modifier                 .padding(6.dp)                 .shadow(elevation = 4.dp, shape = RoundedCornerShape(16.dp))                 .width(width = 120.dp)                 .fillMaxHeight(0.8f)                 .background(Color.White, RoundedCornerShape(16.dp)),             verticalArrangement = Arrangement.Center,             horizontalAlignment = Alignment.CenterHorizontally         ) {             Image(                 painter = painterResource(id = person.profile), contentDescription = null,                 modifier = Modifier                     .size(70.dp)                     .clip(CircleShape),                 contentScale = ContentScale.Crop             )             Spacer(modifier = Modifier.height(10.dp))             Text(                 text = person.name,                 fontSize = 18.sp,                 color = Color.Black,                 fontWeight = FontWeight.Bold             )         } }  LazyRow(     modifier = Modifier         .fillMaxHeight(0.3f)         .fillMaxWidth()         .background(Color.LightGray, shape = RoundedCornerShape(topEnd = 10.dp, topStart = 10.dp))         .padding(vertical = 10.dp)         .align(Alignment.BottomCenter),     verticalAlignment = Alignment.CenterVertically,     horizontalArrangement = Arrangement.Center ) {     items(items = persons) { person ->         PersonCard(person)     } }<\/code><\/pre>\n<h2>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u043b\u044f Drag and Drop<\/h2>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043d\u0430\u0447\u043d\u0451\u043c, \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c:<\/p>\n<h4>Modifier.dragAndDropSource<\/h4>\n<p>\u042d\u0442\u043e\u0442 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c Drag and Drop.<\/p>\n<pre><code class=\"kotlin\">@Composable fun MyDraggableComponent() {     Box(         modifier = Modifier             .size(100.dp)             .background(Color.Blue)             .dragAndDropSource(                 drawDragDecoration = {                     \/\/ UI \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430                 }             ) {                 \/\/ \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 Drag and Drop                 startTransfer (\/* \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 *\/ )             }     ) { \/* \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 *\/ } }<\/code><\/pre>\n<ul>\n<li>\n<p><code>Modifier.dragAndDropSource<\/code>\u00a0\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u0432\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430:\u00a0<code>drawDragDecoration<\/code>\u00a0\u0438\u00a0<code>block<\/code>;<\/p>\n<\/li>\n<li>\n<p><code>drawDragDecoration<\/code> \u2014 \u044d\u0442\u043e \u043b\u044f\u043c\u0431\u0434\u0430 \u0431\u043b\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u0442\u0441\u044f Drag and Drop&#8217;\u043e\u043c;<\/p>\n<\/li>\n<li>\n<p><code>block<\/code>\u00a0\u044d\u0442\u043e \u043b\u044f\u043c\u0431\u0434\u0430 \u0431\u043b\u043e\u043a, \u043e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u00a0<code>DragAndDropSourceScope<\/code>\u00a0\u043a\u0430\u043a \u0440\u0435\u0441\u0438\u0432\u0435\u0440. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c Drag and Drop \u0436\u0435\u0441\u0442 \u0438 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c;<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u0437\u043e\u0432\u00a0<code>startTransfer<\/code>\u00a0\u0432 \u043b\u044f\u043c\u0431\u0434\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 Drag and Drop \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u044d\u0442\u043e\u0442 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0430 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443 \u0435\u0434\u044b:<\/p>\n<p>\u0422\u0443\u0442,\u00a0<code>transferData<\/code>\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 Drag and Drop. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0435\u0434\u044b \u0432 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430. <\/p>\n<pre><code class=\"kotlin\">private const val foodItemTransferAction = \"action_foodItem\" private const val foodItemTransferData = \"data_foofdItem\" ... startTransfer(     DragAndDropTransferData(         clipData = ClipData.newIntent(             \"foodItem\",             Intent(foodItemTransferAction).apply {                 putExtra(                     foodItemTransferData,                     Gson().toJson(foodItem)                 )             },         )     )<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 \u0435\u0434\u044b \u0441\u0442\u0430\u043b\u0430 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u043e\u0439.<\/p>\n<h2>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043c\u0435\u0441\u0442\u043e \u0434\u043b\u044f Drop and Drop<\/h2>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c:<\/p>\n<h4>Modifier.dragAndDropTarget<\/h4>\n<p>\u042d\u0442\u043e\u0442 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0432 Jetpack Compose \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 composable \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e\u0442 Drop and Drop.<\/p>\n<pre><code class=\"kotlin\">@Composable fun MyDragTarget() {     Box(         modifier = Modifier             .size(100.dp)             .background(Color.Green)             .dragAndDropTarget(                 shouldStartDragAndDrop = { startEvent-> return true },                 target =  object : DragAndDropTarget { ... }             )     ) { \/* \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 *\/ } }<\/code><\/pre>\n<p>\u041e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u0432\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430:<\/p>\n<ol>\n<li>\n<p><code>shouldStartDragAndDrop<\/code>: \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u043e\u0442\u00a0<code>DragAndDropEvent<\/code>.<\/p>\n<\/li>\n<li>\n<p><code>target<\/code> \u2014\u00a0<code>DragAndDropTarget<\/code>\u00a0\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e\u0442 Drag and Drop:<\/p>\n<ol>\n<li>\n<p><code>onDrop(event)<\/code>: \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u043e\u0432\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0435\u043d \u0432\u043d\u0443\u0442\u0440\u044c\u00a0<code>DragAndDropTarget<\/code>. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u00a0<code>true<\/code>\u00a0\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043e\u0442\u00a0<code>DragAndDropEvent<\/code>\u00a0\u0431\u044b\u043b\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043e, \u043d\u0430\u043f\u0440\u043e\u0442\u0438\u0432\u00a0<code>false<\/code>\u00a0\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043e\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u043e;<\/p>\n<\/li>\n<li>\n<p><code>onStarted(event)<\/code>: \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 Drag and Drop \u0436\u0435\u0441\u0442. \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f\u00a0<code>DragAndDropTarget<\/code>\u00a0\u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u043a \u044d\u0442\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p><code>onEntered(event)<\/code>,\u00a0<code>onMoved(event)<\/code>,\u00a0<code>onExited(event)<\/code>: \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u043e\u0433\u0434\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f\/\u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438\u00a0<code>DragAndDropTarget<\/code>;<\/p>\n<\/li>\n<li>\n<p><code>onChanged(event)<\/code>: \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 Drag and Drop \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u00a0<code>DragAndDropTarget<\/code>\u00a0\u043e\u0431\u043b\u0430\u0441\u0442\u0438;<\/p>\n<\/li>\n<li>\n<p><code>onEnded(event)<\/code>: \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 Drag and Drop \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e. \u0412\u0441\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b\u00a0<code>DragAndDropTarget<\/code>\u00a0\u0432 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u043d\u0435\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0435\u00a0<code>onStarted<\/code>\u00a0\u043f\u043e\u043b\u0443\u0447\u0430\u0442 \u044d\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f\u00a0<code>DragAndDropTarget<\/code>.<\/p>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 PersonCard \u2014 \u044d\u0442\u043e \u0446\u0435\u043b\u044c Drop, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u044d\u0442\u043e\u0442 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0435 PersonCard.<\/p>\n<pre><code class=\"kotlin\">fun PersonCard(person: Person) {     \/\/ \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u043a\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0435\u0434\u044b \u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430     val foodItems = remember { mutableStateMapOf&lt;Int, FoodItem>() }     Column(         modifier = Modifier              ....             .background(Color.White, RoundedCornerShape(16.dp))             .dragAndDropTarget(                 shouldStartDragAndDrop = { event ->                     \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0435\u0441\u043b\u0438 Drag and Drop \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u0435\u043a\u0441\u0442 intent mime \u0442\u0438\u043f\u0430                     event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_INTENT)                 },                 target = object : DragAndDropTarget {                     override fun onDrop(event: DragAndDropEvent): Boolean {                         \/\/ \u0434\u043e\u0441\u0442\u0430\u0435\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0435\u0434\u044b \u0438\u0437 Drag and Drop \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0433\u043e \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435                         val foodItem = event.toAndroidDragEvent().clipData.foodItem() ?: return false                         foodItems[foodItem.id] = foodItem                         return true                     }                 }             ),         verticalArrangement = Arrangement.Center,         horizontalAlignment = Alignment.CenterHorizontally     ) { \/\/ \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 PersonCard }  private fun ClipData.foodItem(): FoodItem? {     return (0 until itemCount)         .mapNotNull(::getItemAt).firstNotNullOfOrNull { item ->             item.intent?.getStringExtra(foodItemTransferData)?.takeIf { it.isNotEmpty() }         }?.let { Gson().fromJson(it, FoodItem::class.java) } }<\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438\u00a0<code>onDrop<\/code>\u00a0\u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043c\u044b \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0435\u0434\u044b Drag and Drop \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c\u00a0<code>foodItems<\/code>\u00a0\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0447\u0442\u043e\u0431\u044b \u0446\u0435\u043b\u044c Drop \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0430 \u0441\u0432\u043e\u0439 \u0446\u0432\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0436\u0435\u043b\u0430\u0435\u043c\u043e\u0433\u043e Drag and Drop. \u041d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>onEntered<\/code>\u00a0\u0438\u00a0<code>onExited<\/code>.<\/p>\n<pre><code class=\"kotlin\">@OptIn(ExperimentalFoundationApi::class) @Composable fun PersonCard(person: Person) {    var bgColor by remember { mutableStateOf(Color.White) }      Column(         modifier = Modifier             ....             .background(bgColor, RoundedCornerShape(16.dp))             .dragAndDropTarget(                 shouldStartDragAndDrop = { event -> ... },                 target = object : DragAndDropTarget {                     override fun onDrop(event: DragAndDropEvent): Boolean {                          ...                         bgColor = Color.White                         return true                                           }                      override fun onEntered(event: DragAndDropEvent) {                         super.onEntered(event)                         bgColor = Color.Red                     }                      override fun onExited(event: DragAndDropEvent) {                         super.onExited(event)                         bgColor = Color.White                     }                  }             ),     ) { \/* \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 PersonCard *\/ }<\/code><\/pre>\n<blockquote>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438\u0437 \u0441\u0442\u0430\u0442\u044c\u0438 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0439\u0442\u0438 \u0432 Github \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u2014 <a href=\"https:\/\/github.com\/cp-radhika-s\/Drag_and_drop_jetpack_compose\/tree\/explore-modifier-drag-drop-source\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/cp-radhika-s\/Drag_and_drop_jetpack_compose\/tree\/explore-modifier-drag-drop-source<\/a><\/p>\n<\/blockquote>\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\/800389\/\"> https:\/\/habr.com\/ru\/articles\/800389\/<\/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<h2>\u0412\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0412 \u044f\u043d\u0432\u0430\u0440\u0435 2024, \u043a\u0440\u0443\u043f\u043d\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 Jetpack Compose \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u043e \u0434\u0432\u0430 \u043d\u043e\u0432\u044b\u0445 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430: <code>dragAndDropSource<\/code>\u00a0\u0438\u00a0<code>dragAndDropTarget<\/code>. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442 Drag and Drop \u0432 Jetpack Compose.<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/65f39894d1b5b66d8d9d61d6\" data-style=\"\" id=\"65f39894d1b5b66d8d9d61d6\" width=\"\"><\/div>\n<h2>Composable \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0435\u0434\u044b<\/h2>\n<p>\u0421\u043f\u0435\u0440\u0432\u0430 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0435\u0434\u044b.<\/p>\n<figure class=\"full-width\"><\/figure>\n<pre><code class=\"kotlin\">fun FoodItemCard(foodItem: FoodItem) {     Card(         elevation = CardDefaults.elevatedCardElevation(defaultElevation = 10.dp),         colors = CardDefaults.elevatedCardColors(             containerColor = Color.White,         ), shape = RoundedCornerShape(24.dp),         modifier = Modifier.padding(8.dp)     ) {         Row(             verticalAlignment = Alignment.CenterVertically,             modifier = Modifier.padding(10.dp)         ) {             Image(                 painter = painterResource(id = foodItem.image),                 contentDescription = null,                 contentScale = ContentScale.Crop,                 modifier = Modifier                     .size(130.dp)                     .clip(RoundedCornerShape(16.dp))              )                       Spacer(modifier = Modifier.width(20.dp))             Column(modifier = Modifier.weight(1f)) {                 Text(                     text = foodItem.name,                     fontSize = 22.sp,                     color = Color.DarkGray                 )                 Spacer(modifier = Modifier.height(6.dp))                 Text(                     text = \"$${foodItem.price}\",                     fontSize = 18.sp,                     color = Color.Black,                     fontWeight = FontWeight.ExtraBold                 )             }         }     } }  LazyColumn(     modifier = Modifier.fillMaxSize(),     contentPadding = PaddingValues(horizontal = 10.dp) ) {     items(items = foodList) { food ->         FoodItemCard(foodItem = food)     } }<\/code><\/pre>\n<h3>Composable \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430<\/h3>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430.<\/p>\n<figure class=\"full-width\"><\/figure>\n<pre><code class=\"kotlin\">@Composable fun PersonCard(person: Person) {         Column(             modifier = Modifier                 .padding(6.dp)                 .shadow(elevation = 4.dp, shape = RoundedCornerShape(16.dp))                 .width(width = 120.dp)                 .fillMaxHeight(0.8f)                 .background(Color.White, RoundedCornerShape(16.dp)),             verticalArrangement = Arrangement.Center,             horizontalAlignment = Alignment.CenterHorizontally         ) {             Image(                 painter = painterResource(id = person.profile), contentDescription = null,                 modifier = Modifier                     .size(70.dp)                     .clip(CircleShape),                 contentScale = ContentScale.Crop             )             Spacer(modifier = Modifier.height(10.dp))             Text(                 text = person.name,                 fontSize = 18.sp,                 color = Color.Black,                 fontWeight = FontWeight.Bold             )         } }  LazyRow(     modifier = Modifier         .fillMaxHeight(0.3f)         .fillMaxWidth()         .background(Color.LightGray, shape = RoundedCornerShape(topEnd = 10.dp, topStart = 10.dp))         .padding(vertical = 10.dp)         .align(Alignment.BottomCenter),     verticalAlignment = Alignment.CenterVertically,     horizontalArrangement = Arrangement.Center ) {     items(items = persons) { person ->         PersonCard(person)     } }<\/code><\/pre>\n<h2>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u043b\u044f Drag and Drop<\/h2>\n<p>\u041f\u0435\u0440\u0435\u0434 \u0442\u0435\u043c \u043a\u0430\u043a \u043d\u0430\u0447\u043d\u0451\u043c, \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c:<\/p>\n<h4>Modifier.dragAndDropSource<\/h4>\n<p>\u042d\u0442\u043e\u0442 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c Drag and Drop.<\/p>\n<pre><code class=\"kotlin\">@Composable fun MyDraggableComponent() {     Box(         modifier = Modifier             .size(100.dp)             .background(Color.Blue)             .dragAndDropSource(                 drawDragDecoration = {                     \/\/ UI \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430                 }             ) {                 \/\/ \u043b\u043e\u0433\u0438\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 Drag and Drop                 startTransfer (\/* \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 *\/ )             }     ) { \/* \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 *\/ } }<\/code><\/pre>\n<ul>\n<li>\n<p><code>Modifier.dragAndDropSource<\/code>\u00a0\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u0432\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430:\u00a0<code>drawDragDecoration<\/code>\u00a0\u0438\u00a0<code>block<\/code>;<\/p>\n<\/li>\n<li>\n<p><code>drawDragDecoration<\/code> \u2014 \u044d\u0442\u043e \u043b\u044f\u043c\u0431\u0434\u0430 \u0431\u043b\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u0442\u0441\u044f Drag and Drop&#8217;\u043e\u043c;<\/p>\n<\/li>\n<li>\n<p><code>block<\/code>\u00a0\u044d\u0442\u043e \u043b\u044f\u043c\u0431\u0434\u0430 \u0431\u043b\u043e\u043a, \u043e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u00a0<code>DragAndDropSourceScope<\/code>\u00a0\u043a\u0430\u043a \u0440\u0435\u0441\u0438\u0432\u0435\u0440. \u041e\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c Drag and Drop \u0436\u0435\u0441\u0442 \u0438 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c;<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b\u0437\u043e\u0432\u00a0<code>startTransfer<\/code>\u00a0\u0432 \u043b\u044f\u043c\u0431\u0434\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 Drag and Drop \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u044d\u0442\u043e\u0442 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0430 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443 \u0435\u0434\u044b:<\/p>\n<p>\u0422\u0443\u0442,\u00a0<code>transferData<\/code>\u00a0\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 Drag and Drop. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438\u0437 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 \u0435\u0434\u044b \u0432 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0443 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430. <\/p>\n<pre><code class=\"kotlin\">private const val foodItemTransferAction = \"action_foodItem\" private const val foodItemTransferData = \"data_foofdItem\" ... startTransfer(     DragAndDropTransferData(         clipData = ClipData.newIntent(             \"foodItem\",             Intent(foodItemTransferAction).apply {                 putExtra(                     foodItemTransferData,                     Gson().toJson(foodItem)                 )             },         )     )<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 \u0435\u0434\u044b \u0441\u0442\u0430\u043b\u0430 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u043e\u0439.<\/p>\n<h2>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043c\u0435\u0441\u0442\u043e \u0434\u043b\u044f Drop and Drop<\/h2>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f \u0441\u043f\u0440\u0430\u0432\u043a\u0430 \u043f\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c:<\/p>\n<h4>Modifier.dragAndDropTarget<\/h4>\n<p>\u042d\u0442\u043e\u0442 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0432 Jetpack Compose \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 composable \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e\u0442 Drop and Drop.<\/p>\n<pre><code class=\"kotlin\">@Composable fun MyDragTarget() {     Box(         modifier = Modifier             .size(100.dp)             .background(Color.Green)             .dragAndDropTarget(                 shouldStartDragAndDrop = { startEvent-> return true },                 target =  object : DragAndDropTarget { ... }             )     ) { \/* \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 *\/ } }<\/code><\/pre>\n<p>\u041e\u043d \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u0432\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430:<\/p>\n<ol>\n<li>\n<p><code>shouldStartDragAndDrop<\/code>: \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 \u043d\u0443\u0436\u043d\u043e \u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u043e\u0442\u00a0<code>DragAndDropEvent<\/code>.<\/p>\n<\/li>\n<li>\n<p><code>target<\/code> \u2014\u00a0<code>DragAndDropTarget<\/code>\u00a0\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e\u0442 Drag and Drop:<\/p>\n<ol>\n<li>\n<p><code>onDrop(event)<\/code>: \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u043e\u0432\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0435\u043d \u0432\u043d\u0443\u0442\u0440\u044c\u00a0<code>DragAndDropTarget<\/code>. \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u00a0<code>true<\/code>\u00a0\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043e\u0442\u00a0<code>DragAndDropEvent<\/code>\u00a0\u0431\u044b\u043b\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043e, \u043d\u0430\u043f\u0440\u043e\u0442\u0438\u0432\u00a0<code>false<\/code>\u00a0\u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043e\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u043e;<\/p>\n<\/li>\n<li>\n<p><code>onStarted(event)<\/code>: \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 Drag and Drop \u0436\u0435\u0441\u0442. \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f\u00a0<code>DragAndDropTarget<\/code>\u00a0\u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u043a \u044d\u0442\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p><code>onEntered(event)<\/code>,\u00a0<code>onMoved(event)<\/code>,\u00a0<code>onExited(event)<\/code>: \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u043e\u0433\u0434\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f\/\u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438\u00a0<code>DragAndDropTarget<\/code>;<\/p>\n<\/li>\n<li>\n<p><code>onChanged(event)<\/code>: \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 Drag and Drop \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u00a0<code>DragAndDropTarget<\/code>\u00a0\u043e\u0431\u043b\u0430\u0441\u0442\u0438;<\/p>\n<\/li>\n<li>\n<p><code>onEnded(event)<\/code>: \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 Drag and Drop \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e. \u0412\u0441\u0435 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b\u00a0<code>DragAndDropTarget<\/code>\u00a0\u0432 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u043d\u0435\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0435\u00a0<code>onStarted<\/code>\u00a0\u043f\u043e\u043b\u0443\u0447\u0430\u0442 \u044d\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u0435, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f\u00a0<code>DragAndDropTarget<\/code>.<\/p>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 PersonCard \u2014 \u044d\u0442\u043e \u0446\u0435\u043b\u044c Drop, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u044d\u0442\u043e\u0442 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0435 PersonCard.<\/p>\n<pre><code class=\"kotlin\">fun PersonCard(person: Person) {     \/\/ \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u043a\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0435\u0434\u044b \u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430     val foodItems = remember { mutableStateMapOf&lt;Int, FoodItem>() }     Column(         modifier = Modifier              ....             .background(Color.White, RoundedCornerShape(16.dp))             .dragAndDropTarget(                 shouldStartDragAndDrop = { event ->                     \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0435\u0441\u043b\u0438 Drag and Drop \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u0435\u043a\u0441\u0442 intent mime \u0442\u0438\u043f\u0430                     event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_INTENT)                 },                 target = object : DragAndDropTarget {                     override fun onDrop(event: DragAndDropEvent): Boolean {                         \/\/ \u0434\u043e\u0441\u0442\u0430\u0435\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0435\u0434\u044b \u0438\u0437 Drag and Drop \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0433\u043e \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435                         val foodItem = event.toAndroidDragEvent().clipData.foodItem() ?: return false                         foodItems[foodItem.id] = foodItem                         return true                     }                 }             ),         verticalArrangement = Arrangement.Center,         horizontalAlignment = Alignment.CenterHorizontally     ) { \/\/ \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 PersonCard }  private fun ClipData.foodItem(): FoodItem? {     return (0 until itemCount)         .mapNotNull(::getItemAt).firstNotNullOfOrNull { item ->             item.intent?.getStringExtra(foodItemTransferData)?.takeIf { it.isNotEmpty() }         }?.let { Gson().fromJson(it, FoodItem::class.java) } }<\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438\u00a0<code>onDrop<\/code>\u00a0\u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043c\u044b \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0435\u0434\u044b Drag and Drop \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c\u00a0<code>foodItems<\/code>\u00a0\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0447\u0442\u043e\u0431\u044b \u0446\u0435\u043b\u044c Drop \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0430 \u0441\u0432\u043e\u0439 \u0446\u0432\u0435\u0442, \u043a\u043e\u0433\u0434\u0430 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0436\u0435\u043b\u0430\u0435\u043c\u043e\u0433\u043e Drag and Drop. \u041d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u043b\u0443\u0448\u0430\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f <code>onEntered<\/code>\u00a0\u0438\u00a0<code>onExited<\/code>.<\/p>\n<pre><code class=\"kotlin\">@OptIn(ExperimentalFoundationApi::class) @Composable fun PersonCard(person: Person) {    var bgColor by remember { mutableStateOf(Color.White) }      Column(         modifier = Modifier             ....             .background(bgColor, RoundedCornerShape(16.dp))             .dragAndDropTarget(                 shouldStartDragAndDrop = { event -> ... },                 target = object : DragAndDropTarget {                     override fun onDrop(event: DragAndDropEvent): Boolean {                          ...                         bgColor = Color.White                         return true                                           }                      override fun onEntered(event: DragAndDropEvent) {                         super.onEntered(event)                         bgColor = Color.Red                     }                      override fun onExited(event: DragAndDropEvent) {                         super.onExited(event)                         bgColor = Color.White                     }                  }             ),     ) { \/* \u043a\u0430\u0440\u0442\u043e\u0447\u043a\u0430 PersonCard *\/ }<\/code><\/pre>\n<blockquote>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438\u0437 \u0441\u0442\u0430\u0442\u044c\u0438 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0439\u0442\u0438 \u0432 Github \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u2014 <a href=\"https:\/\/github.com\/cp-radhika-s\/Drag_and_drop_jetpack_compose\/tree\/explore-modifier-drag-drop-source\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/cp-radhika-s\/Drag_and_drop_jetpack_compose\/tree\/explore-modifier-drag-drop-source<\/a><\/p>\n<\/blockquote>\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\/800389\/\"> https:\/\/habr.com\/ru\/articles\/800389\/<\/a><br \/><\/br><\/br><\/p>\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-370859","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/370859","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=370859"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/370859\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=370859"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=370859"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=370859"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}