Compose की सुविधा के साथ रोटरी इनपुट


रोटरी इनपुट का मतलब है कि आपकी स्मार्टवॉच के उन हिस्सों से इनपुट लेना जो घूमते हैं या रोटेट होते हैं. औसतन, उपयोगकर्ता अपनी स्मार्टवॉच से इंटरैक्ट करने में कुछ ही सेकंड बिताते हैं. रोटरी इनपुट का इस्तेमाल करके, उपयोगकर्ता अनुभव को बेहतर बनाया जा सकता है. इससे उपयोगकर्ता, कई टास्क तेज़ी से पूरे कर पाते हैं.

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

स्क्रोल इंडिकेटर

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

ScalingLazyColumn, TransformingLazyColumn, और Picker में स्क्रोल करने के लिए जेस्चर की सुविधा डिफ़ॉल्ट रूप से उपलब्ध होती है. इसके लिए, इन कॉम्पोनेंट को AppScaffold और ScreenScaffold के अंदर रखना होता है. साथ ही, ScreenScaffold और कॉम्पोनेंट, जैसे कि TransformingLazyColumn के बीच सूची की स्थिति को पास करना होता है.

AppScaffold और ScreenScaffold, WearOS ऐप्लिकेशन के लिए बुनियादी लेआउट स्ट्रक्चर उपलब्ध कराते हैं. साथ ही, इनमें स्क्रोल इंडिकेटर के लिए पहले से ही एक स्लॉट होता है, जिसमें डिफ़ॉल्ट तौर पर लागू करने की सुविधा होती है. स्क्रोलिंग की प्रोग्रेस को पसंद के मुताबिक बनाने के लिए, सूची के स्टेट ऑब्जेक्ट के आधार पर स्क्रोल इंडिकेटर बनाएं. इसके लिए, यहां दिया गया कोड स्निपेट इस्तेमाल करें:

val listState = rememberTransformingLazyColumnState()
ScreenScaffold(
    scrollState = listState,
    scrollIndicator = {
        ScrollIndicator(state = listState)
    }
) {
    // ...
}

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

val listState = rememberScalingLazyListState()
ScreenScaffold(
    scrollState = listState,
    scrollIndicator = {
        ScrollIndicator(state = listState)
    }
) {

    val state = rememberScalingLazyListState()
    ScalingLazyColumn(
        modifier = Modifier.fillMaxWidth(),
        state = state,
        flingBehavior = ScalingLazyColumnDefaults.snapFlingBehavior(state = state)
    ) {
        // Content goes here
        // ...
    }
}

पसंद के मुताबिक की जाने वाली कार्रवाइयां

आपके पास अपने ऐप्लिकेशन में, रोटरी इनपुट के हिसाब से काम करने वाली कस्टम कार्रवाइयां बनाने का विकल्प भी होता है. उदाहरण के लिए, मीडिया ऐप्लिकेशन में ज़ूम इन और ज़ूम आउट करने या आवाज़ को कंट्रोल करने के लिए, रोटरी इनपुट का इस्तेमाल करें.

अगर आपके कॉम्पोनेंट में वॉल्यूम कंट्रोल जैसे स्क्रोलिंग इवेंट की सुविधा पहले से मौजूद नहीं है, तो स्क्रोलिंग इवेंट को खुद मैनेज किया जा सकता है.

पहला चरण, व्यू मॉडल में मैनेज की गई कस्टम स्थिति और रोटरी स्क्रोल इवेंट को प्रोसेस करने के लिए इस्तेमाल किया जाने वाला कस्टम कॉलबैक बनाना है.

class VolumeRange(
    val max: Int = 10,
    val min: Int = 0
)

private object VolumeViewModel {
    class MyViewModel : ViewModel() {
        private val _volumeState = mutableIntStateOf(0)
        val volumeState: State<Int>
            get() = _volumeState

        // ...
        fun onVolumeChangeByScroll(pixels: Float) {
            _volumeState.value = when {
                pixels > 0 -> minOf(volumeState.value + 1, VolumeRange().max)
                pixels < 0 -> maxOf(volumeState.value - 1, VolumeRange().min)
                else -> volumeState.value
            }
        }
    }
}

इसके बाद, इवेंट मिलने पर कॉलबैक का इस्तेमाल करें. इसके लिए, यहां दिया गया स्निपेट देखें.

val focusRequester: FocusRequester = remember { FocusRequester() }
val volumeViewModel: VolumeViewModel.MyViewModel =
    viewModel()
val volumeState by volumeViewModel.volumeState

TransformingLazyColumn(
    modifier = Modifier
        .fillMaxSize()
        .onRotaryScrollEvent {
            volumeViewModel.onVolumeChangeByScroll(it.verticalScrollPixels)
            true
        }
        .focusRequester(focusRequester)
        .focusable(),
) {
    // You can use volumeState here, for example:
    item {
        Text("Volume: $volumeState")
    }
}

ध्यान दें कि ऊपर दिए गए उदाहरण में, पिक्सल वैल्यू का इस्तेमाल किया गया है. अगर इनका इस्तेमाल किया जाता है, तो ये बहुत ज़्यादा संवेदनशील हो सकती हैं.