Wear OS 7 (एपीआई लेवल 37) और इसके बाद के वर्शन में, एक हाथ से किए जाने वाले जेस्चर का फ़्रेमवर्क उपलब्ध है. साथ ही, Compose for Wear OS का हिस्सा होने वाला एक एपीआई भी उपलब्ध है. इनकी मदद से, उपयोगकर्ता बिना छुए आपके ऐप्लिकेशन के साथ इंटरैक्ट कर सकते हैं.
शुरुआत में, यह सुविधा Pixel Watch डिवाइसों (Pixel Watch 3 और इसके बाद के वर्शन) पर उपलब्ध थी. हालांकि, अब यह फ़्रेमवर्क सभी ओईएम के लिए उपलब्ध है. इस एपीआई को अपनाने से, आपके ऐप्लिकेशन में जेस्चर की सुविधा अपने-आप काम करने लगती है. साथ ही, हार्डवेयर की सुविधा बढ़ने के साथ-साथ, यह सुविधा पूरे नेटवर्क में काम करती है.
उपयोगकर्ताओं को यूज़र इंटरफ़ेस (यूआई) को बिना किसी रुकावट के इस्तेमाल करने की सुविधा देने के लिए, Wear OS फ़्रेमवर्क में ऐनिमेशन वाले जेस्चर इंडिकेटर उपलब्ध होते हैं. इनकी मदद से, उपयोगकर्ता उपलब्ध जेस्चर के बारे में जान पाते हैं. इन विज़ुअल हिंट से पता चलता है कि किस जगह पर जेस्चर किया जा सकता है. वहीं, सिस्टम उपयोगकर्ता की प्राथमिकताओं के हिसाब से, इन विज़ुअल हिंट के दिखने की फ़्रीक्वेंसी और म्यूट होने की फ़्रीक्वेंसी को अपने-आप मैनेज करता है.
इस्तेमाल किए जा सकने वाले जेस्चर और कार्रवाइयां
Wear OS के जेस्चर फ़्रेमवर्क में, दो तरह के जेस्चर इस्तेमाल किए जा सकते हैं:
- मुख्य कार्रवाई (दो उंगलियों से पिंच करना): यह स्क्रीन पर की जाने वाली मुख्य कार्रवाई से मैप होता है. जैसे, कॉल का जवाब देना या मीडिया चलाने की सुविधा को टॉगल करना.
- खारिज करने की कार्रवाई (कलाई घुमाएं): इससे पीछे की ओर नेविगेट किया जा सकता है, डायलॉग बॉक्स को खारिज किया जा सकता है या किसी प्रॉम्प्ट को रद्द किया जा सकता है.
Compose में जेस्चर कॉन्फ़िगर करना
एक हाथ से किए जाने वाले जेस्चर के लिए उपलब्ध एपीआई, आपके यूज़र इंटरफ़ेस (यूआई) को बेहतर बना सकता है. हालांकि, यह ध्यान रखना ज़रूरी है कि कुछ हार्डवेयर और ओईएम, इन जेस्चर के साथ काम नहीं करते. अगर एपीआई को पता चलता है कि आपका ऐप्लिकेशन, इन डिवाइसों में से किसी एक पर चल रहा है, तो लाइब्रेरी अपने-आप काम करना बंद कर देती है. हालांकि, इससे टच के स्टैंडर्ड इंटरैक्शन पर कोई असर नहीं पड़ता.
Compose के स्टैंडर्ड व्यवहारों की तरह ही, यूज़र इंटरफ़ेस (यूआई) एलिमेंट पर एक हाथ से इस्तेमाल करने के लिए जेस्चर की सुविधा चालू की जा सकती है. इसके लिए, मॉडिफ़ायर का इस्तेमाल करें. आपको अपने ऐप्लिकेशन के जेस्चर को, किए जाने वाले ऐक्शन के हिसाब से कॉन्फ़िगर करना होता है. जैसे, प्राइमरी या खारिज करना. साथ ही, सिस्टम-लेवल पर उपयोगकर्ता की प्राथमिकताओं के साथ तालमेल बिठाने के लिए gestureId. जैसे, हिंट दिखाने की कैडेंस और फ़्रीक्वेंसी म्यूट करना. इस कॉन्फ़िगरेशन को OneHandedGestureConfiguration ऑब्जेक्ट बनाकर दिखाया जाता है. हमारा सुझाव है कि इसे बनाने के लिए, rememberOneHandedGestureConfiguration फ़ंक्शन का इस्तेमाल करें. OneHandedGestureConfiguration में, जेस्चर को प्राथमिकता देने का विकल्प भी होता है.
rememberOneHandedGestureConfiguration फ़ंक्शन, ऐप्लिकेशन की स्थिति को दिखाए बिना, फिर से कंपोज़ किए जाने पर उपयोगकर्ता के इंटरैक्शन के इतिहास को ट्रैक करता है. जब आपका ऐप्लिकेशन कॉन्फ़िगरेशन बना लेता है, तो उसे अपने इंटरैक्टिव कंपोज़ेबल पर Modifier.oneHandedGesture को कॉन्फ़िगरेशन पास करना चाहिए.
उपयोगकर्ताओं को उपलब्ध जेस्चर ढूंढने में मदद करने के लिए, लाइब्रेरी OneHandedGestureClickIndicator तरीका उपलब्ध कराती है. यह तरीका एक रैपर के तौर पर काम करता है. यह अपने मूल कॉन्टेंट को बदलकर, उपयोगकर्ता को यह बताता है कि जेस्चर वाली कार्रवाई उपलब्ध है.
इंटरैक्टिव कॉम्पोनेंट
बटन जैसे इंटरैक्टिव कंट्रोल पर जेस्चर की सुविधा चालू करने के लिए, OneHandedGestureAction.Primary की जानकारी देने वाला कॉन्फ़िगरेशन बनाएं. इसके बाद, OneHandedGestureAction.Primary मॉडिफ़ायर लागू करें.oneHandedGesture कंट्रोल और मॉडिफ़ायर, दोनों को एक ही MutableInteractionSource पास करें, ताकि जेस्चर इवेंट, कंट्रोल पर विज़ुअल प्रेस फ़ीडबैक दिखा सकें.
हाथ के जेस्चर दिखाने वाले इंडिकेटर को चालू करने के लिए, OneHandedGestureClickIndicatorState का एक इंस्टेंस बनाएं और उसे याद रखें. इसके बाद, विज़ुअल फ़ीडबैक को ट्रिगर करने के लिए, oneHandedGesture मॉडिफ़ायर से मिले onGestureAvailable कॉलबैक में showIndicator को कॉल करें. इससे सिस्टम को यह सिग्नल मिलता है कि इंडिकेशन इवेंट हुआ है. कॉल किए जाने पर, कॉम्पोनेंट कुछ समय के लिए अपने सामान्य कॉन्टेंट को जेस्चर ऐनिमेशन से बदल देता है.
var isPlaying by remember { mutableStateOf(false) } val onClick = { isPlaying = !isPlaying } val gestureConfig = rememberOneHandedGestureConfiguration( action = OneHandedGestureAction.Primary ) val indicatorState = remember { OneHandedGestureClickIndicatorState() } val coroutineScope = rememberCoroutineScope() val interactionSource = remember { MutableInteractionSource() } Button( onClick = onClick, interactionSource = interactionSource, modifier = Modifier .fillMaxWidth() .oneHandedGesture( gestureConfiguration = gestureConfig, interactionSource = interactionSource, onGestureLabel = if (isPlaying) "pause" else "play", onGestureAvailable = { coroutineScope.launch { indicatorState.showIndicator() } }, onGesture = onClick ) ) { OneHandedGestureClickIndicator( gestureConfiguration = gestureConfig, state = indicatorState ) { Text(if (isPlaying) "Pause" else "Play", modifier = Modifier.fillMaxWidth()) } }
स्क्रोल किए जा सकने वाले कंटेनर
स्क्रोल की जा सकने वाली स्क्रीन या सूचियों के लिए, एक कॉन्फ़िगरेशन बनाएं. इसमें OneHandedGestureAction.Primary तय करें और अपने कंटेनर पर oneHandedGesture मॉडिफ़ायर लागू करें. इसके लिए, scrollDown जैसे स्क्रोलिंग हेल्पर को कॉल करें.
स्क्रोल करने की कार्रवाइयों के लिए विज़ुअल फ़ीडबैक देने के लिए, OneHandedGestureScrollIndicator का इस्तेमाल किया जा सकता है. यह कॉम्पोनेंट, स्क्रोल इंडिकेटर के तौर पर काम करता है. यह स्क्रोल की पोज़िशन दिखाता है. हालांकि, यह यह भी दिखा सकता है कि उपयोगकर्ता के लिए स्क्रोल करने का जेस्चर उपलब्ध है. इस इंडिकेटर को आम तौर पर, ScreenScaffold के scrollIndicator स्लॉट में पास किया जाता है. साथ ही, इसे स्क्रोल किए जा सकने वाले कंटेनर की स्थिति के साथ जोड़ा जाता है. जैसे, TransformingLazyColumn. यह OneHandedGestureScrollIndicatorState को भी देखता है, ताकि विज़ुअल ट्रांज़िशन को मैनेज किया जा सके.
विज़ुअल फ़ीडबैक को ट्रिगर करने के लिए, इस स्थिति में showIndicator को कॉल करें. आम तौर पर, यह oneHandedGesture मॉडिफ़ायर के onGestureAvailable कॉलबैक के अंदर होता है.
ट्रिगर होने के बाद, इंडिकेटर कुछ समय के लिए अपनी स्टैंडर्ड विज़ुअल स्थिति को बदलकर, जेस्चर ऐनिमेशन सीक्वेंस में बदल जाता है, ताकि उपयोगकर्ता को सूचना दी जा सके.
val scrollState = rememberTransformingLazyColumnState() val gestureConfig = rememberOneHandedGestureConfiguration( action = OneHandedGestureAction.Primary, priority = OneHandedGesturePriority.Scrollable ) val indicatorState = remember(gestureConfig) { OneHandedGestureScrollIndicatorState() } val coroutineScope = rememberCoroutineScope() ScreenScaffold( scrollState = scrollState, scrollIndicator = { OneHandedGestureScrollIndicator( gestureConfiguration = gestureConfig, indicatorState = indicatorState, scrollState = scrollState, modifier = Modifier.align(Alignment.CenterEnd) ) } ) { contentPadding -> TransformingLazyColumn( state = scrollState, contentPadding = contentPadding, modifier = Modifier .fillMaxSize() .oneHandedGesture( gestureConfiguration = gestureConfig, onGestureLabel = "scroll", onGestureAvailable = { coroutineScope.launch { indicatorState.showIndicator() } }, onGesture = { OneHandedGestureDefaults.scrollDown(scrollState) } ) ) { items(10) { index -> Text("Item $index", modifier = Modifier.padding(8.dp)) } } }
एक से ज़्यादा जेस्चर को एक साथ इस्तेमाल करना
gesturePriority को अपने OneHandedGestureConfiguration ऑब्जेक्ट में जोड़कर, स्क्रोल करने के जेस्चर और क्लिक करने के जेस्चर, दोनों को एक ही प्राइमरी ऐक्शन के साथ कॉन्फ़िगर किया जा सकता है:
OneHandedGesturePriority.Clickable(सबसे ज़्यादा): इसे इंटरैक्टिव कंट्रोल को असाइन करें. जैसे,ButtonयाCardटाइप वाले कंट्रोल, ताकि स्क्रीन पर दिखने पर वे जेस्चर कैप्चर कर सकें.OneHandedGesturePriority.Scrollable(मीडियम): इसे स्क्रोल किए जा सकने वाले या पेज वाले कंटेनर को असाइन करें, ताकि वे क्लिक किए जा सकने वाले एलिमेंट के साथ काम कर सकें. हालांकि, जब क्लिक किया जा सकने वाला कोई कंट्रोल नहीं दिखता है, तब वे स्क्रोल कर सकें.OneHandedGesturePriority.Unspecified(सबसे कम): यह प्राथमिकता असाइन नहीं की गई है. यह उस जेस्चर के लिए डिफ़ॉल्ट वैल्यू है जिसमेंpriorityसेट नहीं है.
किसी इनर बटन पर priority = OneHandedGesturePriority.Clickable
और उसकी पैरंट लिस्ट पर priority = OneHandedGesturePriority.Scrollable
को साफ़ तौर पर सेट करके, सिस्टम इस जेस्चर-प्रायॉरिटी के व्यवहार को दिखा सकता है.
जब उपयोगकर्ता एक हाथ से किए जाने वाले जेस्चर से मुख्य कार्रवाई को ट्रिगर करता है, तो यह सूची को तब तक नीचे की ओर स्क्रोल करता है, जब तक बटन नहीं दिख जाता. इसके बाद, यह बटन पर क्लिक करने की कार्रवाई को कैप्चर करता है.
एडीबी की मदद से, जेस्चर की जांच करना और उन्हें डीबग करना
Android Debug Bridge (adb) और IWearGestureService सिस्टम सेवा का इस्तेमाल करके, फ़िज़िकल डिवाइस या एम्युलेटर पर एक हाथ से किए जाने वाले जेस्चर की जांच की जा सकती है. इसके लिए, आपको कलाई को हिलाने की ज़रूरत नहीं होती.
जेस्चर सिम्युलेशन चालू करना
adb का इस्तेमाल करके जेस्चर सिम्युलेट करने से पहले, अपने डिवाइस की सेटिंग और कंस्ट्रेंट ओवरराइड कॉन्फ़िगर करें:
पुष्टि करें कि आपके Wear OS डिवाइस पर Wear OS 7 (एपीआई लेवल 37) और इसके बाद का वर्शन चल रहा हो:
adb shell getprop ro.build.version.sdkअगर आपको किसी ऐसे फ़िज़िकल डिवाइस पर टेस्टिंग करनी है जो आपकी कलाई पर नहीं है या चार्जर पर रखा है, तो डिवाइस के शरीर पर न होने की पाबंदी को अनदेखा करें. इससे जेस्चर फ़्रेमवर्क चालू रहेगा:
adb shell cmd IWearGestureService override-constraints offbody-state
ADB का इस्तेमाल करके, जेस्चर इवेंट ट्रिगर करना
दो बार पिंच करने के जेस्चर (जो Pixel Watch पर Primary कार्रवाई है) को सिम्युलेट करने के लिए, यहां दिया गया ADB शेल कमांड चलाएं:
adb shell cmd IWearGestureService gesture DoublePinch
कलाई घुमाने के जेस्चर (जो Pixel Watch पर Dismiss कार्रवाई है) को सिम्युलेट करने के लिए, यहां दी गई ADB शेल कमांड चलाएं:
adb shell cmd IWearGestureService gesture WristTurn
हाथ के जेस्चर के बारे में मिलने वाले सुझावों को ट्रैक करने की सुविधा रीसेट करना
सिस्टम, उपयोगकर्ता के इंटरैक्शन के इतिहास को ट्रैक करता है. साथ ही, ग्लोबल कैडेंस सेटिंग (जैसे कि हमेशा या हर दिन) के आधार पर फ़्लोटिंग जेस्चर के सुझाव दिखाता है. अपने ऐप्लिकेशन के जेस्चर इंडिकेटर को डीबग करते समय, ट्रैकिंग के इस इतिहास को रीसेट करें, ताकि आपके पैकेज के लिए फिर से सुझाव दिखें:
userdebugबिल्ड या एम्युलेटर पर:adb shell cmd IWearGestureService hint clear <your_package_name>खुदरा (
user) बिल्ड पर:रूट ऐक्सेस के बिना कमर्शियल डिवाइसों पर, सिस्टम की अनुमतियों की वजह से
hint clearब्लॉक हो जाता है. हिंट ढूंढने की सुविधा को रीसेट करने के लिए, ऐप्लिकेशन का स्थानीय डेटा मिटाएं:adb shell pm clear <your_package_name>
डिफ़ॉल्ट पाबंदियां वापस लाना
टेस्टिंग पूरी होने के बाद, डीबग की गई सभी कंस्ट्रेंट ओवरराइड को रीसेट करने के लिए:
adb shell cmd IWearGestureService override-constraints reset
जेस्चर इंजेक्शन की समस्या हल करना
अगर आपके ऐप्लिकेशन को सिम्युलेट किए गए जेस्चर नहीं मिलते हैं, तो:
पुष्टि करें कि स्मार्टवॉच की स्क्रीन चालू हो. स्क्रीन बंद होने या ऐंबियंट मोड में होने पर, जेस्चर फ़्रेमवर्क ऐप्लिकेशन को जेस्चर नहीं भेजता. ADB का इस्तेमाल करके डिसप्ले को चालू करने के लिए, यह कमांड चलाएं:
adb shell input keyevent KEYCODE_WAKEUPदेखें कि आपका ऐप्लिकेशन, जेस्चर की सुविधा इस्तेमाल करने वाले सदस्य के तौर पर रजिस्टर है या नहीं. साथ ही, देखें कि फ़िलहाल ऐप्लिकेशन पर विंडो फ़ोकस है या नहीं:
adb shell cmd IWearGestureService get-active-gestures -readableजब आपके ऐप्लिकेशन की जेस्चर स्क्रीन फ़ोरग्राउंड में हो और स्क्रीन चालू हो, तब यह कमांड
[DoublePinch]या[DoublePinch, WristTurn]दिखाती है. अगर खाली सूची ([]) दिखती है, तो देखें कि आपकी विंडो पर फ़ोकस है या नहीं. इसके अलावा, यह भी देखें कि क्या ऑफ़-बॉडी कंस्ट्रेंट, चालू होने की प्रोसेस को ब्लॉक कर रहे हैं.जेस्चर की इंटरनल सेवा की स्थिति और चालू सदस्य के टोकन की जांच करें:
adb shell dumpsys IWearGestureService
अन्य संसाधन
एक हाथ से किए जाने वाले जेस्चर का इस्तेमाल कब और कहां करना है, इसके बारे में डिज़ाइन से जुड़े दिशा-निर्देशों के लिए, एक हाथ से किए जाने वाले जेस्चर लेख पढ़ें.
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर लिंक का टेक्स्ट दिखता है
- एक हाथ से किए जाने वाले जेस्चर के डिज़ाइन से जुड़ी गाइड