Jetpack Compose

آموزش کار با Jetpack Compose در اندروید

آموزش Jetpack Compose در اندروید

در دنیای توسعه اپلیکیشن‌های مدرن اندروید، شیوه طراحی رابط کاربری در سال‌های اخیر دستخوش تحول بزرگی شده است. رویکرد سنتی مبتنی بر فایل‌های XML که سال‌ها به‌عنوان استاندارد توسعه رابط کاربری در اندروید شناخته می‌شد، اکنون جای خود را به روشی مدرن، سریع و انعطاف‌پذیر داده است. گوگل با معرفی Jetpack Compose تلاش کرده تا فرآیند ساخت رابط کاربری را ساده‌تر کرده و تجربه توسعه‌دهندگان را به شکل چشمگیری بهبود دهد.

Jetpack Compose یک فریم‌ورک مدرن برای ساخت رابط کاربری در اندروید است که به‌صورت کامل با زبان Kotlin توسعه یافته و بخشی از مجموعه ابزارهای Jetpack محسوب می‌شود. این فناوری به توسعه‌دهندگان اجازه می‌دهد بدون نیاز به XML و با استفاده از کدهای Kotlin، رابط‌های کاربری پویا، قابل نگهداری و مقیاس‌پذیر ایجاد کنند. همچنین قابلیت‌هایی مانند مدیریت آسان وضعیت، پیش‌نمایش زنده رابط کاربری و کاهش حجم کدهای تکراری باعث شده‌اند که Compose به انتخاب اصلی بسیاری از توسعه‌دهندگان اندروید تبدیل شود.

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

Jetpack Compose چیست؟

Jetpack Compose یک فریم‌ورک مدرن برای طراحی رابط کاربری در اندروید است که بر پایه رویکرد Declarative UI توسعه یافته است. در این مدل، توسعه‌دهنده تنها وضعیت و ظاهر موردنیاز رابط کاربری را توصیف می‌کند و سیستم به‌صورت خودکار تغییرات لازم را در صفحه اعمال می‌کند.

در روش سنتی توسعه اندروید، ابتدا رابط کاربری با استفاده از فایل‌های XML طراحی می‌شد و سپس منطق برنامه در فایل‌های Java یا Kotlin به آن متصل می‌گردید. این جداسازی میان لایه رابط کاربری و منطق برنامه معمولاً باعث افزایش حجم کدها، پیچیدگی نگهداری و دشوار شدن اعمال تغییرات می‌شد.

اما در Jetpack Compose همه‌چیز در یک زبان و یک محیط توسعه انجام می‌شود. رابط کاربری مستقیماً با Kotlin نوشته می‌شود و اجزای UI بر اساس State یا وضعیت برنامه ساخته و به‌روزرسانی می‌شوند. هر زمان که وضعیت داده‌ها تغییر کند، Compose تنها بخش‌های موردنیاز رابط کاربری را مجدداً رسم می‌کند و همین موضوع باعث افزایش کارایی، خوانایی و سرعت توسعه می‌شود.

طراحی رابط کاربری با Kotlin و Jetpack Compose

طراحی رابط کاربری با Kotlin و Jetpack Compose

در روش سنتی:

  • شما XML می‌نوشتید
  • سپس در Kotlin/Java آن را کنترل می‌کردید

اما در Compose:

  • همه‌چیز در Kotlin نوشته می‌شود
  • UI بر اساس State ساخته می‌شود

تفاوت Compose با XML

یکی از مهم‌ترین دلایل محبوبیت Jetpack Compose، تفاوت اساسی آن با روش سنتی طراحی رابط کاربری مبتنی بر XML است. در توسعه کلاسیک اندروید، رابط کاربری در فایل‌های XML تعریف می‌شد و سپس منطق برنامه در فایل‌های Kotlin یا Java به آن متصل می‌گردید. این جداسازی اگرچه سال‌ها استاندارد توسعه اندروید بود، اما در پروژه‌های بزرگ باعث افزایش پیچیدگی و دشواری نگهداری کدها می‌شد.

در مقابل، Jetpack Compose تمام بخش‌های رابط کاربری را مستقیماً در Kotlin پیاده‌سازی می‌کند. این موضوع باعث می‌شود کدها خواناتر، قابل نگهداری‌تر و توسعه آن‌ها سریع‌تر باشد. همچنین تغییر وضعیت داده‌ها به‌صورت خودکار باعث به‌روزرسانی رابط کاربری می‌شود و دیگر نیازی به فراخوانی متدهایی مانند findViewById یا مدیریت دستی Viewها وجود ندارد.

مهم‌ترین تفاوت‌های Compose و XML عبارت‌اند از:

  • در XML رابط کاربری و منطق برنامه در فایل‌های جداگانه قرار دارند، اما در Compose همه چیز در Kotlin نوشته می‌شود.
  • در XML تغییرات رابط کاربری معمولاً به‌صورت دستی انجام می‌شود، در حالی که Compose بر اساس State به‌صورت خودکار UI را به‌روزرسانی می‌کند.
  • در XML برای دسترسی به ویوها از View Binding یا findViewById استفاده می‌شود، اما در Compose چنین نیازی وجود ندارد.
  • پیش‌نمایش رابط کاربری در Compose بسیار سریع‌تر بوده و بدون اجرای کامل برنامه امکان مشاهده تغییرات وجود دارد.
  • نگهداری و توسعه پروژه‌های بزرگ در Compose ساده‌تر و انعطاف‌پذیرتر است.

به همین دلیل، گوگل Jetpack Compose را به‌عنوان آینده توسعه رابط کاربری اندروید معرفی کرده و بسیاری از پروژه‌های جدید اندروید امروزه بر پایه این فناوری توسعه داده می‌شوند.

فعال‌سازی Jetpack Compose در پروژه

برای استفاده از Jetpack Compose ابتدا باید پشتیبانی از آن را در پروژه اندروید خود فعال کنید. خوشبختانه در نسخه‌های جدید Android Studio هنگام ایجاد یک پروژه جدید می‌توانید مستقیماً قالب Compose را انتخاب کنید، اما در پروژه‌های موجود لازم است چند تنظیم اولیه را انجام دهید.

ابتدا باید قابلیت Compose را در فایل build.gradle ماژول اپلیکیشن فعال کنید و نسخه مناسب Kotlin Compiler را مشخص نمایید. همچنین وابستگی‌های موردنیاز Compose مانند ui، material3 و ui-tooling-preview باید به پروژه اضافه شوند.

پس از فعال‌سازی، دیگر نیازی به ایجاد فایل‌های XML برای طراحی صفحات نخواهید داشت. رابط کاربری به‌صورت مستقیم در توابع Kotlin نوشته می‌شود و هر بخش از UI در قالب یک Composable Function تعریف می‌گردد.

یکی از مزایای مهم این رویکرد، امکان مشاهده پیش‌نمایش رابط کاربری در Android Studio بدون اجرای برنامه است. این قابلیت باعث می‌شود توسعه‌دهندگان بتوانند تغییرات ظاهری را سریع‌تر بررسی کرده و فرآیند طراحی رابط کاربری را با سرعت بیشتری انجام دهند.

ساخت اولین پروژه با Jetpack Compose

ساخت اولین پروژه با Jetpack Compose

در بخش‌های بعدی مقاله، اولین Composable را ایجاد کرده و نحوه ساخت یک رابط کاربری ساده با Jetpack Compose را به‌صورت عملی بررسی خواهیم کرد.

تنظیم Gradle

buildFeatures {
    compose true
}

composeOptions {
    kotlinCompilerExtensionVersion = "1.5.3"
}

ساخت اولین UI با Compose

در Jetpack Compose برخلاف روش سنتی XML، رابط کاربری با استفاده از توابع Kotlin ساخته می‌شود. این توابع که با @Composable مشخص می‌شوند، مسئول نمایش بخش‌های مختلف رابط کاربری هستند.

برای مثال، اگر بخواهیم یک متن ساده را در صفحه نمایش دهیم، کافی است یک تابع Composable ایجاد کنیم:

@Composable
fun Greeting() {
    Text(text = "Hello Jetpack Compose")
}

در این مثال، تابع Greeting یک کامپوننت رابط کاربری ایجاد می‌کند که متن «Hello Jetpack Compose» را نمایش می‌دهد. هر تابع Composable می‌تواند شامل سایر Composableها باشد و به این ترتیب رابط‌های کاربری پیچیده از ترکیب چندین جزء کوچک‌تر ساخته می‌شوند.

برای نمایش این رابط کاربری در اکتیویتی، از متد setContent استفاده می‌کنیم:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            Greeting()
        }
    }
}

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

در Compose تقریباً تمام اجزای رابط کاربری مانند متن، دکمه، تصویر، لیست و فرم‌ها به‌صورت Composable ارائه می‌شوند و توسعه‌دهنده می‌تواند آن‌ها را مانند توابع معمولی با یکدیگر ترکیب کند.

پیش‌نمایش رابط کاربری در Android Studio

پیش‌نمایش رابط کاربری در Android Studio

مفهوم مهم: @Composable

یکی از مهم‌ترین مفاهیم در Jetpack Compose، Annotation با نام @Composable است. هر تابعی که وظیفه تولید یا نمایش بخشی از رابط کاربری را بر عهده دارد، باید با این Annotation مشخص شود.

@Composable
fun WelcomeText() {
    Text(text = "Welcome to Compose")
}

زمانی که یک تابع با @Composable مشخص می‌شود، کامپایلر Kotlin آن را به‌عنوان یک جزء رابط کاربری شناسایی می‌کند. این توابع می‌توانند سایر Composableها را فراخوانی کنند و با ترکیب آن‌ها، صفحات و رابط‌های کاربری پیچیده ساخته شوند.

برخلاف توابع معمولی، توابع Composable تنها از داخل سایر Composableها یا درون بلوک setContent قابل فراخوانی هستند. این محدودیت باعث می‌شود ساختار رابط کاربری منظم‌تر و قابل پیش‌بینی‌تر باشد.

یکی دیگر از ویژگی‌های مهم @Composable این است که Compose می‌تواند هنگام تغییر داده‌ها، تنها بخش‌هایی از رابط کاربری را که به‌روزرسانی شده‌اند مجدداً رسم کند. این فرآیند که Recomposition نام دارد، یکی از دلایل اصلی عملکرد سریع و بهینه Jetpack Compose محسوب می‌شود.

به بیان ساده، هر زمان که بخواهید یک دکمه، متن، کارت، فرم یا هر بخش دیگری از رابط کاربری را ایجاد کنید، باید آن را در قالب یک تابع @Composable تعریف کنید.

ساخت صفحه کامل با Compose

@Composable
fun MainScreen() {

    Column {

        Text(
            text = "صفحه اصلی",
        )

        Button(onClick = {}) {
            Text("کلیک کن")
        }
    }
}

مدیریت State در Jetpack Compose

یکی از مهم‌ترین مفاهیم در Jetpack Compose، مدیریت State یا وضعیت است. در Compose رابط کاربری مستقیماً بر اساس داده‌ها و وضعیت برنامه ساخته می‌شود. به عبارت دیگر، هر زمان که State تغییر کند، رابط کاربری نیز به‌صورت خودکار به‌روزرسانی خواهد شد.

برای نگهداری وضعیت در Compose معمولاً از remember و mutableStateOf استفاده می‌شود:

@Composable
fun CounterScreen() {
    var count by remember {
        mutableStateOf(0)
    }

    Column {
        Text(text = "Count: $count")

        Button(
            onClick = {
                count++
            }
        ) {
            Text("Increase")
        }
    }
}

در این مثال، متغیر count به‌عنوان یک State تعریف شده است. هر بار که کاربر روی دکمه کلیک می‌کند، مقدار count افزایش می‌یابد و Compose به‌صورت خودکار متن نمایش داده‌شده را به‌روزرسانی می‌کند.

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

این فرآیند که Recomposition نام دارد، یکی از مهم‌ترین ویژگی‌های Jetpack Compose است و باعث می‌شود توسعه رابط کاربری ساده‌تر، خواناتر و قابل نگهداری‌تر شود. به همین دلیل، درک صحیح مفهوم State یکی از مهم‌ترین مهارت‌ها برای یادگیری Compose محسوب می‌شود.

چرخه عمر Composableها در Jetpack Compose

چرخه عمر Composableها در Jetpack Compose

تابع remember در Jetpack Compose

یکی از توابع مهم در مدیریت State در Jetpack Compose، تابع remember است. این تابع باعث می‌شود مقدار یک State در زمان Recomposition حفظ شود و با هر بار بازسازی رابط کاربری مجدداً مقداردهی نشود.

var count by remember {
    mutableStateOf(0)
}

در این مثال، مقدار count تنها یک‌بار مقداردهی اولیه می‌شود و در طول Recomposition حفظ خواهد شد. هر زمان که مقدار این State تغییر کند، Compose تنها بخش‌های مرتبط با آن را مجدداً رسم می‌کند.

اگر از remember استفاده نکنیم، متغیر در هر بار اجرای مجدد تابع Composable دوباره ایجاد شده و مقدار اولیه خود را دریافت می‌کند:

var count = 0

در این حالت، با هر Recomposition مقدار count دوباره صفر می‌شود و تغییرات کاربر از بین می‌رود. به همین دلیل، remember نقش بسیار مهمی در نگهداری وضعیت رابط کاربری دارد.

البته باید توجه داشت که remember تنها تا زمانی که Composable در حافظه وجود داشته باشد، مقدار را نگه می‌دارد. اگر Activity از بین برود یا پیکربندی دستگاه تغییر کند، این مقدار نیز از دست می‌رود. در چنین شرایطی می‌توان از rememberSaveable استفاده کرد تا State حتی پس از تغییراتی مانند چرخش صفحه نمایش نیز حفظ شود.

کامپوننت‌ ها و Material Design

کامپوننت‌ ها و Material Design

Column و Row در Jetpack Compose

برای چیدمان عناصر در Jetpack Compose معمولاً از دو کامپوننت پایه به نام‌های Column و Row استفاده می‌شود. این دو کامپوننت نقش بسیار مهمی در طراحی رابط کاربری دارند و تا حد زیادی جایگزین Layoutهای سنتی مانند LinearLayout در XML شده‌اند.

کامپوننت Column عناصر را به‌صورت عمودی زیر یکدیگر قرار می‌دهد. هر Composable که داخل یک Column قرار بگیرد، در سطر جدید نمایش داده می‌شود.

Column {
    Text("Android")
    Text("Jetpack Compose")
    Button(onClick = { }) {
        Text("Click")
    }
}

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

در مقابل، Row عناصر را به‌صورت افقی در کنار یکدیگر قرار می‌دهد:

Row {
    Text("Name:")
    Text("Farzad")
}

در اینجا دو متن در یک ردیف و کنار هم نمایش داده می‌شوند.

علاوه بر این، Column و Row امکانات متعددی برای مدیریت فاصله، تراز و نحوه قرارگیری عناصر در اختیار توسعه‌دهنده قرار می‌دهند. برای مثال می‌توان از horizontalAlignment و verticalArrangement برای تنظیم موقعیت عناصر استفاده کرد.

Column(
    verticalArrangement = Arrangement.Center,
    horizontalAlignment = Alignment.CenterHorizontally
) {
    Text("Hello Compose")
    Button(onClick = {}) {
        Text("Start")
    }
}

به‌طور کلی، Column برای چیدمان عمودی و Row برای چیدمان افقی استفاده می‌شوند و تقریباً در تمام رابط‌های کاربری Compose نقش اساسی دارند. ترکیب این دو کامپوننت به شما امکان می‌دهد ساختارهای پیچیده و انعطاف‌پذیری را بدون نیاز به XML طراحی کنید.

Modifier چیست؟

یکی از مهم‌ترین مفاهیم در Jetpack Compose، کلاس Modifier است. تقریباً تمام کامپوننت‌های Compose از Modifier برای کنترل ظاهر، اندازه و نحوه قرارگیری عناصر در رابط کاربری استفاده می‌کنند.

Modifier به شما اجازه می‌دهد ویژگی‌های مختلفی را به یک Composable اضافه کنید، از جمله:

  • تعیین اندازه (size, width, height)
  • ایجاد فاصله داخلی و خارجی (padding)
  • تعیین رنگ پس‌زمینه (background)
  • تنظیم موقعیت و تراز عناصر (alignment)
  • مدیریت کلیک و تعامل کاربر (clickable)
  • افزودن حاشیه و گوشه‌های گرد (border, clip)

برای مثال:

Text(
    text = "Hello Compose",
    modifier = Modifier
        .padding(16.dp)
        .background(Color.LightGray)
)

در این مثال، ابتدا برای متن ۱۶dp فاصله داخلی در نظر گرفته شده و سپس یک رنگ پس‌زمینه به آن اضافه شده است.

یکی از ویژگی‌های مهم Modifier، قابلیت زنجیره‌ای (Chaining) آن است. یعنی می‌توانید چندین Modifier را پشت سر هم قرار دهید:

Button(
    onClick = {},
    modifier = Modifier
        .fillMaxWidth()
        .padding(16.dp)
        .height(56.dp)
) {
    Text("Login")
}

در این مثال، دکمه تمام عرض صفحه را اشغال می‌کند، دارای فاصله داخلی ۱۶dp است و ارتفاع آن ۵۶dp تعیین شده است.

ترتیب Modifierها نیز اهمیت زیادی دارد، زیرا هر Modifier روی نتیجه Modifier قبلی تأثیر می‌گذارد. به همین دلیل، درک صحیح نحوه استفاده از Modifier یکی از مهم‌ترین مهارت‌ها در طراحی رابط کاربری با Jetpack Compose محسوب می‌شود.

طراحی رابط کاربری با Jetpack Compose

طراحی رابط کاربری با Jetpack Compose

ساخت Button در Jetpack Compose

ایجاد دکمه در Jetpack Compose بسیار ساده‌تر از روش سنتی XML است. در Compose از کامپوننت Button برای ساخت دکمه استفاده می‌شود و منطق کلیک و محتوای دکمه در همان محل تعریف می‌شود.

یک دکمه ساده به شکل زیر ایجاد می‌شود:

Button(
    onClick = {
        // عملیات هنگام کلیک
    }
) {
    Text("Click Me")
}

در این مثال، پارامتر onClick مشخص می‌کند که هنگام کلیک روی دکمه چه عملی باید انجام شود و محتوای داخل آکولاد دوم، ظاهر دکمه را تعیین می‌کند. در اینجا یک متن با عنوان «Click Me» داخل دکمه نمایش داده شده است.

همچنین می‌توان با استفاده از Modifier ظاهر دکمه را تغییر داد:

Button(
    onClick = {},
    modifier = Modifier
        .fillMaxWidth()
        .padding(16.dp)
        .height(50.dp)
) {
    Text("Login")
}

در این مثال، دکمه تمام عرض صفحه را اشغال می‌کند، دارای فاصله داخلی ۱۶dp است و ارتفاع آن ۵۰dp تنظیم شده است.

یکی از مزایای Compose این است که محتوای دکمه محدود به متن نیست. شما می‌توانید آیکون، تصویر یا چندین کامپوننت را داخل دکمه قرار دهید:

Button(onClick = {}) {
    Icon(
        imageVector = Icons.Default.Favorite,
        contentDescription = null
    )
    Spacer(modifier = Modifier.width(8.dp))
    Text("Favorite")
}

علاوه بر Button، کامپوننت‌های دیگری مانند OutlinedButton، TextButton و ElevatedButton نیز در Material Design ارائه شده‌اند که برای طراحی انواع مختلف دکمه‌ها مورد استفاده قرار می‌گیرند.

Image در Jetpack Compose

برای نمایش تصاویر در Jetpack Compose از کامپوننت Image استفاده می‌شود. این کامپوننت امکان نمایش تصاویر محلی، آیکون‌ها و حتی تصاویر دانلودشده از اینترنت را فراهم می‌کند.

برای نمایش یک تصویر موجود در پوشه drawable می‌توان از painterResource استفاده کرد:

Image(
    painter = painterResource(R.drawable.profile),
    contentDescription = "Profile Image"
)

در این مثال، تصویر profile از پوشه drawable بارگذاری و نمایش داده می‌شود. پارامتر contentDescription برای دسترس‌پذیری (Accessibility) استفاده می‌شود و به ابزارهای کمکی مانند Screen Reader کمک می‌کند تا محتوای تصویر را برای کاربران توضیح دهند.

با استفاده از Modifier می‌توان اندازه و ظاهر تصویر را تغییر داد:

Image(
    painter = painterResource(R.drawable.profile),
    contentDescription = null,
    modifier = Modifier
        .size(120.dp)
        .clip(CircleShape)
)

در این مثال، تصویر با اندازه ۱۲۰dp نمایش داده شده و به شکل دایره‌ای برش خورده است.

همچنین می‌توان نحوه نمایش تصویر را با استفاده از contentScale کنترل کرد:

Image(
    painter = painterResource(R.drawable.banner),
    contentDescription = null,
    modifier = Modifier.fillMaxWidth(),
    contentScale = ContentScale.Crop
)

مقدار ContentScale.Crop باعث می‌شود تصویر کل فضای موجود را پر کند و بخش‌های اضافی آن برش داده شوند.

برای بارگذاری تصاویر از اینترنت معمولاً از کتابخانه‌هایی مانند Coil استفاده می‌شود:

AsyncImage(
    model = "https://example.com/image.jpg",
    contentDescription = "Network Image"
)

به‌طور کلی، کامپوننت Image در Compose انعطاف‌پذیری بسیار بالایی دارد و با ترکیب آن با Modifier می‌توان انواع تصاویر، آواتارها، بنرها و گالری‌های تصویری را به‌سادگی طراحی کرد.

LazyColumn (لیست حرفه‌ای در Jetpack Compose)

نمایش لیست‌ها یکی از رایج‌ترین نیازها در توسعه اپلیکیشن‌های اندروید است. در Jetpack Compose برای ایجاد لیست‌های اسکرول‌شونده از LazyColumn استفاده می‌شود. این کامپوننت معادل RecyclerView در سیستم Viewهای سنتی محسوب می‌شود.

دلیل استفاده از واژه Lazy این است که تنها آیتم‌هایی که در صفحه قابل مشاهده هستند ایجاد و رندر می‌شوند. به همین دلیل، LazyColumn حتی در لیست‌های بزرگ نیز عملکرد بسیار خوبی دارد و مصرف حافظه را کاهش می‌دهد.

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

LazyColumn {
    items(100) { index ->
        Text(
            text = "Item $index",
            modifier = Modifier.padding(16.dp)
        )
    }
}

در این مثال، ۱۰۰ آیتم در یک لیست اسکرول‌شونده نمایش داده می‌شوند. Compose تنها آیتم‌های قابل مشاهده را رسم می‌کند و هنگام اسکرول، آیتم‌های جدید را به‌صورت خودکار ایجاد می‌کند.

همچنین می‌توان لیستی از داده‌ها را نمایش داد:

val users = listOf("Ali", "Sara", "Reza")

LazyColumn {
    items(users) { user ->
        Text(
            text = user,
            modifier = Modifier.padding(16.dp)
        )
    }
}

برای ایجاد فاصله بین آیتم‌ها و اعمال تنظیمات بیشتر نیز می‌توان از پارامترهای مختلف استفاده کرد:

LazyColumn(
    verticalArrangement = Arrangement.spacedBy(8.dp),
    contentPadding = PaddingValues(16.dp)
) {
    items(users) { user ->
        Card {
            Text(
                text = user,
                modifier = Modifier.padding(16.dp)
            )
        }
    }
}

LazyColumn یکی از مهم‌ترین کامپوننت‌های Compose محسوب می‌شود و در پیاده‌سازی صفحاتی مانند لیست پیام‌ها، محصولات فروشگاه، شبکه‌های اجتماعی و فید اخبار کاربرد فراوانی دارد. اگر در XML از RecyclerView استفاده می‌کردید، در Compose تقریباً در اکثر موارد از LazyColumn استفاده خواهید کرد.

Navigation در Jetpack Compose

در هر اپلیکیشن اندرویدی معمولاً چندین صفحه یا Screen وجود دارد و کاربر باید بتواند بین آن‌ها جابه‌جا شود. در Jetpack Compose این وظیفه بر عهده کتابخانه Navigation Compose است که مدیریت مسیرها و انتقال بین صفحات را ساده‌تر می‌کند.

برای استفاده از Navigation ابتدا باید وابستگی مربوط به navigation-compose را به پروژه اضافه کنید. سپس با استفاده از NavController و NavHost مسیرهای مختلف برنامه را تعریف می‌کنیم.

ابتدا یک کنترلر ناوبری ایجاد می‌شود:

val navController = rememberNavController()

سپس صفحات برنامه داخل NavHost تعریف می‌شوند:

NavHost(
    navController = navController,
    startDestination = "home"
) {
    composable("home") {
        HomeScreen(navController)
    }

    composable("profile") {
        ProfileScreen(navController)
    }
}

در این مثال، صفحه home به‌عنوان صفحه اولیه برنامه در نظر گرفته شده و صفحه دیگری با نام profile نیز تعریف شده است.

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

Button(
    onClick = {
        navController.navigate("profile")
    }
) {
    Text("Go to Profile")
}

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

navController.popBackStack()

یکی از مزایای Navigation Compose، پشتیبانی از ارسال پارامتر بین صفحات، مدیریت Back Stack و ساختاردهی بهتر پروژه است. به همین دلیل، تقریباً تمام اپلیکیشن‌های مدرن Compose برای مدیریت صفحات و مسیریابی از این کتابخانه استفاده می‌کنند.

مزایای Jetpack Compose

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

یکی از مهم‌ترین مزایای Compose، کاهش حجم کدها است. در روش سنتی، توسعه‌دهندگان باید رابط کاربری را در XML طراحی کرده و سپس منطق آن را در فایل‌های Kotlin یا Java پیاده‌سازی می‌کردند. اما در Compose تمام بخش‌های UI در Kotlin نوشته می‌شوند و این موضوع باعث افزایش خوانایی و کاهش کدهای تکراری می‌شود.

مزیت دیگر، توسعه سریع‌تر رابط کاربری است. قابلیت Preview در Android Studio به توسعه‌دهندگان اجازه می‌دهد بدون اجرای کامل برنامه، تغییرات رابط کاربری را مشاهده کنند. این ویژگی زمان طراحی و تست UI را به‌طور قابل‌توجهی کاهش می‌دهد.

Compose همچنین از مدیریت State به‌صورت داخلی پشتیبانی می‌کند. با تغییر داده‌ها، رابط کاربری به‌صورت خودکار به‌روزرسانی می‌شود و نیازی به مدیریت دستی Viewها یا فراخوانی متدهای مختلف برای تغییر UI وجود ندارد.

از دیگر مزایای مهم Jetpack Compose می‌توان به موارد زیر اشاره کرد:

کاهش کدهای XML و حذف findViewById
توسعه سریع‌تر و نگهداری آسان‌تر پروژه‌ها
پشتیبانی کامل از Kotlin
امکان پیش‌نمایش زنده رابط کاربری
عملکرد مناسب به دلیل Recomposition هوشمند
سازگاری با معماری‌های مدرن مانند MVVM
ادغام آسان با ViewModel و Coroutines
پشتیبانی کامل از Material Design 3
قابلیت استفاده در پروژه‌های جدید و پروژه‌های قدیمی به‌صورت هم‌زمان

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

بهترین روش‌ها (Best Practices) در Jetpack Compose

با افزایش اندازه پروژه‌های Compose، رعایت برخی اصول و بهترین روش‌ها اهمیت زیادی پیدا می‌کند. این نکات باعث می‌شوند کدها خواناتر، قابل نگهداری‌تر و عملکرد برنامه بهینه‌تر شود.

1. Composableهای کوچک و قابل استفاده مجدد بنویسید

به‌جای ایجاد توابع بسیار بزرگ، رابط کاربری را به کامپوننت‌های کوچک‌تر تقسیم کنید.

@Composable
fun UserAvatar() { ... }

@Composable
fun UserInfo() { ... }

@Composable
fun UserCard() {
    Row {
        UserAvatar()
        UserInfo()
    }
}

این رویکرد باعث افزایش خوانایی و قابلیت استفاده مجدد از کامپوننت‌ها می‌شود.

2. State را تا حد امکان بالا نگه دارید

بهتر است State در سطوح بالاتر مدیریت شود و از طریق پارامترها به Composableها ارسال شود. این الگو که State Hoisting نام دارد، تست‌پذیری و نگهداری کد را بهبود می‌دهد.

@Composable
fun Counter(
    count: Int,
    onIncrement: () -> Unit
) {
    Button(onClick = onIncrement) {
        Text("$count")
    }
}

3. از ViewModel برای مدیریت داده‌ها استفاده کنید

Stateهای مربوط به منطق کسب‌وکار نباید داخل Composableها نگهداری شوند. بهتر است این داده‌ها در ViewModel قرار بگیرند و UI فقط آن‌ها را نمایش دهد.

4. از LazyColumn برای لیست‌های بزرگ استفاده کنید

برای نمایش تعداد زیادی آیتم، همیشه از LazyColumn و LazyRow استفاده کنید تا تنها آیتم‌های قابل مشاهده رندر شوند و عملکرد برنامه بهبود یابد.

5. Modifierها را به‌درستی استفاده کنید

Modifierها را به‌صورت زنجیره‌ای و خوانا بنویسید و در صورت امکان آن‌ها را به Composableها به‌عنوان پارامتر ارسال کنید تا قابلیت استفاده مجدد افزایش پیدا کند.

@Composable
fun ProfileImage(
    modifier: Modifier = Modifier
) {
    Image(
        painter = painterResource(R.drawable.profile),
        contentDescription = null,
        modifier = modifier
    )
}

6. از remember فقط برای Stateهای موقت استفاده کنید

remember برای نگهداری وضعیت‌های مربوط به UI مناسب است، اما داده‌های مهم و طولانی‌مدت بهتر است در ViewModel یا لایه‌های بالاتر ذخیره شوند.

7. از rememberSaveable برای حفظ State استفاده کنید

اگر می‌خواهید داده‌ها پس از چرخش صفحه یا تغییر پیکربندی حفظ شوند، از rememberSaveable استفاده کنید.

8. از Preview برای توسعه سریع‌تر استفاده کنید

قابلیت @Preview به شما امکان می‌دهد بدون اجرای اپلیکیشن، رابط کاربری را مشاهده و آزمایش کنید.

@Preview
@Composable
fun GreetingPreview() {
    Greeting()
}

9. از Material Design 3 استفاده کنید

کامپوننت‌های Material 3 ظاهر مدرن‌تری دارند و با طراحی‌های جدید اندروید هماهنگ هستند.

10. از Recomposition غیرضروری جلوگیری کنید

سعی کنید Stateها را به‌درستی مدیریت کنید تا فقط بخش‌های موردنیاز رابط کاربری مجدداً رسم شوند. این موضوع تأثیر مستقیمی بر عملکرد اپلیکیشن دارد.

رعایت این اصول باعث می‌شود پروژه‌های Compose مقیاس‌پذیرتر، خواناتر و نگهداری آن‌ها در بلندمدت ساده‌تر باشد. بسیاری از این الگوها در پروژه‌های حرفه‌ای و تیم‌های بزرگ توسعه اندروید به‌عنوان استاندارد استفاده می‌شوند.

جمع‌بندی

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

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

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