إدخال البيانات عبر وحدة تحكُّم دورانية باستخدام Compose

يشير الإدخال عبر وحدة تحكُّم دورانية إلى البيانات التي يتم إدخالها من خلال قطع من ساعتك تدور أو تدور. يقضي المستخدمون بوجهٍ عام بضع ثوانٍ فقط في التفاعل مع ساعتهم. يمكنك تحسين تجربة المستخدم من خلال استخدام الإدخال الدوراني للسماح للمستخدم بالانجاز بشكل سريع لمهام مختلفة.

تشمل المصادر الثلاثة الرئيسية للإدخال بالتناوب في معظم الساعات زر التناوب الجانبي (RSB) أو الحافة الخارجية أو الحافة الخارجية التي تعمل باللمس، وهي منطقة تناوب ملتفة حول الشاشة. على الرغم من أنّ السلوك المتوقّع قد يختلف استنادًا إلى نوع الإدخال، احرص على إتاحة الإدخال الدوراني لجميع التفاعلات الأساسية.

صفحة مواضع التمرير

يتوقع معظم المستخدمين أن تتيح التطبيقات إيماءة الانتقال للأعلى أو للأسفل. أثناء تمرير المحتوى على الشاشة، امنح المستخدمين ملاحظات مرئية استجابةً للتفاعلات الدوارة. يمكن أن تتضمّن الملاحظات المرئية مؤشرات الموضع للتمرير العمودي أو مؤشرات الصفحات.

يتيح ScalingLazyColumn وPicker إيماءة التمرير تلقائيًا، ما دام عليك وضع هذين المكوّنين داخل Scaffold. Scaffold يوفّر بنية التنسيق الأساسية لتطبيقات Wear OS، كما يتضمّن خانة لمؤشر التمرير. لِ عرض مستوى التقدّم في الانتقال للأعلى أو للأسفل، أنشئ مؤشر موضع استنادًا إلى عنصر حالة القائمة، كما هو موضّح في مقتطف الرمز البرمجي التالي:

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

يمكنك ضبط سلوك المحاذاة لعنصر ScalingLazyColumn باستخدام ScalingLazyColumnDefaults.snapFlingBehavior، كما هو موضّح في مقتطف الرمز التالي:

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

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

الإجراءات المخصّصة

يمكنك أيضًا إنشاء إجراءات مخصّصة تستجيب لطريقة إدخال البيانات عبر وحدة تحكُّم دورانية في تطبيقك. على سبيل المثال، يمكنك استخدام طريقة إدخال البيانات عبر وحدة تحكُّم دورانية للتكبير أو التصغير أو للتحكّم في مستوى الصوت في أحد التطبيقات المخصّصة للفيديوهات.

إذا كان المكوّن لا يتيح استخدام أحداث الانتقال للأعلى أو للأسفل بشكلٍ تلقائي، مثل التحكّم في مستوى الصوت، يمكنك معالجة أحداث الانتقال للأعلى أو للأسفل بنفسك.

// 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(),
) { ... }