مولفه SwipeToDismissBox
به کاربر اجازه می دهد تا یک مورد را با کشیدن انگشت به چپ یا راست رد یا به روز کند.
سطح API
از SwipeToDismissBox
قابل ترکیب برای اجرای اقداماتی استفاده کنید که توسط حرکات کشیدن انگشت انجام می شوند. پارامترهای کلیدی عبارتند از:
-
state
: حالتSwipeToDismissBoxState
ایجاد شده برای ذخیره مقدار تولید شده توسط محاسبات در مورد تند کشیدن، که هنگام تولید رویدادها را تحریک می کند. -
backgroundContent
: یک ترکیب قابل تنظیم که در پشت محتوای آیتم نمایش داده می شود که با کشیدن محتوا آشکار می شود.
مثال اصلی: بهروزرسانی یا رد کردن با کشیدن انگشت
تکههای موجود در این مثال اجرای تند کشیدن را نشان میدهند که یا هنگام کشیدن مورد از ابتدا به انتها، آن را بهروزرسانی میکند، یا هنگامی که از ابتدا به ابتدا کشیده میشود، مورد را رد میکند.
data class TodoItem( val itemDescription: String, var isItemDone: Boolean = false )
@Composable fun TodoListItem( todoItem: TodoItem, onToggleDone: (TodoItem) -> Unit, onRemove: (TodoItem) -> Unit, modifier: Modifier = Modifier, ) { val swipeToDismissBoxState = rememberSwipeToDismissBoxState( confirmValueChange = { if (it == StartToEnd) onToggleDone(todoItem) else if (it == EndToStart) onRemove(todoItem) // Reset item when toggling done status it != StartToEnd } ) SwipeToDismissBox( state = swipeToDismissBoxState, modifier = modifier.fillMaxSize(), backgroundContent = { when (swipeToDismissBoxState.dismissDirection) { StartToEnd -> { Icon( if (todoItem.isItemDone) Icons.Default.CheckBox else Icons.Default.CheckBoxOutlineBlank, contentDescription = if (todoItem.isItemDone) "Done" else "Not done", modifier = Modifier .fillMaxSize() .background(Color.Blue) .wrapContentSize(Alignment.CenterStart) .padding(12.dp), tint = Color.White ) } EndToStart -> { Icon( imageVector = Icons.Default.Delete, contentDescription = "Remove item", modifier = Modifier .fillMaxSize() .background(Color.Red) .wrapContentSize(Alignment.CenterEnd) .padding(12.dp), tint = Color.White ) } Settled -> {} } } ) { ListItem( headlineContent = { Text(todoItem.itemDescription) }, supportingContent = { Text("swipe me to update or remove.") } ) } }
نکات کلیدی در مورد کد
-
swipeToDismissBoxState
وضعیت جزء را مدیریت می کند. هنگامی که تعامل با مورد انجام شد، callbackconfirmValueChange
فعال می کند. بدنه تماس با اعمال مختلف ممکن انجام می شود. callback یک بولی برمیگرداند که به مؤلفه میگوید که آیا باید انیمیشن رد کردن را نمایش دهد یا خیر. در این مورد:- اگر مورد از ابتدا تا انتها کشیده شود،
onToggleDone
lambda را فراخوانی میکند وtodoItem
فعلی را ارسال میکند. این با به روز رسانی مورد کار مطابقت دارد. - اگر مورد از پایان به شروع حرکت داده شود،
onRemove
lambda را فراخوانی میکند وtodoItem
فعلی را ارسال میکند. این با حذف مورد کار مطابقت دارد. -
it != StartToEnd
: این خط اگر جهت کش رفتنStartToEnd
نباشدtrue
برمی گرداند و در غیر این صورتfalse
. بازگشتfalse
از ناپدید شدن سریعSwipeToDismissBox
پس از کشیدن "تغییر انجام شد" جلوگیری می کند و امکان تایید تصویری یا انیمیشن را فراهم می کند.
- اگر مورد از ابتدا تا انتها کشیده شود،
-
SwipeToDismissBox
تعاملات کشیدن افقی روی هر مورد را فعال می کند. در حالت استراحت، محتوای داخلی مؤلفه را نشان میدهد، اما وقتی کاربر شروع به کشیدن انگشت میکند، محتوا دور میشود وbackgroundContent
ظاهر میشود. هم محتوای معمولی و هم محتوایbackgroundContent
محدودیتهای کامل محفظه والد را برای نمایش خود در اختیار دارند.content
در بالایbackgroundContent
ترسیم میشود. در این مورد:-
backgroundContent
به عنوان یکIcon
با رنگ پس زمینه بر اساسSwipeToDismissBoxValue
پیاده سازی می شود: -
Blue
هنگام کشیدنStartToEnd
- جابجایی یک مورد کار. -
Red
هنگام کشیدنEndToStart
- حذف یک مورد کار. - هیچ چیزی در پسزمینه برای
Settled
نمایش داده نمیشود — وقتی مورد در حال کشیدن نیست، چیزی در پسزمینه نمایش داده نمیشود. - به طور مشابه،
Icon
که نمایش داده می شود با جهت کشیدن تند تند تطبیق می یابد: -
StartToEnd
یک نمادCheckBox
را زمانی که مورد کار انجام می شود و یک نمادCheckBoxOutlineBlank
را هنگامی که انجام نشده است نشان می دهد. -
EndToStart
یک نمادDelete
را نمایش می دهد.
-
@Composable private fun SwipeItemExample() { val todoItems = remember { mutableStateListOf( TodoItem("Pay bills"), TodoItem("Buy groceries"), TodoItem("Go to gym"), TodoItem("Get dinner") ) } LazyColumn { items( items = todoItems, key = { it.itemDescription } ) { todoItem -> TodoListItem( todoItem = todoItem, onToggleDone = { todoItem -> todoItem.isItemDone = !todoItem.isItemDone }, onRemove = { todoItem -> todoItems -= todoItem }, modifier = Modifier.animateItem() ) } } }
نکات کلیدی در مورد کد
-
mutableStateListOf(...)
یک لیست قابل مشاهده ایجاد می کند که می تواند اشیاءTodoItem
در خود نگه دارد. هنگامی که یک مورد از این لیست اضافه یا حذف می شود، Compose قسمت هایی از UI را که به آن وابسته است دوباره ترکیب می کند.- در داخل
mutableStateListOf()
چهار شیTodoItem
با توضیحات مربوطه خود مقداردهی اولیه می شوند: «پرداخت قبوض»، «خرید مواد غذایی»، «رفتن به ورزشگاه» و «دریافت شام».
- در داخل
-
LazyColumn
یک لیست پیمایش عمودی ازtodoItems
نمایش می دهد. -
onToggleDone = { todoItem -> ... }
یک تابع فراخوانی است که از داخلTodoListItem
زمانی که کاربر یک شی را به عنوان انجام شده علامت گذاری می کند فراخوانی می شود. این ویژگیisItemDone
todoItem
را به روز می کند. از آنجایی کهtodoItems
یکmutableStateListOf
است، این تغییر باعث ایجاد یک ترکیب مجدد می شود و رابط کاربری را به روز می کند. -
onRemove = { todoItem -> ... }
یک تابع پاسخ به تماس است که وقتی کاربر مورد را حذف می کند فعال می شود. اینtodoItem
خاص را از لیستtodoItems
حذف می کند. این نیز باعث ترکیب مجدد می شود و مورد از لیست نمایش داده شده حذف می شود. - یک اصلاحکننده
animateItem
برای هرTodoListItem
اعمال میشود تا وقتی آیتم رد شد،placementSpec
تغییر دهنده فراخوانی شود. این کار حذف آیتم و همچنین ترتیب مجدد سایر موارد موجود در لیست را متحرک می کند.
نتیجه
ویدیوی زیر عملکرد اصلی تند کشیدن برای رد کردن قطعههای قبلی را نشان میدهد:
برای مشاهده کد نمونه کامل به فایل منبع GitHub مراجعه کنید.
مثال پیشرفته: رنگ پس زمینه را با کشیدن انگشت متحرک کنید
قطعههای زیر نشان میدهند که چگونه میتوان یک آستانه موقعیتی را برای متحرک کردن رنگ پسزمینه مورد در هنگام کشیدن تند اضافه کرد.
data class TodoItem( val itemDescription: String, var isItemDone: Boolean = false )
@Composable fun TodoListItemWithAnimation( todoItem: TodoItem, onToggleDone: (TodoItem) -> Unit, onRemove: (TodoItem) -> Unit, modifier: Modifier = Modifier, ) { val swipeToDismissBoxState = rememberSwipeToDismissBoxState( confirmValueChange = { if (it == StartToEnd) onToggleDone(todoItem) else if (it == EndToStart) onRemove(todoItem) // Reset item when toggling done status it != StartToEnd } ) SwipeToDismissBox( state = swipeToDismissBoxState, modifier = modifier.fillMaxSize(), backgroundContent = { when (swipeToDismissBoxState.dismissDirection) { StartToEnd -> { Icon( if (todoItem.isItemDone) Icons.Default.CheckBox else Icons.Default.CheckBoxOutlineBlank, contentDescription = if (todoItem.isItemDone) "Done" else "Not done", modifier = Modifier .fillMaxSize() .drawBehind { drawRect(lerp(Color.LightGray, Color.Blue, swipeToDismissBoxState.progress)) } .wrapContentSize(Alignment.CenterStart) .padding(12.dp), tint = Color.White ) } EndToStart -> { Icon( imageVector = Icons.Default.Delete, contentDescription = "Remove item", modifier = Modifier .fillMaxSize() .background(lerp(Color.LightGray, Color.Red, swipeToDismissBoxState.progress)) .wrapContentSize(Alignment.CenterEnd) .padding(12.dp), tint = Color.White ) } Settled -> {} } } ) { OutlinedCard(shape = RectangleShape) { ListItem( headlineContent = { Text(todoItem.itemDescription) }, supportingContent = { Text("swipe me to update or remove.") } ) } } }
نکات کلیدی در مورد کد
-
drawBehind
مستقیماً به داخل بوم پشت محتوایIcon
قابل ترکیب میکشد.-
drawRect()
یک مستطیل روی بوم می کشد و تمام محدوده های طراحی را باColor
مشخص شده پر می کند.
-
- هنگام کشیدن انگشت، رنگ پسزمینه مورد با استفاده از
lerp
به آرامی تغییر میکند.- برای کشیدن انگشت از
StartToEnd
، رنگ پسزمینه به تدریج از خاکستری روشن به آبی تغییر میکند. - برای کشیدن انگشت از
EndToStart
، رنگ پسزمینه به تدریج از خاکستری روشن به قرمز تغییر میکند. - میزان انتقال از یک رنگ به رنگ دیگر توسط
swipeToDismissBoxState.progress
تعیین می شود.
- برای کشیدن انگشت از
-
OutlinedCard
یک تفکیک بصری ظریف بین موارد لیست اضافه می کند.
@Composable private fun SwipeItemWithAnimationExample() { val todoItems = remember { mutableStateListOf( TodoItem("Pay bills"), TodoItem("Buy groceries"), TodoItem("Go to gym"), TodoItem("Get dinner") ) } LazyColumn { items( items = todoItems, key = { it.itemDescription } ) { todoItem -> TodoListItemWithAnimation( todoItem = todoItem, onToggleDone = { todoItem -> todoItem.isItemDone = !todoItem.isItemDone }, onRemove = { todoItem -> todoItems -= todoItem }, modifier = Modifier.animateItem() ) } } }
نکات کلیدی در مورد کد
- برای نکات کلیدی در مورد این کد، نکات کلیدی بخش قبلی را ببینید که یک قطعه کد یکسان را توضیح می دهد.
نتیجه
ویدیوی زیر عملکرد پیشرفته با رنگ پس زمینه متحرک را نشان می دهد:
برای مشاهده کد نمونه کامل به فایل منبع GitHub مراجعه کنید.