हाथ के जेस्चर के बारे में जानकारी

ऐसे कई शब्द और कॉन्सेप्ट हैं जिन्हें समझना ज़रूरी है ऐप्लिकेशन में जेस्चर हैंडलिंग पर काम करते समय. इस पेज पर शर्तों के बारे में बताया गया है पॉइंटर, पॉइंटर इवेंट, और जेस्चर का इस्तेमाल करके, अलग-अलग ऐब्स्ट्रैक्ट के बारे में जानकारी जेस्चर के लिए लेवल चुनें. इसमें इवेंट के इस्तेमाल और प्रचार होता है.

परिभाषाएं

इस पेज पर दिए गए अलग-अलग कॉन्सेप्ट को समझने के लिए, आपको का हिस्सा हैं:

  • पॉइंटर: एक फ़िज़िकल ऑब्जेक्ट जिसका इस्तेमाल अपने ऐप्लिकेशन के साथ इंटरैक्ट करने के लिए किया जा सकता है. मोबाइल डिवाइसों के लिए, आपकी उंगली सबसे सामान्य पॉइंटर के साथ इंटरैक्ट करती है टच स्क्रीन. इसके अलावा, उंगली के बदले स्टाइलस का भी इस्तेमाल किया जा सकता है. बड़ी स्क्रीन के लिए, माउस या ट्रैकपैड का इस्तेमाल करके, किसी दूसरे तरह के डिवाइस से इंटरैक्ट किया जा सकता है डिसप्ले. इनपुट डिवाइस "पॉइंट" करने में सक्षम होना चाहिए निर्देशांक पर होने के लिए को पॉइंटर माना जाता है, इसलिए उदाहरण के लिए, कीबोर्ड को पॉइंटर. लिखें में, पॉइंटर प्रकार को इसका उपयोग करके पॉइंटर बदलावों में शामिल किया जाता है PointerType.
  • पॉइंटर इवेंट: एक या उससे ज़्यादा पॉइंटर के लो-लेवल इंटरैक्शन की जानकारी देता है किसी तय समय पर आवेदन करें. कोई भी पॉइंटर इंटरैक्शन, जैसे कि स्क्रीन पर उंगली रखने या माउस को खींचने से कोई इवेंट ट्रिगर होगा. तय सीमा में लिखें, तो ऐसे इवेंट से संबंधित सभी प्रासंगिक जानकारी PointerEvent क्लास.
  • जेस्चर: पॉइंटर इवेंट का क्रम, जिसे एक ही माना जा सकता है कार्रवाई. उदाहरण के लिए, टैप जेस्चर को नीचे का क्रम माना जा सकता है इवेंट और उसके बाद कोई अप इवेंट. हाथ के कुछ ऐसे सामान्य जेस्चर (हाव-भाव) हैं जिन्हें ज़्यादातर लोग इस्तेमाल करते हैं जैसे ऐप्लिकेशन, जैसे कि टैप करना, ड्रैग करना या पूरी तरह बदलना, लेकिन अपनी पसंद के मुताबिक हाथ के जेस्चर का इस्तेमाल करें.

ऐब्स्ट्रैक्टेशन के अलग-अलग लेवल

Jetpack Compose में जेस्चर को हैंडल करने के लिए अलग-अलग लेवल का ऐब्स्ट्रैक्ट दिया गया है. सबसे ऊपर वाले लेवल पर, कॉम्पोनेंट के लिए सहायता दिखती है. Button जैसे कंपोज़ेबल जेस्चर सहायता को अपने-आप शामिल कर लिया जाता है. कस्टम में जेस्चर से जुड़ी सहायता जोड़ने के लिए कॉम्पोनेंट, किसी भी कॉम्पोनेंट में जेस्चर मॉडिफ़ायर, जैसे कि clickable जोड़ने का विकल्प होता है. कंपोज़ेबल. आखिर में, अगर आपको हाथ के जेस्चर की ज़रूरत है, तो pointerInput मॉडिफ़ायर.

एक नियम के तौर पर, ऐब्स्ट्रैक्ट के सबसे ऊंचे स्तर पर बनाएं जो और आपके काम का है. इस तरह, आपको इन सबसे सही तरीकों का फ़ायदा मिलता है लेयर में. उदाहरण के लिए, Button में ज़्यादा सिमैंटिक जानकारी है, जिसका इस्तेमाल इनके लिए किया जाता है clickable के मुकाबले सुलभता, जिसमें रॉ के मुकाबले ज़्यादा जानकारी होती है pointerInput लागू किया गया.

कॉम्पोनेंट के लिए सहायता

Compose में मौजूद कई मुख्य कॉम्पोनेंट में इंटरनल जेस्चर शामिल होते हैं हैंडलिंग. उदाहरण के लिए, LazyColumn हाथ के जेस्चर को खींचकर, उसके हिसाब से जवाब देता है कॉन्टेंट को स्क्रोल करते समय, Button को दबाने पर रिपल दिखती है. और SwipeToDismiss कॉम्पोनेंट में एलिमेंट. इस तरह के जेस्चर अपने-आप काम करते हैं.

अंदरूनी जेस्चर हैंडलिंग के आगे, कई कॉम्पोनेंट के लिए कॉलर को हाथ के जेस्चर का इस्तेमाल करें. उदाहरण के लिए, Button, टैप का पता अपने-आप लगाता है और कोई क्लिक इवेंट ट्रिगर करता हो. आपने onClick लैम्डा को Button को पास किया है, ताकि हाथ के जेस्चर पर प्रतिक्रिया दें. इसी तरह, आप एक onValueChange lambda को स्लाइडर हैंडल को खींचकर छोड़ने वाले उपयोगकर्ता की प्रतिक्रिया देने के लिए Slider.

जब यह आपके इस्तेमाल के हिसाब से सही हो, तो कॉम्पोनेंट में शामिल किए गए जेस्चर को प्राथमिकता दें, क्योंकि वे फ़ोकस और सुलभता के लिए आउट-ऑफ़-द-बॉक्स सपोर्ट शामिल करना चाहिए और अच्छी तरह से जांचा-परखा गया. उदाहरण के लिए, Button को खास तरीके से मार्क किया जाता है, ताकि सुलभता सेवाएं इसे एक बटन के तौर पर सही तरीके से पेश करती हैं क्लिक किया जा सकने वाला एलिमेंट:

// Talkback: "Click me!, Button, double tap to activate"
Button(onClick = { /* TODO */ }) { Text("Click me!") }
// Talkback: "Click me!, double tap to activate"
Box(Modifier.clickable { /* TODO */ }) { Text("Click me!") }

Compose में सुलभता सुविधाओं के बारे में ज़्यादा जानने के लिए, इस सुविधा में मौजूद सुलभता सुविधाओं को देखें लिखें.

मॉडिफ़ायर की मदद से आर्बिट्रेरी कंपोज़ेबल में खास जेस्चर को जोड़ना

किसी भी कंपोज़ेबल में जेस्चर मॉडिफ़ायर का इस्तेमाल करके, हाथ के जेस्चर को सुनने के लिए कंपोज़ेबल. उदाहरण के लिए, सामान्य Box इससे टैप जेस्चर को हैंडल करके, clickable बनाएं या Column verticalScroll को लागू करके, वर्टिकल स्क्रोल को मैनेज करें.

अलग-अलग तरह के जेस्चर के लिए, कई मॉडिफ़ायर मौजूद हैं:

नियम के तौर पर, हाथ के जेस्चर हैंडल करने के बजाय, सबसे बड़े जेस्चर मॉडिफ़ायर को प्राथमिकता दें. मॉडिफ़ायर, पॉइंटर इवेंट को हैंडल करने के बाद ज़्यादा सुविधाएं जोड़ता है. उदाहरण के लिए, clickable मॉडिफ़ायर, न सिर्फ़ दबाव की पहचान करता है और टैप करने के अलावा, अन्य जानकारी और इंटरैक्शन के लिए विज़ुअल संकेत भी जोड़े जाते हैं. कर्सर घुमाना, फ़ोकस करना, और कीबोर्ड की सुविधा. सोर्स कोड की जांच के लिए, सोर्स कोड की जांच की जा सकती है clickable का इस्तेमाल करके देखें कि कैसे जोड़ा जा रहा है.

pointerInput मॉडिफ़ायर की मदद से, आर्बिट्रेरी कंपोज़ेबल में कस्टम जेस्चर जोड़ें

हर जेस्चर को खास तरह के जेस्चर के साथ लागू नहीं किया जाता है. इसके लिए उदाहरण के लिए, देर तक दबाने के बाद खींचे जाने पर प्रतिक्रिया देने के लिए, कार्रवाई बदलने वाली कुंजी का इस्तेमाल नहीं किया जा सकता, कंट्रोल-क्लिक या तीन उंगलियों से टैप करें. इसके बजाय, अपने हिसाब से हाथ का जेस्चर लिखा जा सकता है हैंडलर का इस्तेमाल करें. जेस्चर हैंडलर बनाया जा सकता है pointerInput मॉडिफ़ायर, जो आपको रॉ पॉइंटर का ऐक्सेस देता है इवेंट.

यह कोड, रॉ पॉइंटर इवेंट को सुनता है:

@Composable
private fun LogPointerEvents(filter: PointerEventType? = null) {
    var log by remember { mutableStateOf("") }
    Column {
        Text(log)
        Box(
            Modifier
                .size(100.dp)
                .background(Color.Red)
                .pointerInput(filter) {
                    awaitPointerEventScope {
                        while (true) {
                            val event = awaitPointerEvent()
                            // handle pointer event
                            if (filter == null || event.type == filter) {
                                log = "${event.type}, ${event.changes.first().position}"
                            }
                        }
                    }
                }
        )
    }
}

अगर इस स्निपेट को अलग-अलग हिस्सों में बांटा जाता है, तो इसके मुख्य कॉम्पोनेंट ये हैं:

  • pointerInput मॉडिफ़ायर. इसका मतलब है कि आपने उसे एक या एक से ज़्यादा बटन पास किया है. जब उनमें से किसी एक कुंजी का मान बदल जाता है, तो संशोधक सामग्री lambda यह है फिर से लागू किया गया. यह सैंपल, कंपोज़ेबल में एक वैकल्पिक फ़िल्टर पास करता है. अगर आपने उस फ़िल्टर का मान बदलता है, तो पॉइंटर इवेंट हैंडलर यह होना चाहिए फिर से लागू किया जाता है, ताकि यह पक्का किया जा सके कि सही इवेंट लॉग किए गए हैं.
  • awaitPointerEventScope एक कोरूटीन स्कोप बनाता है. इसका इस्तेमाल इन कामों के लिए किया जा सकता है पॉइंटर इवेंट की इंतज़ार करें.
  • awaitPointerEvent, अगले पॉइंटर इवेंट तक कोरूटीन को निलंबित करता है होता है.

वैसे तो रॉ इनपुट इवेंट को सुनना फ़ायदेमंद होता है, लेकिन लिखना भी मुश्किल है इस रॉ डेटा के आधार पर कस्टम जेस्चर को बनाया जा सकता है. कस्टम रिपोर्ट बनाने की प्रोसेस को आसान बनाने के लिए के लिए, कई उपयोगी तरीके उपलब्ध हैं.

हाथ के सभी जेस्चर का पता लगाएं

रॉ पॉइंटर इवेंट को हैंडल करने के बजाय, खास जेस्चर को ध्यान से सुना जा सकता है ताकि उन पर कार्रवाई की जा सके. AwaitPointerEventScope उपलब्ध कराता है इसे सुनने के तरीके:

ये टॉप लेवल डिटेक्टर हैं, इसलिए एक में कई डिटेक्टर नहीं जोड़े जा सकते pointerInput मॉडिफ़ायर. नीचे दिया गया स्निपेट सिर्फ़ टैप का पता लगाता है, न कि खींचें:

var log by remember { mutableStateOf("") }
Column {
    Text(log)
    Box(
        Modifier
            .size(100.dp)
            .background(Color.Red)
            .pointerInput(Unit) {
                detectTapGestures { log = "Tap!" }
                // Never reached
                detectDragGestures { _, _ -> log = "Dragging" }
            }
    )
}

अंदरूनी तौर पर, detectTapGestures तरीका कोरूटीन को ब्लॉक करता है. साथ ही, दूसरा तरीका डिटेक्टर कभी ऐक्सेस नहीं किया जा सका. अगर आपको एक से ज़्यादा जेस्चर लिसनर जोड़ने की ज़रूरत है, तो एक कंपोज़ेबल, इसके बजाय अलग-अलग pointerInput मॉडिफ़ायर इंस्टेंस का इस्तेमाल करें:

var log by remember { mutableStateOf("") }
Column {
    Text(log)
    Box(
        Modifier
            .size(100.dp)
            .background(Color.Red)
            .pointerInput(Unit) {
                detectTapGestures { log = "Tap!" }
            }
            .pointerInput(Unit) {
                // These drag events will correctly be triggered
                detectDragGestures { _, _ -> log = "Dragging" }
            }
    )
}

हाथ के हर जेस्चर के हिसाब से इवेंट मैनेज करना

परिभाषा के मुताबिक, हाथ के जेस्चर, पॉइंटर डाउन इवेंट से शुरू होते हैं. Google आपके यूआरएल पैरामीटर को कैसे इस्तेमाल करेगा, यह तय करने के लिए while(true) लूप के बजाय, awaitEachGesture हेल्पर तरीका हर रॉ इवेंट से गुज़रता है. awaitEachGesture तरीका रीस्टार्ट होने पर जब सभी पॉइंटर हटा दिए जाते हैं, तब ब्लॉक शामिल होता है, जो दिखाता है कि जेस्चर यह है पूरा हुआ:

@Composable
private fun SimpleClickable(onClick: () -> Unit) {
    Box(
        Modifier
            .size(100.dp)
            .pointerInput(onClick) {
                awaitEachGesture {
                    awaitFirstDown().also { it.consume() }
                    val up = waitForUpOrCancellation()
                    if (up != null) {
                        up.consume()
                        onClick()
                    }
                }
            }
    )
}

व्यावहारिक तौर पर, आप आम तौर पर awaitEachGesture का इस्तेमाल करना तब तक पसंद करते हैं, जब तक आप जेस्चर की पहचान किए बिना, पॉइंटर इवेंट पर प्रतिक्रिया देता हो. इसका एक उदाहरण यह है hoverable, जो पॉइंटर डाउन या अप इवेंट का जवाब नहीं देता—सिर्फ़ यह जानने की ज़रूरत है कि कोई पॉइंटर कब अपने दायरे में आता है या उससे बाहर निकल जाता है.

किसी खास इवेंट या सब-हाथ के जेस्चर (हाव-भाव) का इंतज़ार करना

यहां ऐसे तरीकों का एक सेट दिया गया है जो हाथ के जेस्चर के सामान्य हिस्सों की पहचान करने में मदद करते हैं:

  • पॉइंटर के awaitFirstDown के नीचे जाने तक निलंबित करें या सभी के लिए इंतज़ार करें waitForUpOrCancellation तक जाने के लिए पॉइंटर हैं.
  • awaitTouchSlopOrCancellation का इस्तेमाल करके, ड्रैग लिसनर बनाएं और awaitDragOrCancellation. जेस्चर हैंडलर तब तक निलंबित रहता है, जब तक पॉइंटर टच स्लोप तक पहुंचता है और फिर पहले ड्रैग इवेंट तक निलंबित हो जाता है आता है. अगर आपको सिर्फ़ एक ऐक्सिस पर खींचना है, तो इसका इस्तेमाल करें awaitHorizontalTouchSlopOrCancellation से ज़्यादा awaitHorizontalDragOrCancellation या awaitVerticalTouchSlopOrCancellation प्लस इसके बजाय awaitVerticalDragOrCancellation.
  • awaitLongPressOrCancellation का इस्तेमाल करने पर, खाते को लंबे समय तक दबाकर रखने पर रोक लगाएं.
  • ड्रैग इवेंट को लगातार सुनने के लिए, drag तरीके का इस्तेमाल करें या किसी एक पर खींचें और छोड़ें इवेंट को सुनने के लिए horizontalDrag या verticalDrag ऐक्सिस.

मल्टी-टच इवेंट के लिए कैलकुलेशन की सुविधा लागू करना

जब कोई उपयोगकर्ता एक से ज़्यादा पॉइंटर का इस्तेमाल करके, मल्टी-टच जेस्चर का इस्तेमाल करता है, रॉ वैल्यू के आधार पर, ज़रूरी बदलाव को समझना मुश्किल है. अगर transformable मॉडिफ़ायर या detectTransformGestures के तरीके से आपके इस्तेमाल के उदाहरण के लिए, बेहतर कंट्रोल नहीं मिल रहा है. रॉ इवेंट को सुनें और उनका हिसाब लगाएं. ये सहायक तरीके हैं calculateCentroid, calculateCentroidSize, calculatePan, calculateRotation, और calculateZoom.

इवेंट की जानकारी भेजना और हिट-टेस्टिंग

हर pointerInput मॉडिफ़ायर को हर पॉइंटर इवेंट नहीं भेजा जाता. इवेंट डिस्पैच करने की प्रोसेस इस तरह से काम करती है:

  • पॉइंटर इवेंट, कंपोज़ेबल हैरारकी में भेजे जाते हैं. ऐसे समय में नया पॉइंटर अपना पहला पॉइंटर इवेंट ट्रिगर करता है, सिस्टम हिट-टेस्टिंग शुरू करता है "मंज़ूरी दी गई" कंपोज़ेबल. कंपोज़ेबल को तब मंज़ूरी मिलती है, जब उसके पास पॉइंटर इनपुट हैंडलिंग की क्षमताएं. यूज़र इंटरफ़ेस में सबसे ऊपर से हिट-टेस्टिंग फ़्लो पेड़ से नीचे तक. कंपोज़ेबल "हिट" है पॉइंटर इवेंट कब हुआ उन कंपोज़ेबल की सीमाओं में शामिल किया जा सकता है. इस प्रक्रिया के कारण एक ऐसी ऐसे कंपोज़ेबल जो लगातार लोकप्रिय हो रहे हैं.
  • डिफ़ॉल्ट रूप से, जब एक ही लेवल पर कई योग्य कंपोज़ेबल पेड़ ही, सबसे ज़्यादा z-इंडेक्स वाला कंपोज़ेबल "हिट" होता है. इसके लिए उदाहरण के लिए, जब Box में ओवरलैप करने वाले दो Button कंपोज़ेबल जोड़े जाते हैं, तो सिर्फ़ सबसे ऊपर बनाई गई इमेज को कोई भी पॉइंटर इवेंट मिलता है. सैद्धांतिक तौर पर अपना PointerInputModifierNode बनाकर इस व्यवहार को बदलें लागू करें और sharePointerInputWithSiblings को 'सही' पर सेट करें.
  • एक ही पॉइंटर के लिए आगे के इवेंट की उसी शृंखला में भेजे जाते हैं कंपोज़ेबल और इवेंट प्रोपगेशन लॉजिक के हिसाब से फ़्लो. सिस्टम इस पॉइंटर के लिए अब और हिट-टेस्टिंग नहीं करता. इसका मतलब है कि हर चेन में कंपोज़ेबल को उस पॉइंटर के लिए सभी इवेंट मिलते हैं, भले ही वे कंपोज़ेबल की सीमाओं से बाहर होते हैं. ऐसे कंपोज़ेबल जो चेन में कभी भी पॉइंटर इवेंट नहीं मिलते, तब भी नहीं, जब पॉइंटर सीमाओं से बाहर रखा जा सकता है.

जिन इवेंट को माउस या स्टाइलस के कर्सर घुमाने से ट्रिगर किया जाता है वे इवेंट के अपवाद हैं नियमों को यहां परिभाषित किया गया है. होवर इवेंट, उन सभी कंपोज़ेबल को भेजे जाते हैं जिन पर वे हिट करते हैं. तो जब कोई उपयोगकर्ता, एक कंपोज़ेबल से अगले पॉइंटर पर कर्सर घुमाता है, उस पहले कंपोज़ेबल को इवेंट भेजने के बजाय, इवेंट को नए कंपोज़ेबल.

इवेंट देखने का मकसद

जब एक से ज़्यादा कंपोज़ेबल को जेस्चर हैंडलर असाइन किए जाते हैं, हैंडलर में एक ही नाम या ब्रैंड शामिल नहीं होना चाहिए. उदाहरण के लिए, इस यूज़र इंटरफ़ेस (यूआई) पर एक नज़र डालें:

सूची में एक इमेज, दो टेक्स्ट वाला कॉलम, और एक बटन है.

जब कोई उपयोगकर्ता बुकमार्क बटन पर टैप करता है, तो बटन का onClick lambda इसे हैंडल करता है हाथ के जेस्चर. जब कोई उपयोगकर्ता सूची आइटम के किसी अन्य हिस्से पर टैप करता है, तो ListItem उस जेस्चर को हैंडल करके, लेख पर ले जाता है. पॉइंटर इनपुट के रूप में, बटन को इस इवेंट का इस्तेमाल करना चाहिए, ताकि उसके पैरंट को पता हो कि ऐसा नहीं करना है उस पर ज़्यादा प्रतिक्रिया नहीं देनी चाहिए. अलग-अलग चीज़ों के साथ मिलने वाले हाथ के जेस्चर और आम जेस्चर मॉडिफ़ायर में, इस्तेमाल के इस तरीके को शामिल किया जाता है. हालांकि, अगर लिखने के लिए, आपको इवेंट मैन्युअल तरीके से इस्तेमाल करने होंगे. आपने यह कर लिया इसका इस्तेमाल करके, PointerInputChange.consume यह तरीका अपनाया जा सकता है:

Modifier.pointerInput(Unit) {

    awaitEachGesture {
        while (true) {
            val event = awaitPointerEvent()
            // consume all changes
            event.changes.forEach { it.consume() }
        }
    }
}

किसी इवेंट का इस्तेमाल करने से, अन्य कंपोज़ेबल में इवेंट का प्रमोशन नहीं रुकता. ऐप्लिकेशन इसके बजाय, कंपोज़ेबल को इस्तेमाल किए गए इवेंट को अनदेखा करना चाहिए. लिखते समय इस्तेमाल करने के लिए, आपको यह देखना चाहिए कि किसी इवेंट को पहले ही किसी अन्य उपयोगकर्ता ने देख लिया है या नहीं एलिमेंट:

Modifier.pointerInput(Unit) {
    awaitEachGesture {
        while (true) {
            val event = awaitPointerEvent()
            if (event.changes.any { it.isConsumed }) {
                // A pointer is consumed by another gesture handler
            } else {
                // Handle unconsumed event
            }
        }
    }
}

इवेंट का प्रमोशन

जैसा कि पहले बताया गया है, पॉइंटर में होने वाले बदलाव, हर उस कंपोज़ेबल को भेजे जाते हैं जिस पर यह हिट होता है. हालांकि, अगर एक से ज़्यादा कंपोज़ेबल मौजूद हैं, तो इवेंट किस क्रम में प्रचार करें? अगर आप पिछले सेक्शन से उदाहरण लेते हैं, तो इस यूज़र इंटरफ़ेस (यूआई) का अनुवाद यह यूज़र इंटरफ़ेस (यूआई) ट्री है, जहां सिर्फ़ ListItem और Button पॉइंटर इवेंट:

पेड़ की बनावट. सबसे ऊपर की लेयर ListItem है, दूसरी लेयर में इमेज, कॉलम, और बटन है, और कॉलम को दो टेक्स्ट में बांटा गया है. ListItem और बटन हाइलाइट किए गए हैं.

पॉइंटर इवेंट, इन कंपोज़ेबल में से हर तीन कंपोज़ेबल से, तीन बार तक प्रोसेस होते हैं "पास":

  • शुरुआती पास में, इवेंट, यूज़र इंटरफ़ेस (यूआई) ट्री के ऊपर से नीचे. इस फ़्लो की मदद से, माता-पिता किसी इवेंट को देखने से पहले ही उसे रोक सकते हैं उसका उपयोग करें. उदाहरण के लिए, टूलटिप को दबाकर रखें. हमारे उदाहरण के लिए, ListItem को Button से पहले इवेंट मिलता है.
  • मुख्य पास में, इवेंट यूज़र इंटरफ़ेस (यूआई) ट्री के लीफ़ नोड से यूज़र इंटरफ़ेस ट्री का रूट डालें. आम तौर पर, इसी दौरान हाथ के जेस्चर का इस्तेमाल किया जाता है. यह इवेंट सुनते समय डिफ़ॉल्ट पास की जानकारी देता है. इस पास में हाथ के जेस्चर का इस्तेमाल करना इसका मतलब है कि लीफ़ नोड को उनके पैरंट के मुकाबले प्राथमिकता दी जाती है, यानी कि लीफ़ नोड को प्राथमिकता दी जाती है अधिकांश जेस्चर के लिए, सबसे तार्किक व्यवहार. हमारे उदाहरण में, Button को ListItem से पहले वाला इवेंट.
  • फ़ाइनल पास में, इवेंट, यूज़र इंटरफ़ेस (यूआई) में सबसे ऊपर से एक बार और फ़्लो करता है पेड़ से लीफ़ नोड तक इस फ़्लो की मदद से, स्टैक में ऊपर मौजूद एलिमेंट को इवेंट के इस्तेमाल के बारे में उनके माता-पिता की ओर से जवाब दिया जा सकता है. उदाहरण के लिए, बटन हटाता है इसका रिपल संकेत तब दिखता है, जब कोई प्रेस स्क्रोल करके, स्क्रोल किए जा सकने वाले पैरंट बटन में बदल जाती है.

विज़ुअल तौर पर, इवेंट फ़्लो को इस तरह से दिखाया जा सकता है:

इनपुट में किए गए बदलाव का इस्तेमाल करने के बाद, यह जानकारी उस रिपोर्ट से भेजी जाती है इन पॉइंट को शामिल करें:

कोड में, उस पास के बारे में बताया जा सकता है जिसमें आपकी दिलचस्पी है:

Modifier.pointerInput(Unit) {
    awaitPointerEventScope {
        val eventOnInitialPass = awaitPointerEvent(PointerEventPass.Initial)
        val eventOnMainPass = awaitPointerEvent(PointerEventPass.Main) // default
        val eventOnFinalPass = awaitPointerEvent(PointerEventPass.Final)
    }
}

इस कोड स्निपेट में, इनमें से हर एक ने एक जैसा इवेंट दिखाया है ये तरीक़ों के लिए ज़िम्मेदार होते हैं. हालांकि, नेटवर्क के इस्तेमाल से जुड़ा डेटा बदल दिया गया है.

हाथ के जेस्चर की जांच करें

जांच के तरीकों में, पॉइंटर इवेंट को मैन्युअल तौर पर भेजने के लिए, performTouchInput तरीका. इससे आपको ऊपरी लेवल में से कोई भी एक काम करने में मदद मिलती है हाथ के सभी जेस्चर (जैसे, पिंच करना या देर तक क्लिक करना) या कम लेवल के जेस्चर (जैसे कि कर्सर को पिक्सल की तय संख्या से आगे बढ़ाने के लिए):

composeTestRule.onNodeWithTag("MyList").performTouchInput {
    swipeUp()
    swipeDown()
    click()
}

ज़्यादा उदाहरणों के लिए, performTouchInput दस्तावेज़ देखें.

ज़्यादा जानें

Jetpack Compose में हाथ के जेस्चर के बारे में ज़्यादा जानने के लिए, यहां दिए गए लिंक देखें संसाधन:

{% endverba नया %} {% verbatim %}