রচনা সহ ঘূর্ণমান ইনপুট

রোটারি ইনপুট বলতে আপনার ঘড়ির টুকরো থেকে ইনপুট বোঝায় যা ঘোরানো বা ঘোরানো হয়। গড়ে, ব্যবহারকারীরা তাদের ঘড়ির সাথে ইন্টারঅ্যাক্ট করতে মাত্র কয়েক সেকেন্ড ব্যয় করে। আপনি রোটারি ইনপুট ব্যবহার করে আপনার ব্যবহারকারীর অভিজ্ঞতা বাড়াতে পারেন যাতে আপনার ব্যবহারকারীকে দ্রুত বিভিন্ন কাজ সম্পন্ন করতে পারে।

বেশিরভাগ ঘড়িতে রোটারি ইনপুটের তিনটি প্রধান উৎসের মধ্যে রয়েছে রোটেটিং সাইড বোতাম (RSB), এবং হয় একটি ফিজিক্যাল বেজেল বা একটি টাচ বেজেল, যা স্ক্রিনের চারপাশে একটি বৃত্তাকার স্পর্শ অঞ্চল। যদিও প্রত্যাশিত আচরণ ইনপুট ধরনের উপর ভিত্তি করে পরিবর্তিত হতে পারে, সমস্ত প্রয়োজনীয় মিথস্ক্রিয়া জন্য ঘূর্ণমান ইনপুট সমর্থন নিশ্চিত করুন.

স্ক্রল করুন

বেশিরভাগ ব্যবহারকারী অ্যাপগুলি স্ক্রোল অঙ্গভঙ্গি সমর্থন করবে বলে আশা করে৷ বিষয়বস্তু স্ক্রিনে স্ক্রোল করার সাথে সাথে, ঘূর্ণমান মিথস্ক্রিয়াগুলির প্রতিক্রিয়া হিসাবে ব্যবহারকারীদের ভিজ্যুয়াল প্রতিক্রিয়া দিন। ভিজ্যুয়াল প্রতিক্রিয়া উল্লম্ব স্ক্রোল বা পৃষ্ঠা সূচকগুলির জন্য অবস্থান নির্দেশক অন্তর্ভুক্ত করতে পারে।

Wear OS এর জন্য Compose ব্যবহার করে রোটারি স্ক্রোল প্রয়োগ করুন। এই উদাহরণটি একটি স্ক্যাফোল্ড এবং একটি ScalingLazyColumn সহ একটি অ্যাপ্লিকেশন বর্ণনা করে যা উল্লম্বভাবে স্ক্রোল করে। স্ক্যাফোল্ড Wear OS অ্যাপগুলির জন্য মৌলিক লেআউট কাঠামো প্রদান করে এবং ইতিমধ্যেই একটি স্ক্রোল নির্দেশকের জন্য একটি স্লট রয়েছে৷ স্ক্রোলিং অগ্রগতি দেখাতে, তালিকার অবস্থার অবজেক্টের উপর ভিত্তি করে একটি অবস্থান নির্দেশক তৈরি করুন। ScalingLazyColumn সহ স্ক্রোলযোগ্য ভিউ, রোটারি ইনপুট যোগ করার জন্য ইতিমধ্যেই একটি স্ক্রোলযোগ্য অবস্থা রয়েছে। রোটারি স্ক্রোল ইভেন্টগুলি পেতে, নিম্নলিখিতগুলি করুন:

  1. FocusRequester ব্যবহার করে স্পষ্টভাবে ফোকাসের অনুরোধ করুন। একটি HorizontalPager এ একাধিক ScalingLazyColumns অবজেক্টের মতো আরও জটিল ক্ষেত্রে HierarchicalFocusCoordinator ব্যবহার করুন।

  2. ব্যবহারকারীর মুকুট ঘুরিয়ে বা বেজেল ঘোরানোর সময় সিস্টেম যে ইভেন্টগুলি তৈরি করে তা আটকাতে onRotaryScrollEvent সংশোধক যোগ করুন। প্রতিটি ঘূর্ণমান ইভেন্টের একটি সেট পিক্সেল মান থাকে এবং উল্লম্ব বা অনুভূমিকভাবে স্ক্রোল করে। ইভেন্টটি গ্রাস করা হয়েছে কিনা তা নির্দেশ করার জন্য সংশোধকের একটি কলব্যাকও রয়েছে এবং সেবন করা হলে তার পিতামাতার কাছে ইভেন্ট প্রচার বন্ধ করে দেয়।

val listState = rememberScalingLazyListState()
Scaffold(
    positionIndicator = {
        PositionIndicator(scalingLazyListState = listState)
    }
) {

    val focusRequester = rememberActiveFocusRequester()
    val coroutineScope = rememberCoroutineScope()

    ScalingLazyColumn(
        modifier = Modifier
            .onRotaryScrollEvent {
                coroutineScope.launch {
                    listState.scrollBy(it.verticalScrollPixels)
                    listState.animateScrollBy(0f)
                }
                true
            }
            .focusRequester(focusRequester)
            .focusable()
            .fillMaxSize(),
        state = listState
    ) {
        // Content goes here
        // ...
    }
}

বিচ্ছিন্ন মান

বিচ্ছিন্ন মানগুলিও সামঞ্জস্য করতে ঘূর্ণমান মিথস্ক্রিয়া ব্যবহার করুন, যেমন সেটিংসে উজ্জ্বলতা সামঞ্জস্য করা বা অ্যালার্ম সেট করার সময় টাইম পিকারে নম্বর নির্বাচন করা।

ScalingLazyColumn এর মতই, পিকার, স্লাইডার, স্টেপার এবং অন্যান্য কম্পোজেবলের রোটারি ইনপুট পাওয়ার জন্য ফোকাস থাকা প্রয়োজন । স্ক্রিনে একাধিক স্ক্রোলযোগ্য লক্ষ্যের ক্ষেত্রে, যেমন টাইম পিকারে ঘন্টা এবং মিনিট, প্রতিটি লক্ষ্যের জন্য একটি FocusRequester তৈরি করুন এবং ব্যবহারকারী যখন ঘন্টা বা মিনিটে ট্যাপ করে তখন সেই অনুযায়ী ফোকাস পরিবর্তন পরিচালনা করুন।

var selectedColumn by remember { mutableIntStateOf(0) }

val hoursFocusRequester = remember { FocusRequester() }
val minutesRequester = remember { FocusRequester() }
// ...
Scaffold(modifier = Modifier.fillMaxSize()) {
    Row(
        // ...
        // ...
    ) {
        // ...
        Picker(
            readOnly = selectedColumn != 0,
            modifier = Modifier.size(64.dp, 100.dp)
                .onRotaryScrollEvent {
                    coroutineScope.launch {
                        hourState.scrollBy(it.verticalScrollPixels)
                    }
                    true
                }
                .focusRequester(hoursFocusRequester)
                .focusable(),
            onSelected = { selectedColumn = 0 },
            // ...
            // ...
        )
        // ...
        Picker(
            readOnly = selectedColumn != 1,
            modifier = Modifier.size(64.dp, 100.dp)
                .onRotaryScrollEvent {
                    coroutineScope.launch {
                        minuteState.scrollBy(it.verticalScrollPixels)
                    }
                    true
                }
                .focusRequester(minutesRequester)
                .focusable(),
            onSelected = { selectedColumn = 1 },
            // ...
            // ...
        )
        LaunchedEffect(selectedColumn) {
            listOf(
                hoursFocusRequester,
                minutesRequester
            )[selectedColumn]
                .requestFocus()
        }
    }
}

কাস্টম অ্যাকশন

আপনি কাস্টম অ্যাকশনও তৈরি করতে পারেন যা আপনার অ্যাপে রোটারি ইনপুটে সাড়া দেয়। উদাহরণস্বরূপ, জুম ইন এবং আউট করতে বা মিডিয়া অ্যাপে ভলিউম নিয়ন্ত্রণ করতে রোটারি ইনপুট ব্যবহার করুন।

যদি আপনার উপাদানটি নেটিভভাবে স্ক্রলিং ইভেন্টগুলিকে সমর্থন না করে যেমন ভলিউম নিয়ন্ত্রণ, আপনি নিজেই স্ক্রোল ইভেন্টগুলি পরিচালনা করতে পারেন।

// VolumeScreen.kt

val focusRequester: FocusRequester = remember { FocusRequester() }

Column(
    modifier = Modifier
        .fillMaxSize()
        .onRotaryScrollEvent {
            // handle rotary scroll events
            true
        }
        .focusRequester(focusRequester)
        .focusable(),
) { ... }

ভিউ মডেলে পরিচালিত একটি কাস্টম অবস্থা এবং একটি কাস্টম কলব্যাক তৈরি করুন যা রোটারি স্ক্রোল ইভেন্টগুলি প্রক্রিয়া করতে ব্যবহৃত হয়।

// VolumeViewModel.kt

object VolumeRange(
    public val max: Int = 10
    public val min: Int = 0
)

val volumeState: MutableStateFlow<Int> = ...

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

সরলতার খাতিরে, পূর্ববর্তী উদাহরণে পিক্সেল মান ব্যবহার করা হয়েছে যেটি বাস্তবে ব্যবহার করলে অত্যধিক সংবেদনশীল হওয়ার সম্ভাবনা থাকে।

আপনি ইভেন্টগুলি পাওয়ার পরে কলব্যাক ব্যবহার করুন, যেমনটি নিম্নলিখিত স্নিপেটে দেখানো হয়েছে।

val focusRequester: FocusRequester = remember { FocusRequester() }
val volumeState by volumeViewModel.volumeState.collectAsState()

Column(
    modifier = Modifier
        .fillMaxSize()
        .onRotaryScrollEvent {
            volumeViewModel
                .onVolumeChangeByScroll(it.verticalScrollPixels)
            true
        }
        .focusRequester(focusRequester)
        .focusable(),
) { ... }

অতিরিক্ত সম্পদ

Horologist ব্যবহার করার কথা বিবেচনা করুন, একটি Google ওপেন সোর্স প্রকল্প যা Wear লাইব্রেরির একটি সেট সরবরাহ করে যা Wear OS এবং অন্যান্য Wear OS API-এর জন্য Compose দ্বারা প্রদত্ত কার্যকারিতার পরিপূরক। হরোলজিস্ট উন্নত ব্যবহারের ক্ষেত্রে এবং অনেক ডিভাইস নির্দিষ্ট বিবরণের জন্য বাস্তবায়ন প্রদান করে।

উদাহরণস্বরূপ, বিভিন্ন ঘূর্ণমান ইনপুট উত্সের সংবেদনশীলতা পরিবর্তিত হতে পারে। মানগুলির মধ্যে মসৃণ পরিবর্তনের জন্য আপনি সীমা নির্ধারণ করতে পারেন বা স্থানান্তরের জন্য স্ন্যাপিং বা অ্যানিমেশন যোগ করতে পারেন। এটি ব্যবহারকারীদের জন্য বাঁক গতিকে আরও স্বাভাবিক অনুভব করতে দেয়। হরোলজিস্ট স্ক্রোলযোগ্য উপাদান এবং পৃথক মানগুলির জন্য সংশোধক অন্তর্ভুক্ত করে। এটিতে ফোকাস পরিচালনা করার জন্য ইউটিলিটি এবং হ্যাপটিক্সের সাথে ভলিউম নিয়ন্ত্রণ বাস্তবায়নের জন্য একটি অডিও UI লাইব্রেরি অন্তর্ভুক্ত রয়েছে।

আরও তথ্যের জন্য, GitHub-এ হরোলজিস্ট দেখুন।

{% শব্দার্থে %} {% endverbatim %} {% শব্দার্থে %} {% endverbatim %}