Swipeable הוא API של Compose Material שעוזר לכם ליצור רכיבים שאפשר להחליק ביניהם בין מצבים נפרדים, כמו גיליונות תחתונים, מגירות או החלקה לסגירה. כדי לתמוך טוב יותר בתרחישי שימוש מתקדמים, כמו עוגנים שתלויים בגודל של רכיב, פורסמה גרסה חדשה ב-Compose-Foundation 1.6.0-alpha01: AnchoredDraggable. AnchoredDraggable
הוא Foundation API ליצירת רכיבים שניתן לגרור עם מצבים מעוגנים, כמו גיליונות תחתונים, מגירות או החלקה לסגירה.
ממשקי ה-API של Material Swipeable הוצאו משימוש לטובת AnchoredDraggable של Foundation ויוסרו בגרסה עתידית. במדריך הזה מוסבר איך לבצע מיגרציה מ-Swipeable APIs אל AnchoredDraggable.
העברה של SwipeableState אל AnchoredDraggableState
כדי להתחיל, צריך לזהות שינויים במאחסן המצב. אי אפשר להעביר את AnchoredDraggableState בירושה, וההיסט מוצג כ-Float.NaN לפני שהוא מאותחל.
עדכון של מאחסן המצב
AnchoredDraggableState היא מחלקה סופית, כלומר אי אפשר להוריש ממנה. אם הרכיב הקיים שלכם עובר בירושה מ-SwipeableState, צריך לעדכן את מאחסן המצב שלכם כדי שיכיל הפניה אל AnchoredDraggableState במקום לעבור בירושה ממנו:
עם פונקציית החלקה
class MySwitchState: SwipeableState()
AnchoredDraggable
class MySwitchState {
private val anchoredDraggableState = AnchoredDraggableState(...)
}
מכיוון שמאחסן המצב שלכם כבר לא עובר בירושה מ-SwipeableState, יכול להיות שתצטרכו לחשוף ממשקי API בעצמכם. ממשקי ה-API הנפוצים ביותר שבהם אפשר להשתמש הם offset, progress, currentValue ו-targetValue.
גישה להיסט
בניגוד ל-Swipeable, הערך של offset ב-AnchoredDraggableState הוא Float.NaN לפני האתחול. ב-AnchoredDraggable, אפשר להעביר את העוגנים ל-constructor של AnchoredDraggableState או לעדכן אותם באמצעות AnchoredDraggableState#updateAnchors. העברת העוגנים לקונסטרוקטור של AnchoredDraggableState מאתחלת את ההיסט באופן מיידי.
אם העוגנים שלכם תלויים בפריסה או שהם עשויים להשתנות, השתמשו ב-AnchoredDraggableState#updateAnchors כדי להימנע מיצירה מחדש של המצב כשהעוגנים משתנים.
אם משתמשים ב-updateAnchors, ההיסט יהיה Float.NaN לפני העברת העוגנים אל updateAnchors. כדי למנוע העברה לא מכוונת של Float.NaN לרכיבים, משתמשים ב-AnchoredDraggableState#requireOffset כדי לדרוש שההיסט יאותחל כשקוראים אותו. כך תוכלו לזהות אי-התאמות או באגים אפשריים בשלב מוקדם.
@Composable
fun AnchoredDraggableBox() {
val state = remember { AnchoredDraggableState(...) }
val density = LocalDensity.current
val anchors = remember { DraggableAnchors { ... } }
SideEffect {
state.updateAnchors(anchors)
}
Box(
Modifier.offset { IntOffset(x = state.requireOffset(), y = 0) }
}
}
העברה של Modifier.swipeable אל Modifier.anchoredDraggable
Modifier.anchoredDraggable() מחליף את Modifier.swipeable. חלק מהפרמטרים של Modifier.swipeable() הועברו ישירות אל AnchoredDraggableState, כמו שמתואר בקטעים הבאים.
הגדרת עוגנים
מגדירים את העוגנים באמצעות שיטת ה-build של DraggableAnchors. לאחר מכן, מעבירים אותם לבונה של AnchoredDraggableState#updateAnchors או AnchoredDraggableState:
Constructor
enum class DragValue { Start, Center, End }
@Composable
fun AnchoredDraggableBox() {
val anchors = DraggableAnchors {
Start at -100.dp.toPx()
Center at 0f
End at 100.dp.toPx()
}
val state = remember {
AnchoredDraggableState(anchors = anchors)
}
Box(
Modifier.offset { IntOffset(x = state.requireOffset(), y = 0) }
)
}
updateAnchors
enum class DragValue { Start, Center, End }
@Composable
fun AnchoredDraggableBox() {
val state = remember { AnchoredDraggableState(...) }
val density = LocalDensity.current
val anchors = with (density) {
DraggableAnchors {
Start at -100.dp.toPx()
Center at 0f
End at 100.dp.toPx()
}
}
SideEffect {
state.updateAnchors(anchors)
}
Box(
Modifier.offset { IntOffset(x = state.requireOffset(), y = 0) }
)
}
אם העוגנים סטטיים, מעבירים אותם ל-constructor. אם הם תלויים בפריסה או שהם לא סטטיים, צריך להשתמש ב-updateAnchors.
הגדרת ספים מיקומיים
הסוג והשם של פרמטר הספים השתנו. במקום ממשק ThresholdConfig נפרד, ל-AnchoredDraggableState יש פרמטר positionalThreshold שמקבל פונקציית lambda שמחזירה את מיקום הסף. לדוגמה, סף מיקום של 50% יכול להיות מוגדר כך:
val anchoredDraggableState = AnchoredDraggableState(
positionalThreshold = { distance -> distance * 0.5f },
...
)
סף מיקום של 56dp יכול להיות מוצג כך:
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
positionalThreshold = { with(density) { 56.dp.toPx() } },
...
)
הגדרת ספי מהירות
גם ערכי הסף של המהירות מועברים לקונסטרוקטור של AnchoredDraggableState, וגם הם מבוטאים כביטוי למדה:
val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
velocityThreshold = { with(density) { 125.dp.toPx() } },
...
)
שינויים בפלטפורמת ה-API
בהמשך מופיעה סקירה כללית של השינויים בממשק ה-API.
AnchoredDraggableState
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
לא רלוונטי |
|
|
|
|
|
|
|
|
|
|
|
Modifier.anchoredDraggable
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
מועבר לבונה |
|
עדיין לא נתמך. אפשר לראות את הסטטוס העדכני בכתובת b/288084801. |
|
הועבר אל ה-constructor |