סיבוב קלט באמצעות 'כתיבה'

קלט החוגה מתייחס לקלט מחלקים בשעון שמסתובבים או מסתובבים. במצב מופעל בממוצע, משתמשים מקדישים שניות ספורות בלבד לאינטראקציה עם השעון. שלך יכול לשפר את חוויית המשתמש באמצעות חוגה לקלט הנתונים כדי לאפשר למשתמש לבצע משימות שונות במהירות.

ברוב השעונים, שלושת המקורות העיקריים לקלט החוגה כוללים את הצד המסתובב (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(),
) { ... }

יצירת מצב מותאם אישית המנוהל בתצוגה מפורטת, וקריאה חוזרת (callback) בהתאמה אישית שנעשה בה שימוש כדי לעבד אירועי גלילה סיבובית.

// 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)
    }
}

כדי לשמור על הפשטות, הדוגמה הקודמת משתמשת בערכי פיקסלים, עשויות להיות רגישות מדי.

משתמשים בקריאה החוזרת (callback) אחרי שמקבלים את האירועים, כפי שמתואר בקטע הקוד הבא.

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

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