جت‌پک کامپوز در اندروید: سفارشی‌سازی Composable ها با Modifier

جت‌پک کامپوز در اندروید: سفارشی‌سازی Composable ها با Modifier

بررسی کلاس Modifier

کلاس Modifier بین تمام Composable ها مشترک است، با استفاده از Modifier میتونیم یک Composable رو سفارشی‌سازی کنیم.

کلاس Modifier یک کلاس Builder است و ترتیب صدا زدن توابع Modifier مهم است؛ توابع کلاس Modifier تغییر‌ناپذیر (immutable) هستن، یعنی یک بار که مقداردهی بشن دیگه نمیتونیم مقدار جدیدی بهشون بدیم.

به طور قراردادی بهتره هر Composable که تعریف میکنیم یک پارامتر از نوع Modifier داشته باشه.

@Composable
fun MyComposableFunction(modifier: Modifier = Modifier){
    //do something here
}
                

توابع پرکاربرد

در این بخش توابع پرکاربرد کلاس Modifier رو بررسی میکنیم؛ در UML زیر هر تابع با ویژگی ها و عملکردش مشخص شده.

Modifier
fillMaxSize(): Modifier عرض و ارتفاع Composable اندازه Parent میشه.
fillMaxWidth(): Modifier عرض Composable اندازه Parent میشه.
fillMaxHeight(): Modifier ارتفاع Composable اندازه Parent میشه.
wrapContentSize(): Modifier عرض و ارتفاع Composable اندازه محتوای Composable میشه
wrapContentWidth(): Modifier عرض Composable اندازه ارتفاع محتوای Composable میشه.
wrapContentHeight(): Modifier ارتفاع Composable اندازه ارتفاع محتوای Composable میشه.
size(dp: Dp): Modifier طول و عرض Composable رو به صورت dp تعریف میکنیم.
background(color: Color): Modifier پس زمینه Composable رو تغییر میده.
padding(all: Dp): Modifier فاصله ی داخلی یا خارجی Composable رو تغییر میده.
border(width: Dp, color: Color, shape: Shape): Modifier دور تا دور Composable رو ترسیم میکنه؛ width: قطر خط، color: رنگ خط و shape: شکل چهار گوشه خط.
shadow(elevation: Dp, shape: Shape, clip: Boolean, ambientColor: Color, spotColor: Color): Modifier یک سایه برای Composable ایجاد میکنه.
clickable(clickable: Boolean, onClickLabel: String?, onClick: () -> Unit): Modifier میتونیم روی Composable کلیک کنیم؛ برای این تابع پارامتر های دیگه ای وجود داره ولی برای خلاصه کردن همین سه تا پارامتر کافیه.
then(modifier: Modifier): Modifier Modifier فعلی رو با یک Modifier دیگه ترکیب میکنه.

میخوایم یک متن رو نمایش بدیم و از چهار طرف به اندازه 16 dp فاصله ایجاد کنیم.

@Composable
fun MyText(content: String, modifier: Modifier = Modifier){
    Text(
        text = content,
        modifier = modifier.padding(16.dp)
    )
}
                

در زیر میخوایم یک متن رو نمایش بدیم، بکگراند متن رو عوض کنیم و بین لایه متن و چهار طرف به اندازه 8 dp فاصله ایجاد کنیم.

@Composable
fun MyText(content: String, modifier: Modifier = Modifier){
    Text(
        text = content,
        fontSize = 50.sp,
        modifier = modifier.padding(8.dp).background(Color(0xFFF5F5F5))
    )
}
                

اگه بعد از تعریف یک ویژگی با Modifier (مثلا بک گراند یا border رو تعریف کنیم) تابع padding رو صدا بزنیم بین محتوای Composable و ویژگی تعریف شده فاصله ایجاد میشه.

در زیر میخوایم علاوه بر ویژگی های قبلی میخوایم یک فاصله ی داخلی به اندازه 16 dp نسبت به محتوای متن هم ایجاد کنیم.

@Composable
fun MyText(content: String, modifier: Modifier = Modifier){
    Text(
        text = content,
        fontSize = 50.sp,
        modifier = modifier.padding(8.dp).background(Color(0xFFF5F5F5)).padding(16.dp)
    )
}
                

در زیر میخوایم یک سایه آبی هم به لایه متن اضافه کنیم.

@Composable
fun MyText(content: String, modifier: Modifier = Modifier){
    Text(
        text = content,
        fontSize = 50.sp,
        modifier = modifier.padding(8.dp).background(Color(0xFFF5F5F5))
            .shadow(elevation = 2.dp, shape = ShapeDefaults.Small, spotColor = Color.Blue)
            .padding(16.dp)
    )
}
                

حالا میخوایم دور تا دور محتوای متن یک border هم ترسیم کنیم.

@Composable
fun MyText(content: String, modifier: Modifier = Modifier){
    Text(
        text = content,
        fontSize = 50.sp,
        modifier = modifier.padding(8.dp).background(Color(0xFFF5F5F5))
            .shadow(elevation = 2.dp, shape = ShapeDefaults.Small, spotColor = Color.Blue)
            .padding(16.dp).border(width = 2.dp, shape = ShapeDefaults.Small, color = Color.Yellow)
    )
}
                

حالا چی میشه اگه بتونیم رو متن کلیک هم کنیم؟

@Composable
fun MyText(content: String, modifier: Modifier = Modifier){
    Text(
        text = content,
        fontSize = 50.sp
        modifier = modifier.padding(8.dp).background(Color(0xFFF5F5F5))
            .shadow(elevation = 2.dp, shape = ShapeDefaults.Small, spotColor = Color.Blue)
            .padding(16.dp).border(width = 2.dp, shape = ShapeDefaults.Small, color = Color.Yellow).padding(12.dp)
            .clickable{
                Log.d("CLICKED", "clicked on $content")
            }
        )
}
                

حالا یکم فاصله ام بین border و محتوای متن بندازیم.

@Composable
fun MyText(content: String, modifier: Modifier = Modifier){
    Text(
        text = content,
        fontSize = 50.sp
        modifier = modifier.padding(8.dp).background(Color(0xFFF5F5F5))
            .shadow(elevation = 2.dp, shape = ShapeDefaults.Small, spotColor = Color.Blue)
            .padding(16.dp).border(width = 2.dp, shape = ShapeDefaults.Small, color = Color.Yellow)
            .padding(12.dp)
            .clickable{
                Log.d("CLICKED", "clicked on $content")
            }
    )
}
                

حالا هرچی نوشتیمو بریم اجرا کنیم.

import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.ShapeDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import ir.kodedevel.helloworld.ui.theme.HelloWorldTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            HelloWorldTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    MyText("Hello World", modifier = Modifier.padding(innerPadding))
                }
            }
        }
    }
}

@Composable
fun MyText(content: String, modifier: Modifier = Modifier){
    Text(
        text = content,
        fontSize = 45.sp,
        modifier = modifier.padding(8.dp).background(Color(0xFFF5F5F5))
            .shadow(elevation = 2.dp, shape = ShapeDefaults.Small, spotColor = Color.Blue)
            .padding(16.dp).border(width = 2.dp, shape = ShapeDefaults.Small, color = Color.Yellow)
            .clickable{
                Log.d("CLICKED", "clicked on $content")
            }
            .padding(12.dp)
    )
}

@Preview
@Composable
fun MyTextPreview(){
    MyText("Hello World!")
}
                

در کد بالا از innerPadding مربوط به تابع Scoffold استفاده کردیم، اگه از innerPadding استفاده نکنیم، Composable میوفته روی استاتوس بار در بالای وسیله اندرویدی؛ در واقع innerPadding یک فاصله بین لایه کامپوز اصلی و حاشیه های وسیله ی اندرویدی ایجاد میکنه.

کلاس Log یک کلاس استاتیک اندروید است که باهاش میتونیم لاگ های برنامه رو از طریق LogCat ببینیم داخل اندروید استادیو لاگ‌کت رو باز کنید و با هربار کلیک روی متن نتیجه پیغامی که داخل Log.d نوشتیم رو نمایش میده؛ برای باز کردن تب لاگ‌کت در پایین سمت چپ اندروید استادیو مطابق تصویر روی علامتی که دورش خط قرمز کشیده شده کلیک کنید.

تب لاگ‌کت در اندروید استادیو
تب لاگ‌کت در اندروید استادیو

خلاصه

  • کلاس Modifier یک کلاس عمومی بین تمام Composable هاست.
  • به طور کلی بهتره هر Composable که تعریف میکنیم یک کلاس Modifier به عنوان پارامتر براش تعریف کنیم.
  • کلاس Modifier نوعی builder است و ترتیب صدا زدن توابع داخل کلاس مهم است.
  • توابع Modifier تغییر‌ناپذیر هستن
  • اگه بعد از تعریف یک ویژگی برای Composable (مثلا بکگراند) تابع padding رو صدا بزنیم بین محتوای Composable و ویژگی تعریف شده فاصله ایجاد میشه.

بازخورد و دیدگاه‌ ها

اولین نفری باشید که در این صفحه نظر می‌دهید

notifications برای اطلاع از جدیدترین مطالب و پست های مرتبط، عضو کانال تلگرام ما بشید.

arrow_drop_up
کپی شد!