# 1. مشکل از کجا شروع شد؟ قبل از Jetpack Compose در اندروید، وقتی داده‌ای در برنامه تغییر می‌کرد باید **خودمان دستی UI را آپدیت می‌کردیم**. مثال: کاربر روی دکمه افزایش کلیک می‌کند → مقدار عدد تغییر می‌کند → باید TextView را هم تغییر دهیم. در View های قدیمی: ```kotlin count++ textView.text = count.toString() ``` یعنی برنامه‌نویس **باید یادش بماند UI را هم آپدیت کند**. مشکل‌ها: - ممکن است فراموش کنیم UI را آپدیت کنیم - کدها پیچیده می‌شوند - نگهداری سخت می‌شود --- # 2. راه‌حل Compose چیست؟ در Compose یک قانون مهم داریم: **UI باید تابعی از State باشد** یعنی: ``` UI = f(state) ``` اگر state تغییر کند → UI خودش دوباره ساخته می‌شود. به این فرایند می‌گوییم: **Recomposition** --- # 3. State چیست؟ State یعنی: **داده‌ای که اگر تغییر کند، UI باید تغییر کند.** مثال‌ها: - مقدار counter - متن داخل TextField - وضعیت لودینگ - لیست پیام‌ها - وضعیت لاگین کاربر مثال ساده: ```kotlin var count = 0 ``` اگر مقدار `count` تغییر کند، UI باید تغییر کند. اما Compose از تغییر این متغیر خبر ندارد. پس باید از **State مخصوص Compose** استفاده کنیم. --- # 4. mutableStateOf چیست؟ برای اینکه Compose بفهمد داده تغییر کرده باید از **State Object** استفاده کنیم. یکی از مهم‌ترین آن‌ها: ``` mutableStateOf ``` مثال: ```kotlin var count = mutableStateOf(0) ``` اینجا count یک **State** است. برای دسترسی به مقدار: ``` count.value ``` مثال: ```kotlin count.value++ ``` وقتی مقدار تغییر کند: Compose متوجه می‌شود → UI دوباره ساخته می‌شود. --- # 5. استفاده از State در Compose یک مثال ساده Counter: ```kotlin @Composable fun CounterScreen() { var count = remember { mutableStateOf(0) } Column { Text(text = "Count: ${count.value}") Button(onClick = { count.value++ }) { Text("Increase") } } } ``` اتفاقی که می‌افتد: 1️⃣ صفحه ساخته می‌شود 2️⃣ مقدار count = 0 3️⃣ Text مقدار 0 را نشان می‌دهد 4️⃣ کاربر دکمه را می‌زند 5️⃣ مقدار count تغییر می‌کند 6️⃣ Compose تشخیص می‌دهد state تغییر کرده 7️⃣ UI دوباره اجرا می‌شود این فرایند همان **Recomposition** است. --- # 6. Recomposition چیست؟ **Recomposition یعنی اجرای دوباره Composable ها وقتی State تغییر می‌کند.** در مثال قبل: وقتی: ``` count.value++ ``` اجرا می‌شود Compose: - متوجه تغییر state می‌شود - Composable مربوطه را دوباره اجرا می‌کند - UI جدید رسم می‌شود نکته مهم: Compose **کل صفحه را دوباره نمی‌سازد** فقط بخش‌هایی که نیاز دارند دوباره اجرا می‌شوند. --- # 7. remember چیست؟ یک مشکل مهم وجود دارد. اگر این کد را بنویسیم: ```kotlin var count = mutableStateOf(0) ``` در هر Recomposition مقدار دوباره **0 می‌شود**. چرا؟ چون تابع دوباره اجرا می‌شود. برای حل این مشکل از: ``` remember ``` استفاده می‌کنیم. ```kotlin var count = remember { mutableStateOf(0) } ``` remember باعث می‌شود: ✅ مقدار بین recomposition ها حفظ شود. --- # 8. روش بهتر: by delegation نوشتن `.value` کمی آزاردهنده است. روش بهتر: ```kotlin var count by remember { mutableStateOf(0) } ``` حالا می‌توانیم مستقیم استفاده کنیم: ```kotlin count++ ``` مثال کامل: ```kotlin @Composable fun CounterScreen() { var count by remember { mutableStateOf(0) } Column { Text(text = "Count: $count") Button(onClick = { count++ }) { Text("Increase") } } } ``` --- # 9. جریان کامل اتفاقات مراحل اجرای برنامه: 1️⃣ Composable اجرا می‌شود 2️⃣ State ساخته می‌شود 3️⃣ UI بر اساس State ساخته می‌شود وقتی کاربر دکمه را می‌زند: 4️⃣ State تغییر می‌کند 5️⃣ Compose تغییر را تشخیص می‌دهد 6️⃣ Recomposition انجام می‌شود 7️⃣ UI جدید ساخته می‌شود --- # 10. مثال Counter کامل ```kotlin @Composable fun CounterScreen() { var count by remember { mutableStateOf(0) } Column { Text( text = "Count: $count", fontSize = 30.sp ) Button( onClick = { count++ } ) { Text("Increase") } Button( onClick = { count-- } ) { Text("Decrease") } } } ``` --- # 11. نکات مهم ✅ State داده‌ای است که UI به آن وابسته است. ✅ وقتی State تغییر کند → Recomposition اتفاق می‌افتد. ✅ برای تعریف State از `mutableStateOf` استفاده می‌کنیم. ✅ برای حفظ مقدار در Recomposition از `remember` استفاده می‌کنیم. ✅ بهتر است از `by` استفاده کنیم تا `.value` حذف شود. --- # 12. تمرین برای دانشجویان 1️⃣ یک Counter بسازید که دکمه‌های زیر داشته باشد: - Increase - Decrease - Reset 2️⃣ اگر مقدار Counter به **10 رسید** یک متن نمایش دهید: ``` Maximum reached! ``` 3️⃣ اگر مقدار Counter **منفی شد** رنگ متن قرمز شود. --- # 13. چالش فکری اگر به جای State این کد را بنویسیم: ```kotlin var count = 0 ``` و در Button مقدار را زیاد کنیم: ``` count++ ``` آیا UI تغییر می‌کند؟ چرا؟ --- پاسخ: خیر. چون Compose از تغییر این متغیر خبر ندارد. بنابراین Recomposition اتفاق نمی‌افتد. --- # جمع‌بندی مهم‌ترین مفاهیم Compose: - State → داده قابل تغییر UI - mutableStateOf → ساخت state - remember → نگهداری مقدار در recomposition - Recomposition → اجرای دوباره UI بعد از تغییر state قانون اصلی Compose: **UI تابعی از State است.**