اصول اولیه سبک‌ها

سه روش برای استفاده از استایل‌ها در سراسر برنامه شما وجود دارد:

  1. مستقیماً روی اجزای موجودی که پارامتر Style را در معرض نمایش قرار می‌دهند، استفاده کنید.
  2. با استفاده از Modifier.styleable روی کامپوننت‌های layout که پارامتر Style را نمی‌پذیرند، یک استایل اعمال کنید.
  3. در سیستم طراحی سفارشی خودتان، Modifier.styleable{} استفاده کنید و یک پارامتر style را روی اجزای خودتان نمایش دهید.

ویژگی‌های موجود در Styles

سبک‌ها از بسیاری از ویژگی‌های مشابه اصلاح‌کننده‌ها پشتیبانی می‌کنند؛ با این حال، هر چیزی که اصلاح‌کننده باشد را نمی‌توان با یک سبک تکرار کرد. شما هنوز برای رفتارهای خاص، مانند تعاملات، ترسیم سفارشی یا انباشت ویژگی‌ها، به اصلاح‌کننده‌ها نیاز دارید.

گروه بندی خواص به فرزندان به ارث می‌رسد
طرح‌بندی و اندازه‌بندی
بالشتک contentPadding (داخلی) و externalPadding (بیرونی). در انواع جهت‌دار، افقی، عمودی و همه‌طرفه موجود است. خیر
ابعاد fillWidth/Height/Size() و width ، height و size (از کسرهای Dp ، DpSize یا Float پشتیبانی می‌کنند). خیر
موقعیت یابی انحرافات left/top/right/bottom . خیر
ظاهر بصری
پر کردن‌ها background و foreground ( Color یا Brush پشتیبانی می‌کند). خیر
مرزها borderWidth ، borderColor و borderBrush . خیر
شکل shape خیر - اما در رابطه با سایر ویژگی‌ها استفاده می‌شود. clip و border از این شکل تعریف شده استفاده می‌کنند.
سایه‌ها dropShadow ، innerShadow خیر
دگرگونی‌ها
حرکت فضایی لایه گرافیکی translationX ، translationY ، scaleX/Y ، rotationX/Y/Z خیر
کنترل alpha ، zIndex (ترتیب روی هم قرار دادن) و transformOrigin (نقطه محوری) خیر
تایپوگرافی
استایل textStyle ، fontSize ، fontWeight ، fontStyle و fontFamily بله
رنگ‌آمیزی contentColor و contentBrush . این دو همچنین برای استایل‌دهی به آیکون‌ها استفاده می‌شوند. بله
پاراگراف lineHeight ، letterSpacing ، textAlign ، textDirection ، lineBreak و hyphens . بله
دکوراسیون textDecoration ، textIndent و baselineShift . بله

استفاده مستقیم از استایل‌ها روی کامپوننت‌ها با پارامترهای استایل

کامپوننت‌هایی که پارامتر Style را نمایش می‌دهند، به شما امکان می‌دهند استایل‌بندی آنها را تنظیم کنید:

BaseButton(
    onClick = { },
    style = { }
) {
    BaseText("Click me")
}

درون استایل لامبدا، می‌توانید ویژگی‌های مختلفی مانند externalPadding یا background را تنظیم کنید:

BaseButton(
    onClick = { },
    style = { background(Color.Blue) }
) {
    BaseText("Click me")
}

برای لیست کامل ویژگی‌های پشتیبانی‌شده، به ویژگی‌های موجود در Styles مراجعه کنید.

اعمال سبک‌ها با استفاده از اصلاح‌کننده‌ها برای کامپوننت‌هایی که پارامتری ندارند

برای کامپوننت‌هایی که فاقد پارامتر style داخلی هستند، همچنان می‌توانید استایل‌ها را با استفاده از styleable modifier اعمال کنید. این رویکرد همچنین هنگام توسعه کامپوننت‌های سفارشی خودتان مفید است.

Row(
    modifier = Modifier.styleable { }
) {
    BaseText("Content")
}

مشابه پارامتر style ، می‌توانید ویژگی‌هایی مانند background یا padding درون لامبدا قرار دهید.

Row(
    modifier = Modifier.styleable {
        background(Color.Blue)
    }
) {
    BaseText("Content")
}

اصلاح‌کننده‌های زنجیره‌ای چندگانه Modifier.styleable با ویژگی‌های غیرارثی روی composable اعمال‌شده، افزایشی هستند و مشابه چندین اصلاح‌کننده که ویژگی‌های یکسانی را تعریف می‌کنند، رفتار می‌کنند. برای ویژگی‌های ارثی، این اصلاح‌کننده‌ها لغو می‌شوند و آخرین اصلاح‌کننده styleable در زنجیره، مقادیر را تعیین می‌کند.

هنگام استفاده از Modifier.styleable ، ممکن است بخواهید یک StyleState نیز ایجاد و ارائه کنید تا با استفاده از اصلاح‌کننده، استایل‌دهی مبتنی بر حالت را اعمال کند. برای جزئیات بیشتر، به بخش State and animations with Styles مراجعه کنید.

تعریف یک سبک مستقل

شما می‌توانید یک استایل مستقل برای اهداف قابلیت استفاده مجدد تعریف کنید:

val style = Style { background(Color.Blue) }

سپس می‌توانید آن سبک تعریف‌شده را به پارامتر style یک composable یا با Modifier.styleable ارسال کنید. هنگام استفاده از Modifier.styleable ، باید یک شیء StyleState نیز ایجاد کنید. StyleState به طور مفصل در مستندات State و animations with Styles پوشش داده شده است.

مثال زیر نشان می‌دهد که چگونه می‌توانید یک Style را مستقیماً از طریق پارامترهای داخلی کامپوننت یا از طریق Modifier.styleable اعمال کنید:

val style = Style { background(Color.Blue) }

// built in parameter
BaseButton(onClick = { }, style = style) {
    BaseText("Button")
}

// modifier styleable
val styleState = remember { MutableStyleState(null) }
Column(
    Modifier.styleable(styleState, style)
) {
    BaseText("Column content")
}

همچنین می‌توانید آن استایل را به چندین کامپوننت ارسال کنید:

val style = Style { background(Color.Blue) }

// built in parameter
BaseButton(onClick = { }, style = style) {
    BaseText("Button")
}
BaseText("Different text that uses the same style parameter", style = style)

// modifier styleable
val columnStyleState = remember { MutableStyleState(null) }
Column(
    Modifier.styleable(columnStyleState, style)
) {
    BaseText("Column")
}
val rowStyleState = remember { MutableStyleState(null) }
Row(
    Modifier.styleable(rowStyleState, style)
) {
    BaseText("Row")
}

اضافه کردن چندین ویژگی استایل

شما می‌توانید با تنظیم ویژگی‌های مختلف در هر خط، چندین ویژگی Style اضافه کنید:

BaseButton(
    onClick = { },
    style = {
        background(Color.Blue)
        contentPaddingStart(16.dp)
    }
) {
    BaseText("Button")
}

ویژگی‌های موجود در Styles، برخلاف سبک‌بندی مبتنی بر اصلاح‌کننده، افزایشی نیستند. سبک‌ها آخرین مقدار تعیین‌شده در لیست ویژگی‌های درون یک بلوک سبک را می‌گیرند. در مثال زیر، با دو بار تنظیم پس‌زمینه، TealColor پس‌زمینه اعمال‌شده است. برای padding، contentPaddingTop padding بالایی تعیین‌شده توسط contentPadding را لغو می‌کند و مقادیر را ترکیب نمی‌کند.

BaseButton(
    style = {
        background(Color.Red)
        // Background of Red is now overridden with TealColor instead
        background(TealColor)
        // All directions of padding are set to 64.dp (top, start, end, bottom)
        contentPadding(64.dp)
        // Top padding is now set to 16.dp, all other paddings remain at 64.dp
        contentPaddingTop(16.dp)
    },
    onClick = {
        //
    }
) {
    BaseText("Click me!")
}

دکمه‌ای با دو رنگ پس‌زمینه تنظیم شده و دو پارامتر contentPadding نادیده گرفته می‌شوند.
شکل ۱. دکمه‌ای با دو رنگ پس‌زمینه تنظیم شده و دو contentPadding نادیده گرفته شده.

ادغام چندین شیء سبک

شما می‌توانید چندین شیء Style ایجاد کنید و آنها را به پارامتر style در composable خود ارسال کنید.

val style1 = Style { background(TealColor) }
val style2 = Style { contentPaddingTop(16.dp) }

BaseButton(
    style = style1 then style2,
    onClick = {

    },
) {
    BaseText("Click me!")
}

دکمه با رنگ پس‌زمینه و مجموعه محتوای PaddingTop
شکل ۲. دکمه با رنگ پس‌زمینه و مجموعه contentPaddingTop .

وقتی چندین Styles یک ویژگی یکسان را مشخص می‌کنند، آخرین ویژگی set انتخاب می‌شود. از آنجایی که ویژگی‌ها در Styles جمع‌پذیر نیستند، آخرین padding ارسالی، contentPaddingHorizontal تنظیم‌شده توسط contentPadding اولیه را لغو می‌کند. علاوه بر این، آخرین رنگ پس‌زمینه، رنگ پس‌زمینه تنظیم‌شده توسط style اولیه ارسالی را لغو می‌کند.

val style1 = Style {
    background(Color.Red)
    contentPadding(32.dp)
}

val style2 = Style {
    contentPaddingHorizontal(8.dp)
    background(Color.LightGray)
}

BaseButton(
    style = style1 then style2,
    onClick = {

    },
) {
    BaseText("Click me!")
}

در این حالت، استایل اعمال شده دارای پس‌زمینه خاکستری روشن و padding 32.dp است، به جز padding چپ و راست که مقدار 8.dp دارد.

دکمه‌ای با contentPadding که توسط سبک‌های مختلف بازنویسی شده است
شکل ۳. دکمه‌ای با contentPadding که توسط Styleهای مختلف بازنویسی شده است.

وراثت سبک

ویژگی‌های استایل خاص، مانند ویژگی‌های مربوط به contentColor و text، به کامپوننت‌های فرزند منتقل می‌شوند. استایلی که روی یک کامپوننت فرزند تنظیم می‌شود، استایل والد به ارث رسیده را برای آن فرزند خاص لغو می‌کند.

انتشار سبک با پارامترهای Style، styleable و direct
شکل ۴. انتشار سبک با پارامترهای Style ، styleable و direct.
اولویت روش اثر
۱ (بالاترین) آرگومان‌های مستقیم روی یک ترکیب‌پذیر همه چیز را لغو می‌کند؛ برای مثال، Text(color = Color.Red)
۲ پارامتر سبک سبک محلی، Text(style = Style { contentColor(Color.Red)} را لغو می‌کند.
۳ زنجیره اصلاح‌کننده Modifier.styleable{ contentColor(Color.Red) روی خود کامپوننت.
۴ (پایین‌ترین) سبک‌های والدین برای ویژگی‌هایی که می‌توانند از والد به ارث برده شوند (مانند تایپوگرافی/رنگ).

استایل‌دهی والدین

شما می‌توانید ویژگی‌های متن (مانند contentColor ) را از composable والد تنظیم کنید، و آنها را به همه composableهای Text فرزند منتقل کنید.

val styleState = remember { MutableStyleState(null) }
Column(
    modifier = Modifier.styleable(styleState) {
        background(Color.LightGray)
        val blue = Color(0xFF4285F4)
        val purple = Color(0xFFA250EA)
        val colors = listOf(blue, purple)
        contentBrush(Brush.linearGradient(colors))
    },
) {
    BaseText("Children inherit", style = { width(60.dp) })
    BaseText("certain properties")
    BaseText("from their parents")
}

ارث بری از اموال قابل ترکیب فرزند
شکل ۵. وراثت ویژگی‌های فرزند composables.

نادیده گرفتن ویژگی‌ها توسط فرزند

شما همچنین می‌توانید استایل‌بندی را روی یک Composable Text خاص تنظیم کنید. اگر Composable والد دارای مجموعه استایل‌بندی باشد، مجموعه استایل‌بندی روی Composable فرزند، استایل‌بندی Composable والد را لغو می‌کند.

val styleState = remember { MutableStyleState(null) }
Column(
    modifier = Modifier.styleable(styleState) {
        background(Color.LightGray)
        val blue = Color(0xFF4285F4)
        val purple = Color(0xFFA250EA)
        val colors = listOf(blue, purple)
        contentBrush(Brush.linearGradient(colors))
    },
) {
    BaseText("Children can ", style = {
        contentBrush(Brush.linearGradient(listOf(Color.Red, Color.Blue)))
    })
    BaseText("override properties")
    BaseText("set by their parents")
}

کامپوننت‌های فرزند، ویژگی‌های والد را نادیده می‌گیرند
شکل ۶. کامپوننت‌های فرزند، ویژگی‌های والد را نادیده می‌گیرند.

پیاده‌سازی ویژگی‌های استایل سفارشی

شما می‌توانید با استفاده از توابع افزونه در StyleScope ، همانطور که در مثال زیر نشان داده شده است، ویژگی‌های سفارشی ایجاد کنید که به تعاریف Style موجود نگاشت می‌شوند:

fun StyleScope.outlinedBackground(color: Color) {
    border(1.dp, color)
    background(color)
}

این ویژگی جدید را در تعریف Style اعمال کنید:

val customExtensionStyle = Style {
    outlinedBackground(Color.Blue)
}

ایجاد ویژگی‌های جدید با قابلیت استایل‌دهی پشتیبانی نمی‌شود. اگر مورد استفاده شما به چنین پشتیبانی نیاز دارد، درخواست ویژگی ارسال کنید.

خواندن مقادیر CompositionLocal

این یک الگوی رایج است که توکن‌های سیستم طراحی را درون یک CompositionLocal ذخیره کنیم تا به متغیرها بدون نیاز به ارسال آنها به عنوان پارامتر دسترسی داشته باشیم. استایل‌ها می‌توانند به CompositionLocal دسترسی داشته باشند تا مقادیر کل سیستم را درون یک استایل بازیابی کنند:

val buttonStyle = Style {
    contentPadding(12.dp)
    shape(RoundedCornerShape(50))
    background(Brush.verticalGradient(LocalCustomColors.currentValue.background))
}