يسمح المكوّن SwipeToDismissBox للمستخدم بإغلاق ملف شخصي أو تعديله
من خلال التمرير سريعًا لليسار أو اليمين.
واجهة برمجة التطبيقات
استخدِم العنصر القابل للتجميع 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حالة المكوّن. ويعمل هذا الإجراء على تنشيطconfirmValueChangecallback بعد الانتهاء من التفاعل مع العنصر. يعالج ملف الاستدعاء الإجراءات المختلفة المحتملة. يعرض الإجراء المُعاد برمجيًا قيمة برمجية تشكل تعبيرًا منطقيًا تحدّد للمكوّن ما إذا كان يجب عرض رسوم متحركة لإغلاق التطبيق. في هذه الحالة:- إذا تم التمرير سريعًا للعنصر من البداية إلى النهاية، يتم استدعاء دالة
onToggleDoneلامدا مع تمريرtodoItemالحالية. ويتوافق ذلك مع تعديل مادة المهام. - إذا تم التمرير سريعًا للعنصر من النهاية إلى البداية، يتمّ استدعاء دالة
onRemovelambda، مع تمريرtodoItemالحالية. ويؤدي ذلك إلى حذف مهمة جدول الأعمال. it != StartToEnd: يعرض هذا السطر القيمةtrueإذا لم يكن اتجاه التمرير هوStartToEnd، ويعرض القيمة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عناصر عند إضافة عنصر أو إزالته من هذه القائمة، يعيد تطبيق "الإنشاء" تركيب أجزاء واجهة المستخدم التي تعتمد عليه.- داخل
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 للحصول على نموذج الرمز البرمجي الكامل.