طرح بندی های سفارشی

در Compose، عناصر UI با توابع ترکیبی نمایش داده می شوند که در هنگام فراخوانی، یک قطعه از UI را منتشر می کنند، سپس به درخت UI اضافه می شود که روی صفحه نمایش داده می شود. هر عنصر رابط کاربری یک والد و احتمالاً فرزندان زیادی دارد. هر عنصر همچنین در والد خود قرار دارد که به عنوان موقعیت (x، y) و اندازه به عنوان width و height مشخص می شود.

والدین محدودیت هایی را برای عناصر فرزند خود تعریف می کنند. از یک عنصر خواسته می شود تا اندازه خود را در آن محدودیت ها تعریف کند. محدودیت ها حداقل و حداکثر width و height یک عنصر را محدود می کنند. اگر عنصری دارای عناصر فرزند باشد، ممکن است هر کودک را اندازه گیری کند تا به تعیین اندازه آن کمک کند. هنگامی که یک عنصر اندازه خود را تعیین و گزارش می‌کند، این فرصت را دارد که نحوه قرار دادن عناصر فرزند خود را نسبت به خودش تعریف کند، همانطور که در ایجاد طرح‌بندی‌های سفارشی توضیح داده شده است.

چیدمان هر گره در درخت UI یک فرآیند سه مرحله ای است. هر گره باید:

  1. هر کودکی را اندازه گیری کنید
  2. اندازه خود را تعیین کنید
  3. فرزندان خود را قرار دهد

سه مرحله چیدمان گره: اندازه گیری کودکان، تعیین اندازه، قرار دادن کودکان

استفاده از اسکوپ ها مشخص می کند که چه زمانی می توانید فرزندان خود را اندازه گیری و قرار دهید. اندازه‌گیری طرح‌بندی را فقط می‌توان در حین اندازه‌گیری و پاس‌های طرح‌بندی انجام داد، و یک فرزند را فقط می‌توان در طول پاس‌های طرح‌بندی (و فقط پس از اندازه‌گیری آن) قرار داد. با توجه به دامنه های Compose مانند MeasureScope و PlacementScope ، این در زمان کامپایل اجرا می شود.

از اصلاح کننده layout استفاده کنید

می‌توانید از اصلاح‌کننده layout برای تغییر نحوه اندازه‌گیری و چیدمان یک عنصر استفاده کنید. Layout یک لامبدا است. پارامترهای آن شامل عنصری است که می‌توانید اندازه‌گیری کنید، به‌عنوان measurable ارسال می‌شود، و محدودیت‌های ورودی آن composable که به‌عنوان constraints ارسال می‌شوند. یک اصلاح کننده طرح بندی سفارشی می تواند به شکل زیر باشد:

fun Modifier.customLayoutModifier() =
    layout { measurable, constraints ->
        // ...
    }

بیایید یک Text روی صفحه نمایش دهیم و فاصله از بالا تا خط پایه خط اول متن را کنترل کنیم. این دقیقاً همان کاری است که اصلاح‌کننده paddingFromBaseline انجام می‌دهد، ما آن را در اینجا به عنوان مثال پیاده‌سازی می‌کنیم. برای انجام این کار، از اصلاح کننده layout استفاده کنید تا به صورت دستی composable را روی صفحه قرار دهید. در اینجا رفتار مورد نظر است که در آن قسمت بالای Text 24.dp تنظیم شده است:

تفاوت بین بالشتک رابط کاربری معمولی، که فضای بین عناصر را تنظیم می‌کند، و بالشتک متنی که فضا را از یک خط پایه به خط دیگر تنظیم می‌کند، نشان می‌دهد.

در اینجا کد تولید این فاصله آمده است:

fun Modifier.firstBaselineToTop(
    firstBaselineToTop: Dp
) = layout { measurable, constraints ->
    // Measure the composable
    val placeable = measurable.measure(constraints)

    // Check the composable has a first baseline
    check(placeable[FirstBaseline] != AlignmentLine.Unspecified)
    val firstBaseline = placeable[FirstBaseline]

    // Height of the composable with padding - first baseline
    val placeableY = firstBaselineToTop.roundToPx() - firstBaseline
    val height = placeable.height + placeableY
    layout(placeable.width, height) {
        // Where the composable gets placed
        placeable.placeRelative(0, placeableY)
    }
}

در اینجا چیزی است که در آن کد می گذرد:

  1. در پارامتر لامبدا measurable ، Text که با پارامتر قابل اندازه‌گیری نمایش داده می‌شود، با فراخوانی measurable.measure(constraints) اندازه‌گیری می‌کنید.
  2. شما با فراخوانی متد layout(width, height) اندازه کامپوزیشن را مشخص می‌کنید، که همچنین یک لامبدا را برای قرار دادن عناصر پیچیده شده به دست می‌دهد. در این مورد، ارتفاع بین آخرین خط پایه و لایه بالایی اضافه شده است.
  3. با فراخوانی placeable.place(x, y) عناصر پیچیده شده را روی صفحه نمایش قرار می دهید. اگر عناصر پیچیده قرار نگیرند، قابل مشاهده نخواهند بود. موقعیت y مربوط به لایه بالایی است - موقعیت اولین خط پایه متن.

برای تأیید اینکه این کار همانطور که انتظار می رود کار می کند، از این اصلاح کننده در یک Text استفاده کنید:

@Preview
@Composable
fun TextWithPaddingToBaselinePreview() {
    MyApplicationTheme {
        Text("Hi there!", Modifier.firstBaselineToTop(32.dp))
    }
}

@Preview
@Composable
fun TextWithNormalPaddingPreview() {
    MyApplicationTheme {
        Text("Hi there!", Modifier.padding(top = 32.dp))
    }
}

پیش نمایش های متعدد از عناصر متن. یکی بالشتک معمولی بین عناصر را نشان می دهد، دیگری لایه بندی را از یک خط پایه به خط بعدی نشان می دهد

طرح بندی های سفارشی ایجاد کنید

اصلاح کننده layout فقط قابلیت فراخوانی را تغییر می دهد. برای اندازه‌گیری و چیدمان چند کامپوزی‌پذیر، به جای آن از Layout composable استفاده کنید. این ترکیب به شما امکان می دهد تا کودکان را به صورت دستی اندازه گیری و دراز کنید. همه طرح‌بندی‌های سطح بالاتر مانند Column و Row با Layout composable ساخته می‌شوند.

بیایید یک نسخه بسیار ابتدایی از Column بسازیم. اکثر طرح‌بندی‌های سفارشی از این الگو پیروی می‌کنند:

@Composable
fun MyBasicColumn(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
) {
    Layout(
        modifier = modifier,
        content = content
    ) { measurables, constraints ->
        // measure and position children given constraints logic here
        // ...
    }
}

مشابه اصلاح‌کننده layout ، measurables فهرستی از فرزندان هستند که باید اندازه‌گیری شوند و constraints محدودیت‌های والدین هستند. با همان منطق قبلی، MyBasicColumn می توان به صورت زیر پیاده سازی کرد:

@Composable
fun MyBasicColumn(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
) {
    Layout(
        modifier = modifier,
        content = content
    ) { measurables, constraints ->
        // Don't constrain child views further, measure them with given constraints
        // List of measured children
        val placeables = measurables.map { measurable ->
            // Measure each children
            measurable.measure(constraints)
        }

        // Set the size of the layout as big as it can
        layout(constraints.maxWidth, constraints.maxHeight) {
            // Track the y co-ord we have placed children up to
            var yPosition = 0

            // Place children in the parent layout
            placeables.forEach { placeable ->
                // Position item on the screen
                placeable.placeRelative(x = 0, y = yPosition)

                // Record the y co-ord placed up to
                yPosition += placeable.height
            }
        }
    }
}

ترکیب‌پذیرهای فرزند توسط محدودیت‌های Layout (بدون محدودیت‌های minHeight ) محدود می‌شوند، و بر اساس yPosition ترکیب‌بندی قبلی قرار می‌گیرند.

در اینجا نحوه استفاده از آن composable سفارشی آمده است:

@Composable
fun CallingComposable(modifier: Modifier = Modifier) {
    MyBasicColumn(modifier.padding(8.dp)) {
        Text("MyBasicColumn")
        Text("places items")
        Text("vertically.")
        Text("We've done it by hand!")
    }
}

چندین عنصر متنی در یک ستون یکی بالای دیگری روی هم چیده شده اند.

جهت چیدمان

جهت طرح بندی یک composable را با تغییر LocalLayoutDirection ترکیب محلی تغییر دهید.

اگر می‌خواهید فایل‌های composable را به صورت دستی روی صفحه قرار دهید، LayoutDirection بخشی از LayoutScope اصلاح‌کننده layout یا Layout composable است.

هنگام استفاده از layoutDirection ، composable ها را با استفاده از place قرار دهید. برخلاف روش placeRelative ، place بر اساس جهت چیدمان تغییر نمی کند (از چپ به راست در مقابل راست به چپ).

طرح بندی های سفارشی در عمل

درباره طرح‌بندی‌ها و اصلاح‌کننده‌ها در طرح‌بندی‌های پایه در Compose اطلاعات بیشتری کسب کنید و در نمونه‌های Compose که طرح‌بندی‌های سفارشی ایجاد می‌کنند، طرح‌بندی‌های سفارشی را در عمل ببینید.

بیشتر بدانید

برای کسب اطلاعات بیشتر در مورد طرح‌بندی‌های سفارشی در Compose، به منابع اضافی زیر مراجعه کنید.

فیلم های

{% کلمه به کلمه %} {% آخر کلمه %} {% کلمه به کلمه %} {% آخر کلمه %}