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( painter = rememberVectorPainter(if (todoItem.isItemDone) AppIcons.CheckBox else AppIcons.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( painter = rememberVectorPainter(AppIcons.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, कॉम्पोनेंट की स्थिति को मैनेज करता है. आइटम के साथ इंटरैक्शन पूरा होने के बाद, यहconfirmValueChangeकॉलबैक को ट्रिगर करता है. कॉलबैक बॉडी, अलग-अलग संभावित कार्रवाइयों को मैनेज करती है. कॉलबैक, बूलियन वैल्यू दिखाता है. इससे कॉम्पोनेंट को पता चलता है कि उसे खारिज करने वाला ऐनिमेशन दिखाना चाहिए या नहीं. इस मामले में:- अगर आइटम को शुरू से आखिर तक स्वाइप किया जाता है, तो यह
onToggleDoneलैम्ब्डा को कॉल करता है और मौजूदाtodoItemको पास करता है. यह टास्क की सूची में मौजूद आइटम को अपडेट करने से जुड़ा है. - अगर आइटम को आखिर से शुरू की ओर स्वाइप किया जाता है, तो यह
onRemoveलैम्ब्डा को कॉल करता है और मौजूदाtodoItemको पास करता है. इसका मतलब है कि टास्क मिटा दिया गया है. it != StartToEnd: अगर स्वाइप करने की दिशाStartToEndनहीं है, तो यह लाइनtrueदिखाती है. अगर ऐसा नहीं है, तो यहfalseदिखाती है.falseको वापस करने से, "टॉगल हो गया" स्वाइप के बादSwipeToDismissBoxतुरंत गायब नहीं होता. इससे विज़ुअल की पुष्टि या ऐनिमेशन की अनुमति मिलती है.
- अगर आइटम को शुरू से आखिर तक स्वाइप किया जाता है, तो यह
SwipeToDismissBox, हर आइटम पर हॉरिज़ॉन्टल स्वाइप करने की सुविधा देता है. बाकी समय में, यह कॉम्पोनेंट का अंदरूनी कॉन्टेंट दिखाता है. हालांकि, जब कोई उपयोगकर्ता स्वाइप करना शुरू करता है, तो कॉन्टेंट हट जाता है औरbackgroundContentदिखता है. सामान्य कॉन्टेंट औरbackgroundContent, दोनों को पैरंट कंटेनर की सभी पाबंदियां मिलती हैं, ताकि वे खुद को रेंडर कर सकें.contentकोbackgroundContentके ऊपर ड्रॉ किया जाता है. इस मामले में:backgroundContentकोIconके तौर पर लागू किया गया है. इसका बैकग्राउंड कलर,SwipeToDismissBoxValueपर आधारित है:BlueजबStartToEndस्वाइप किया जाता है, तो टास्क की सूची में मौजूद किसी आइटम को टॉगल किया जाता है.EndToStartको स्वाइप करने परRed— टास्क मिटाया जा रहा है.Settledके लिए, बैकग्राउंड में कुछ नहीं दिखता — जब आइटम को स्वाइप नहीं किया जाता, तो बैकग्राउंड में कुछ नहीं दिखता.- इसी तरह, दिखने वाला
Icon, स्वाइप करने की दिशा के हिसाब से बदलता है: StartToEndमें, टास्क पूरा होने परCheckBoxआइकॉन और पूरा न होने परCheckBoxOutlineBlankआइकॉन दिखता है.EndToStartमेंDeleteआइकॉन दिखता है.
@Composable 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 यूज़र इंटरफ़ेस (यूआई) के उन हिस्सों को फिर से बनाता है जो इस सूची पर निर्भर करते हैं.mutableStateListOf()के अंदर, चारTodoItemऑब्जेक्ट को उनके ब्यौरे के साथ शुरू किया जाता है: "बिल भरें", "किराने का सामान खरीदें", "जिम जाएं", और "डिनर करें".
LazyColumnमें,todoItemsकी सूची वर्टिकल स्क्रोलिंग के साथ दिखती है.onToggleDone = { todoItem -> ... }एक कॉलबैक फ़ंक्शन है, जिसेTodoListItemसे तब शुरू किया जाता है, जब उपयोगकर्ता किसी ऑब्जेक्ट को 'हो गया' के तौर पर मार्क करता है. यहtodoItemकीisItemDoneप्रॉपर्टी को अपडेट करता है.todoItemsएकmutableStateListOfहै. इसलिए, इस बदलाव से रीकंपोज़िशन ट्रिगर होता है और यूज़र इंटरफ़ेस (यूआई) अपडेट होता है.onRemove = { todoItem -> ... }एक कॉलबैक फ़ंक्शन है. यह तब ट्रिगर होता है, जब उपयोगकर्ता आइटम को हटाता है. इससेtodoItemsसूची से, खासtodoItemहट जाता है. इससे रीकंपोज़िशन भी होता है और आइटम को दिखाई गई सूची से हटा दिया जाएगा.- हर
TodoListItemपर एकanimateItemमॉडिफ़ायर लागू किया जाता है, ताकि आइटम को खारिज करने पर मॉडिफ़ायर का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( painter = rememberVectorPainter(if (todoItem.isItemDone) AppIcons.CheckBox else AppIcons.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( painter = rememberVectorPainter(AppIcons.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 सोर्स फ़ाइल देखें.