,

ساختاردهی به طراحی با Scaffold در Compose

Scaffold in JetBrains compose and jetpack compose

در این بخش از آموزش برنامه نویسی، می‌خوایم در مورد یکی از بهترین ابزارهای Compose صحبت کنیم که کار طراحی رابط کاربری رو برامون حسابی راحت می‌کنه: Scaffold! اگه تا حالا با Compose کار کرده باشید، حتماً می‌دونید که هرچیزی یه کامپوزبل (Composable) خاص خودش رو داره. اما وقتی می‌خوایم یه صفحه کامل بسازیم، مثلاً صفحه‌ای که یه نوار بالایی (Toolbar)، یه نوار پایینی برای جابجایی بین صفحات و یه دکمه شناور اکشن (FAB) داشته باشه، چطوری باید این‌ها رو کنار هم بذاریم که همه‌چیز مرتب و درست سر جاش باشه؟

scaffold in compose

خب، دقیقاً همینجاست که Scaffold هم در جت پک کامپوز اندروید و هم در جت برینز کامپوز در کاتلین مولتی پلتفرم، به کمکمون میاد. Scaffold مثل اسکلت‌بندی یه ساختمون می‌مونه. اون یه ساختار از پیش‌آماده بهمون میده که می‌تونیم اجزای مختلف UI رو روی اون سوار کنیم، بدون اینکه نگران تداخل یا همپوشانی‌شون باشیم. این کار باعث میشه اپلیکیشن ما یه ظاهر منسجم و حرفه‌ای داشته باشه و از اصول طراحی متریال (Material Design) پیروی کنه. پس دیگه لازم نیست کلی کد بنویسیم تا مطمئن شیم نوار پایینی، محتوای اصلی رو نمی‌پوشونه. Scaffold خودش همه‌چیز رو برامون مدیریت می‌کنه.


Scaffold دقیقا چیکار می‌کنه؟

در دنیای طراحی متریال، اکثر اپلیکیشن‌ها یه الگوی ثابت دارن: یه نوار بالا، یه نوار پایین برای ناوبری، یه دکمه شناور برای انجام یه کار مهم و البته، محتوای اصلی صفحه. کامپوزبل Scaffold دقیقاً همین اجزا رو برای ما فراهم می‌کنه. اون مثل یه ظرف بزرگه که یه سری جای خالی مشخص داره که ما می‌تونیم کامپوزبل‌های دیگه رو داخل اون قرار بدیم.

Scaffold پارامترهای مختلفی داره که هر کدوم برای یه بخش از صفحه هستن:

  • topBar: برای نوار بالایی.
  • bottomBar: برای نوار پایینی.
  • floatingActionButton: برای دکمه اکشن شناور.
  • content: برای محتوای اصلی صفحه.

یکی از ویژگی‌های باحال Scaffold اینه که به پارامتر content یه مقدار PaddingValues میده که به ما می‌گه چقدر از بالا و پایین فضای خالی داریم. با این کار، وقتی محتوای اصلی رو داخل Column یا LazyColumn قرار می‌دیم، می‌تونیم این padding رو بهش بدیم تا مطمئن بشیم محتوا از زیر نوار بالا یا پایین رد نمیشه و کاربر می‌تونه به راحتی به تمام قسمت‌ها دسترسی داشته باشه. این مورد مخصوصا برای دنیای اندروید که هر دستگاهی یه فرم و شکلی داره و موقعیت های دوربین جلوش باهم متفاوته خیلی کاربردیه.


بریم سراغ کد و مثال‌ها!

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

اول از همه، باید کتابخانه‌های کامپوز رو به پروژه‌مون اضافه کنیم (اگه از قبل اضافه نیستن).

حالا بیاید یه نگاه به کد کامل بندازیم. این کد یه صفحه ساده با تمام اجزای Scaffold می‌سازه:


@Composable
fun MyScaffoldScreen() {

    // این همون اسکلت‌بندی اصلی ماست
    Scaffold(
        // اینجا نوار بالایی رو تعریف می‌کنیم
        topBar = {
            TopAppBar(
                title = { Text(text = "صفحه اصلی") })
        },
        // اینجا دکمه اکشن شناور رو قرار می‌دیم
        floatingActionButton = {
            FloatingActionButton(
                onClick = { /* وقتی روی دکمه کلیک شد، یه کار خاص انجام بده */ }) {
                Icon(Icons.Filled.Add, contentDescription = "افزودن")
            }
        },
        // و این هم نوار پایینی برای ناوبری
        bottomBar = {
            BottomAppBar() {
                // این Row برای قرار دادن آیکون‌های ناوبری کنار هم هست
                Row(
                    modifier = Modifier.fillMaxWidth(),
                    horizontalArrangement = Arrangement.SpaceAround
                ) {
                    IconButton(onClick = { /* ناوبری به صفحه خانه */ }) {
                        Icon(Icons.Filled.Home, contentDescription = "خانه")
                    }
                    IconButton(onClick = { /* ناوبری به صفحه پروفایل */ }) {
                        Icon(Icons.Filled.Person, contentDescription = "پروفایل")
                    }
                    IconButton(onClick = { /* ناوبری به صفحه تنظیمات */ }) {
                        Icon(Icons.Filled.Settings, contentDescription = "تنظیمات")
                    }
                }
            }
        }
    ) { paddingValues ->
        // این بخش محتوای اصلی صفحه ماست
        // حواستون به paddingValues باشه! این مقدار رو Scaffold بهمون میده تا محتوامون زیر نوار بالا و پایین قایم نشه.
        Column(
            modifier = Modifier
                .padding(paddingValues) // اینجا از PaddingValues استفاده می‌کنیم
                .fillMaxSize(),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = androidx.compose.ui.Alignment.CenterHorizontally
        ) {
            Text(
                text = "به اپلیکیشن من خوش آمدید!",
                style = MaterialTheme.typography.h4
            )
            Spacer(modifier = Modifier.height(16.dp))
            Text(
                text = "این یه نمونه ساده از Scaffold در Jetpack Compose هست.",
            )
        }
    }
}

// برای نمایش پیش‌نمایش در اندروید استودیو
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    MyScaffoldScreen()
}

چرا باید از Scaffold استفاده کنیم؟

استفاده از Scaffold فقط برای اینکه کدمون مرتب به نظر برسه نیست. این ابزار مزایای خیلی مهمی داره:

  1. سرعت توسعه بالا: دیگه لازم نیست برای هر صفحه از اول کد نویسی کنی. فقط کافیه از الگوی آماده Scaffold استفاده کنی و محتوای خودت رو داخلش بذاری.
  2. ثبات و یکپارچگی UI: با استفاده از Scaffold، مطمئن میشی که تمام صفحات اپلیکیشنت یه ظاهر و حس یکسان دارن. این کار تجربه کاربری (UX) رو خیلی بهتر می‌کنه.
  3. پیروی از اصول طراحی متریال: Scaffold کاملاً بر اساس دستورالعمل‌های طراحی متریال گوگل ساخته شده. پس بدون اینکه خودت رو درگیر جزئیات کنی، یه UI مدرن و زیبا خواهی داشت.
  4. مدیریت آسان لایه‌بندی: اون paddingValues که بالاتر در موردش صحبت کردیم، یکی از بزرگترین مزایای Scaffold هست. این ویژگی از تداخل اجزا جلوگیری می‌کنه و بهت اجازه میده بدون دردسر، محتوای صفحه رو طراحی کنی.

خب حالا بریم سراغ یه مثال کامل تر که امکان نمایش پیغام SnackBar هم داشته باشه:



@Composable
fun MyScaffoldWithSnackbarScreen() {
// از یادآوری (remember) استفاده می‌کنیم تا وضعیت Snackbar رو در طول چرخه حیات کامپوزبل نگه داریم
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
    topBar = {
        TopAppBar(
            title = { Text(text = "صفحه اصلی") },
            backgroundColor = MaterialTheme.colors.surface,
            contentColor = MaterialTheme.colors.onSurface
        )
    },
    // این همون دکمه اکشن شناور ماست
    floatingActionButton = {
        FloatingActionButton(
            // وقتی روی دکمه کلیک شد، این کد اجرا میشه
            onClick = {
                // از CoroutineScope برای اجرای کد تعلیقی استفاده می‌کنیم
                scope.launch {
                    // اینجا به SnackbarHostState میگیم که پیام رو نشون بده
                    snackbarHostState.showSnackbar(
                        message = "شما دکمه اکشن شناور را لمس کردید!",
                        actionLabel = "بستن",
                        duration = SnackbarDuration.Short // مدت زمان نمایش
                    )
                }
            },
            backgroundColor = MaterialTheme.colors.primary
        ) {
            Icon(Icons.Filled.Add, contentDescription = "افزودن")
        }
    },
    // این بخش SnackbarHost هست که محل نمایش Snackbar رو مشخص می‌کنه
    snackbarHost = {
        SnackbarHost(hostState = snackbarHostState)
    },
    bottomBar = {
        BottomAppBar(
            backgroundColor = MaterialTheme.colors.surface,
            contentColor = MaterialTheme.colors.onSurface
        ) {
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceAround
            ) {
                IconButton(onClick = { /* ناوبری به صفحه خانه */ }) {
                    Icon(Icons.Filled.Home, contentDescription = "خانه")
                }
                IconButton(onClick = { /* ناوبری به صفحه پروفایل */ }) {
                    Icon(Icons.Filled.Person, contentDescription = "پروفایل")
                }
                IconButton(onClick = { /* ناوبری به صفحه تنظیمات */ }) {
                    Icon(Icons.Filled.Settings, contentDescription = "تنظیمات")
                }
            }
        }
    }
) { paddingValues ->
    // این بخش محتوای اصلی صفحه ماست
    Column(
        modifier = Modifier
            .padding(paddingValues)
            .fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = androidx.compose.ui.Alignment.CenterHorizontally
    ) {
        Text(
            text = "به اپلیکیشن من خوش آمدید!",
            style = MaterialTheme.typography.h4
        )
        Spacer(modifier = Modifier.height(16.dp))
        Text(
            text = "این یه نمونه ساده از Scaffold در Jetpack Compose هست.",
            style = MaterialTheme.typography.body1
        )
    }
}}

نتیجه‌گیری

خلاصه بگم، Scaffold یه ابزار ضروری برای هر توسعه‌دهنده اندرویدیه که با Jetpack Compose کار می‌کنه. اگه می‌خوای UI اپلیکیشنت سریع، مرتب، زیبا و استاندارد باشه، حتماً Scaffold رو تو پروژه‌هات به کار بگیر. با این ابزار، می‌تونی تمرکزت رو بذاری روی منطق برنامه و نه روی اینکه هر جزء کجا باید قرار بگیره.

Comments

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *