Swipeable הוא API של Compose Material שעוזר לכם ליצור רכיבים שאפשר להחליק ביניהם בין מצבים נפרדים, כמו גיליונות תחתונים, מגירות או החלקה לסגירה. כדי לתמוך טוב יותר בתרחישי שימוש מתקדמים, כמו עוגנים שתלויים בגודל של רכיב, פורסמה גרסה חדשה ב-Compose-Foundation 1.6.0-alpha01: AnchoredDraggable. AnchoredDraggable
הוא API בסיסי ליצירת רכיבים שאפשר לגרור עם מצבים מעוגנים, כמו גיליונות תחתונים, מגירות או החלקה לסגירה.
ממשקי ה-API של Material Swipeable הוצאו משימוש לטובת AnchoredDraggable של Foundation ויוסרו בגרסה עתידית. במדריך הזה מוסבר איך לעבור מ-Swipeable API אל 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, אפשר להעביר את העוגנים לבונה של 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, כמו שמתואר בקטעים הבאים.
הגדרת מודעות עוגן
מגדירים את העוגנים באמצעות שיטת ה-builder 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
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
הועבר ל-constructor של |
|
עדיין אין תמיכה. כדי לראות את הסטטוס העדכני, אפשר להיכנס לקישור b/288084801. |
|
הועבר אל ה-constructor |