אילוץ פריסה בכתיבה

ConstraintLayout הוא פריסה שמאפשרת למקם רכיבים של Composable ביחס לרכיבים אחרים של Composable במסך. היא חלופה לשימוש במספר Row, Column, Box ורכיבי פריסה אחרים בהתאמה אישית. ConstraintLayout שימושי כאשר מטמיעים פריסות גדולות יותר עם יישור מורכב יותר בדרישות שלנו.

מומלץ להשתמש ב-ConstraintLayout בתרחישים הבאים:

  • כדי להימנע מהטמעה של כמה רכיבי Column ו-Row למיקום רכיבים במסך, וכדי לשפר את קריאת הקוד.
  • למיקום של תכנים קומפוזביליים ביחס לתכנים קומפוזביליים אחרים או למיקום תכנים קומפוזביליים שמבוססים על הנחיות, מחסומים או רשתות.

במערכת התצוגה, ConstraintLayout הייתה הדרך המומלצת ליצירת פריסות גדולות ומורכבות, כי היררכיית תצוגה רגילה משפרת את הביצועים יותר מאשר תצוגות בתצוגות. עם זאת, זה לא בעיה ב-Compose, שיכול לטפל ביעילות בהיררכיות עיצוב עמוקות.

התחל לעבוד עם ConstraintLayout

כדי להשתמש ב-ConstraintLayout בניסוח האוטומטי, צריך להוסיף את התלות הזו build.gradle (בנוסף ל- הגדרת פיתוח נייטיב):

implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"

ConstraintLayout ב-Compose פועל באופן הבא באמצעות DSL:

  • יוצרים הפניות לכל תוכן קומפוזבילי ב-ConstraintLayout באמצעות createRefs() או createRefFor()
  • האילוצים מוצגים באמצעות המשתנה המשנה constrainAs(), שמקבל את ההפניה כפרמטר ומאפשר לציין את האילוצים שלו ב-body של הלמה.
  • המגבלות מפורטות באמצעות linkTo() או בשיטות מועילות אחרות.
  • parent הוא קובץ עזר קיים שאפשר להשתמש בו כדי לציין אילוצים לאובייקט הקומפוזבילי ConstraintLayout עצמו.

דוגמה לתוכן קומפוזבילי באמצעות ConstraintLayout:

@Composable
fun ConstraintLayoutContent() {
    ConstraintLayout {
        // Create references for the composables to constrain
        val (button, text) = createRefs()

        Button(
            onClick = { /* Do something */ },
            // Assign reference "button" to the Button composable
            // and constrain it to the top of the ConstraintLayout
            modifier = Modifier.constrainAs(button) {
                top.linkTo(parent.top, margin = 16.dp)
            }
        ) {
            Text("Button")
        }

        // Assign reference "text" to the Text composable
        // and constrain it to the bottom of the Button composable
        Text(
            "Text",
            Modifier.constrainAs(text) {
                top.linkTo(button.bottom, margin = 16.dp)
            }
        )
    }
}

הקוד הזה מגביל את החלק העליון של שדה Button להורה עם שוליים של 16.dp ו-Text לחלק התחתון של Button גם כן עם שוליים של 16.dp.

הצגת לחצן ורכיב טקסט שמסודרים ב-ConstraintLayout

API לאחר ביטול צימוד

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

במקרים כאלה, אפשר להשתמש ב-ConstraintLayout בדרך אחרת:

  1. מעבירים את ConstraintSet כפרמטר ל-ConstraintLayout.
  2. מקצים את ההפניות שנוצרו ב-ConstraintSet לרכיבים הניתנים לשילוב באמצעות המשתנה layoutId.

@Composable
fun DecoupledConstraintLayout() {
    BoxWithConstraints {
        val constraints = if (minWidth < 600.dp) {
            decoupledConstraints(margin = 16.dp) // Portrait constraints
        } else {
            decoupledConstraints(margin = 32.dp) // Landscape constraints
        }

        ConstraintLayout(constraints) {
            Button(
                onClick = { /* Do something */ },
                modifier = Modifier.layoutId("button")
            ) {
                Text("Button")
            }

            Text("Text", Modifier.layoutId("text"))
        }
    }
}

private fun decoupledConstraints(margin: Dp): ConstraintSet {
    return ConstraintSet {
        val button = createRefFor("button")
        val text = createRefFor("text")

        constrain(button) {
            top.linkTo(parent.top, margin = margin)
        }
        constrain(text) {
            top.linkTo(button.bottom, margin)
        }
    }
}

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

ConstraintLayout מושגים

ConstraintLayout כולל מושגים כמו הנחיות, מכשולים ורשתות שיכול לעזור במיקום של רכיבים בתוך הקומפוזבילי.

הנחיות

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

יש שני סוגים של הנחיות - אנכיות ואופקיות. שני הסוגים האופקיים הם top ו-bottom, והשניים הם start end

ConstraintLayout {
    // Create guideline from the start of the parent at 10% the width of the Composable
    val startGuideline = createGuidelineFromStart(0.1f)
    // Create guideline from the end of the parent at 10% the width of the Composable
    val endGuideline = createGuidelineFromEnd(0.1f)
    //  Create guideline from 16 dp from the top of the parent
    val topGuideline = createGuidelineFromTop(16.dp)
    //  Create guideline from 16 dp from the bottom of the parent
    val bottomGuideline = createGuidelineFromBottom(16.dp)
}

כדי ליצור הנחיה, צריך להשתמש במאפיין createGuidelineFrom* עם סוג ההנחיה נדרש. כך נוצרת הפניה שאפשר להשתמש בה בבלוק Modifier.constrainAs().

מחסומים

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

כדי ליצור מחסום, צריך להשתמש ב-createTopBarrier() (או ב-createBottomBarrier(), createEndBarrier(), createStartBarrier()), ולספק את ההפניות ש המכשול אמור להוות את המחסום.

ConstraintLayout {
    val constraintSet = ConstraintSet {
        val button = createRefFor("button")
        val text = createRefFor("text")

        val topBarrier = createTopBarrier(button, text)
    }
}

לאחר מכן אפשר להשתמש בחסימה בבלוק Modifier.constrainAs().

רשתות

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

כדי ליצור שרשרת, משתמשים ב-createVerticalChain או ב-createHorizontalChain:

ConstraintLayout {
    val constraintSet = ConstraintSet {
        val button = createRefFor("button")
        val text = createRefFor("text")

        val verticalChain = createVerticalChain(button, text, chainStyle = ChainStyle.Spread)
        val horizontalChain = createHorizontalChain(button, text)
    }
}

לאחר מכן אפשר להשתמש בשרשרת בבלוק Modifier.constrainAs().

אפשר להגדיר רשת עם סוגים שונים של ChainStyles, שקובעים את אופן הטיפול כשהרווח סביב תוכן קומפוזבילי, למשל:

  • ChainStyle.Spread: המרחב מתחלק באופן שווה בין כל התכנים הקומפוזביליים, כולל שטח פנוי לפני הפריט הקומפוזבילי הראשון ואחרי קומפוזבילי.
  • ChainStyle.SpreadInside: המרחב יחולק באופן שווה בין כל תכנים קומפוזביליים, ללא מקום פנוי לפני התוכן הקומפוזבילי הראשון או אחרי הקומפוזבילי האחרון.
  • ChainStyle.Packed: הרווח מופיע לפני ה-Composable הראשון ואחרי ה-Composable האחרון, וה-Composables מקובצים יחד ללא רווח ביניהם.

מידע נוסף

מידע נוסף על ConstraintLayout ב-Composer מממשקי ה-API בפעולה כתיבת דוגמאות שמשתמשות ב-ConstraintLayout.

אין המלצות כרגע.

אפשר לנסות לחשבון Google.