בConstraintLayout
גרסה 2.1, נוספו מספר תכונות כדי לעזור
ניהול מכשירים מתקפלים, כולל SharedValues
,
ReactiveGuide
ותמיכה משופרת באנימציה עם MotionLayout
.
ערכים משותפים
הוספנו מנגנון חדש להחדרת ערכים של זמן ריצה ב-ConstraintLayout
–
הוא מיועד לשימוש בערכים ברמת המערכת, כי כל המופעים של
ל-ConstraintLayout
יש גישה לערך.
בהקשר של מכשירים מתקפלים, אנחנו יכולים להשתמש במנגנון הזה כדי להחדיר את מיקום החלק התחתון בזמן ריצה:
Kotlin
ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold)
Java
ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold);
בכלי עזר בהתאמה אישית, אפשר לגשת לערכים המשותפים על ידי הוספת האזנה כל שינוי:
Kotlin
val sharedValues: SharedValues = ConstraintLayout.getSharedValues() sharedValues.addListener(mAttributeId, this)
Java
SharedValues sharedValues = ConstraintLayout.getSharedValues(); sharedValues.addListener(mAttributeId, this);
אפשר לעיין בדוגמה לניסויים מתקפלים
כדי לראות איך אנחנו אוספים את מיקום החלק העליון של הקיפול באמצעות
ספריית Jetpack windowManager והחדרה
את המיקום ב-ConstraintLayout
.
Kotlin
inner class StateContainer : Consumer<WindowLayoutInfo> { override fun accept(newLayoutInfo: WindowLayoutInfo) { // Add views that represent display features for (displayFeature in newLayoutInfo.displayFeatures) { val foldFeature = displayFeature as? FoldingFeature if (foldFeature != null) { if (foldFeature.isSeparating && foldFeature.orientation == FoldingFeature.Orientation.HORIZONTAL ) { // The foldable device is in tabletop mode val fold = foldPosition(motionLayout, foldFeature) ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold) } else { ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, 0); } } } } }
Java
class StateContainer implements Consumer<WindowLayoutInfo> { @Override public void accept(WindowLayoutInfo newLayoutInfo) { // Add views that represent display features for (DisplayFeature displayFeature : newLayoutInfo.getDisplayFeatures()) { if (displayFeature instanceof FoldingFeature) { FoldingFeature foldFeature = (FoldingFeature)displayFeature; if (foldFeature.isSeparating() && foldFeature.getOrientation() == FoldingFeature.Orientation.HORIZONTAL ) { // The foldable device is in tabletop mode int fold = foldPosition(motionLayout, foldFeature); ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, fold); } else { ConstraintLayout.getSharedValues().fireNewValue(R.id.fold, 0); } } } } }
הפונקציה fireNewValue()
לוקחת מזהה שמייצג את הערך כפרמטר הראשון,
את הערך שרוצים להחדיר כפרמטר השני.
ReactiveGuide
אחת מהדרכים להשתמש ב-SharedValue
בפריסה, בלי
כל קוד שהוא, הוא להשתמש בפונקציה ReactiveGuide
Assistant. פעולה זו תמקם קו מנחה אופקי או אנכי בהתאם
קושר SharedValue
.
<androidx.constraintlayout.widget.ReactiveGuide
android:id="@+id/fold"
app:reactiveGuide_valueId="@id/fold"
android:orientation="horizontal" />
אחר כך אפשר להשתמש בו בדיוק כמו בהנחיות רגילות.
MotionLayout
למכשירים מתקפלים
הוספנו כמה תכונות ב-MotionLayout
בגרסה 2.1 שעוזרות לשנות מורפינג
הוא שימושי במיוחד למכשירים מתקפלים, מכיוון שאנחנו בדרך כלל
צריכים לטפל באנימציה בין הפריסות האפשריות השונות.
יש שתי שיטות זמינות למכשירים מתקפלים:
- בזמן הריצה, צריך לעדכן את הפריסה הנוכחית (
ConstraintSet
) כדי להציג או להסתיר את לקפל. - צריך להשתמש במאפיין
ConstraintSet
נפרד לכל אחד מהמצבים המתקפלים שרוצים תמיכה (closed
,folded
אוfully open
).
אנימציה של ConstraintSet
הפונקציה updateStateAnimate()
ב-MotionLayout
נוספה בגרסה 2.1
גרסה:
Kotlin
fun updateStateAnimate(stateId: Int, set: ConstraintSet, duration: Int)
Java
void updateStateAnimate(int stateId, ConstraintSet set, int duration);
הפונקציה הזו תציג אנימציה לשינויים באופן אוטומטי במהלך עדכון נתון
ConstraintSet
במקום לבצע עדכון מיידי (אבל אפשר לעשות את זה באופן מיידי)
updateState(stateId, constraintset)
). כך אפשר לעדכן את ממשק המשתמש
בהתאם לשינויים, כמו המצב המתקפל שבו אתם נמצאים.
ReactiveGuide
בתוך MotionLayout
ReactiveGuide
תומך גם בשני מאפיינים שימושיים כשנעשה בהם שימוש בתוך
MotionLayout
:
app:reactiveGuide_animateChange="true|false"
app:reactiveGuide_applyToAllConstraintSets="true|false"
הראשון ישנה את ConstraintSet
הנוכחי ותוסיף אנימציה לשינוי
באופן אוטומטי. הערך השני יחיל את הערך החדש של ReactiveGuide
המיקום לכל ConstraintSet
בMotionLayout
. גישה אופיינית
במכשירים מתקפלים צריך להשתמש ב-ReactiveGuide
שמייצג את מיקום הקיפול,
להגדיר את רכיבי הפריסה שלך ביחס ל-ReactiveGuide
.
שימוש בכמה מעבדי ConstraintSet
לייצוג מצב מתקפל
במקום לעדכן את מצב MotionLayout
הנוכחי, אפשר להשתמש בדרך נוספת בארכיטקטורה
בממשק המשתמש, שתומך במכשירים מתקפלים, צריך ליצור מצבים נפרדים ספציפיים
closed
, folded
ו-fully open
).
בתרחיש הזה, יכול להיות שעדיין תרצו להשתמש ב-ReactiveGuide
כדי לייצג את
לקפל, אבל תהיה לך הרבה יותר שליטה (בהשוואה
אנימציה כשמעדכנים את ה-ConstraintSet
הנוכחי), שממחישה איך כל מצב
לעבור לחשבון אחר.
בגישה הזו, ב-DeviceState
המאזינים שלכם פשוט תגדירו את ה-
MotionLayout
כדי לעבור למדינות ספציפיות באמצעות
MotionLayout.transitionToState(stateId)
.