
ב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)
.