Codeit Mobile
94 subscribers
3 photos
1 video
243 links
📱 آموزش برنامه‌نویسی موبایل

Kotlin • Android

🚀 آموزش ساده، کاربردی و پروژه‌محور
💡 مخصوص توسعه‌دهندگان موبایل
Download Telegram
🚀 قسمت ۱۳ از سری «Flow»؛ این بار «StateFlow» را در «ViewModel» بررسی میکنیم!

🔹 «StateFlow» یک «Hot Flow» است که همیشه آخرین مقدار را نگه میدارد؛ بهترین گزینه برای نگهداری state در «ViewModel».

💡 چرا بهجای «LiveData»؟
🔹 هماهنگی کامل با «Kotlin» و «Coroutines»
🔹 سازگاری مستقیم با «Jetpack Compose» بدون نیاز به کد اضافه

📱 کاربرد واقعی: نمایش وضعیت «Loading» و «Error» هنگام دریافت داده از «Repository».

کد زیر یک «ViewModel» عملی را نشان میدهد:

data class User(val id: String, val name: String)

interface UserRepository {
suspend fun getUser(): User
}

data class UserUiState(
val isLoading: Boolean = false,
val error: String? = null,
val user: User? = null
)

class UserViewModel(
private val repository: UserRepository
) : ViewModel() {

private val _uiState = MutableStateFlow(UserUiState())
val uiState: StateFlow<UserUiState> = _uiState.asStateFlow()

fun loadUser() {
viewModelScope.launch {
_uiState.update { it.copy(isLoading = true) }
try {
val user = repository.getUser()
_uiState.update { it.copy(isLoading = false, user = user) }
} catch (e: Exception) {
_uiState.update { it.copy(isLoading = false, error = e.message) }
}
}
}
}


«MutableStateFlow» خصوصی است و فقط نسخهی فقطخواندنی آن با «asStateFlow» بیرون داده میشود. تابع «update» تغییر state را اتمیک انجام میدهد.

💎 نکته طلایی: هرگز «MutableStateFlow» را مستقیم expose نکنید.

📌 جمعبندی: «StateFlow» یعنی state همیشه در دسترس، همیشه بهروز و کاملاً تستپذیر.

#Codeit #Android #Kotlin #Jetpack #Flow #StateFlow #ViewModel #Compose

🌐 Codeithttps://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
3🔥1
«SharedFlow» برخلاف «StateFlow» برای ارسال رویدادهای یکبارمصرف ساخته شده! 🚀

تو «ViewModel» برای اتفاقهایی مثل نمایش پیام یا ناوبری نباید از «StateFlow» استفاده کنی؛ چون مقدار قبلی رو دوباره به مشترک جدید تحویل میده. 😬

«SharedFlow» فقط به مشترکهای فعال ارسال میکنه و هیچ مقدار قبلیای رو نگه نمیداره.

کاربرد واقعی: بعد از زدن دکمه ثبتنام، فقط یکبار باید پیام «موفقیت» نمایش داده بشه، نه هر بار که به صفحه برمیگردی. 🎯

یک نمونه ساده از تعریف «SharedFlow» در «ViewModel»:

class MainViewModel : ViewModel() {
private val _events = MutableSharedFlow<String>(extraBufferCapacity = 1)
val events = _events.asSharedFlow()

fun onSaveClick() {
viewModelScope.launch {
_events.emit("ذخیره شد")
}
}
}


این کد رویداد رو فقط به شنوندههای فعال میفرسته؛ اگه مشترکی وجود نداشته باشه، رویداد از بین میره. «extraBufferCapacity» هم باعث میشه اگه مشترک در حال پردازش بود، یک رویداد در بافر بمونه. 📦

نکته مهم: برای «Event» ها از «SharedFlow» و برای «State» ها از «StateFlow» استفاده کن. 🧠

#Codeit #Android #Kotlin #Jetpack #SharedFlow #Coroutines #Flow #CleanArchitecture
🌐 Codeithttps://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2🔥1🥰1
🔥 «Flow» فقط ابزار انتشار داده نیست؛ اگر اصولش رو رعایت نکنی، باعث نشت حافظه و مصرف بی‌دلیل منابع می‌شه!

ما رسیدیم به قسمت پانزدهم: «Flow Best Practices»؛ جایی که تئوری تموم می‌شه و بحث سر کدنویسی واقعی و بهینه‌ست. 🚀

🚫 اشتباه رایج: جمع‌آوری مستقیم «Flow» در «ViewModel» بدون مدیریت چرخه حیات. این کار باعث می‌شه «Coroutine» همیشه زنده بمونه و «Bundle» هرگز آزاد نشه.

راهکار درست: تبدیل «Flow» به «StateFlow» با استفاده از «stateIn» و مشخص کردن زمان شروع. توی «Jetpack Compose» هم باید با «repeatOnLifecycle» جمع‌آوری بشه تا فقط وقتی UI فعاله، داده بیاد.

فرض کن یک «ViewModel» داری که وضعیت صفحه رو از مخزن می‌گیره:

class MainViewModel(
private val repository: Repository
) : ViewModel() {

val uiState: StateFlow<UiState> = repository
.latestNews
.map { news -> UiState.Success(news) }
.catch { error -> emit(UiState.Error(error.message)) }
.stateIn(
scope = viewModelScope,
started = WhileSubscribed(5_000),
initialValue = UiState.Loading
)
}


کد بالا سه تا «Best Practice» رو رعایت می‌کنه: تبدیل به «StateFlow»، مدیریت خطا با «catch» و شروع فقط وقتی مشتری فعاله.

حالا توی «Compose» هم به‌جای جمع‌آوری مستقیم، از این الگو استفاده کن:

@Composable
fun MainScreen(viewModel: MainViewModel) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
// now render based on uiState
}


با «collectAsStateWithLifecycle» مطمئن می‌شی جمع‌آوری فقط توی پس‌زمینه فعاله و با رفتن به پس‌زمینه، کارگر اضافه انجام نمی‌شه. 🧠

نکته بعدی: اگر داده‌ها تکراری هستن، حتماً از «distinctUntilChanged» استفاده کن تا فقط با تغییر مقدار، «Recomposition» اتفاق بیفته. برای رویدادهای سریع هم «conflate» رو فراموش نکن.

جمع‌بندی: «Flow» قدرتمنده، اما قدرت واقعی‌ش توی پایبندی به اصول استفاده‌ست. این ۳ عادت رو جدی بگیر: «stateIn» با «WhileSubscribed» در «ViewModel»، جمع‌آوری با «repeatOnLifecycle» و کاهش نویز با «distinctUntilChanged». 🎯

#Codeit #Android #Kotlin #Jetpack #Flow #StateFlow #BestPractices

🌐 Codeithttps://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2🔥1🥰1
🧘♂️ ساعت ۲ نصفه شب، صفحه مونیتور زل زدی به یه خط کد که داری کرش میکنه و هیچ دلیل منطقی هم نمیبینی؟

🔍 آروم باش. دقیقا همین لحظه ست که یه «Developer» حرفهای رو از یه مبتدی جدا میکنه.

🛠 «Debugging» فقط پیدا کردن باگ نیست؛ مدیریت ذهنیه که باید با یه مشکل ناشناخته روبهرو بشه.

🚶 اول از همه از پشت سیستم بلند شو. ۱۰ دقیقه راه برو. مغزت موقع حرکت، الگوهای بهتری پیدا میکنه.

📝 بعد، باگ رو دقیقا بنویس: چی انتظار داشتی؟ چی اتفاق افتاد؟ چه ورودیهایی دادی؟

💡 این همون تکنیک معروف «Rubber Duck Debugging» است؛ مشکل رو برای یه آدم خیالی توضیح بده تا اشکال خودش رو نشون بده.

قانون طلایی: هیچوقت با ذهن خسته تغییرات بزرگ نده. یه «Log» اضافه کن، یه «Breakpoint» بذار و کوچیککوچیک پیش برو.

🧠 یادت باشه: هر باگ یه فرصت یادگیریه. هر دقیقهای که دنبال علت میگردی، تجربهات داره عمیقتر میشه.

🔁 اگه ۳۰ دقیقهست گیر کردی، رهاش کن و برو چیز دیگهای انجام بده. مغز تو ناخودآگاه هنوز داره روش کار میکنه.

🤝 قبل از اینکه توی «Stack Overflow» دنبال جواب بگردی، مطمئن شو که مشکلت رو کامل شبیهسازی کردهای.

🎯 نتیجه؟ با آرامش، باگها نصفِ زمان حل میشن. عصبانیت فقط سرعتتو کم میکنه و کلی خطای جدید هم میسازه.

🚀 پس دفعه بعد که باگ دیدی، لبخند بزن؛ این یعنی داری یه چیز جدید یاد میگیری.

#Codeit #Android #Kotlin #Jetpack #Debugging #DeveloperMindset #ProblemSolving #StayCalm

🌐 Codeithttps://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2🔥1🥰1
🎯 آموزش Jetpack Compose — قسمت اول: کامپوز چیه؟

کار ساخت UI توی اندروید تا چند سال پیش فقط با XML بود. ديگه لازم نیست با findViewById و LayoutInflater درگیر بشی.

«Jetpack Compose» یه تولد‌باکس مدرن از گوگله که بهت اجازه میده با نوشتن کد «Kotlin» کل UI رو بسازی. بدون XML، بدون دردسر.

📌 فرق اصلیش اینه: UI به‌صورت «Declarative» نوشته میشه. یعنی میگی «چی می‌خوام ببینم»، نه «چطور ببینم». این طرز فکر، کد رو خواناتر و نگهداریش رو ساده‌تر می‌کنه.

💡 مثال واقعی: فرض کن یه دکمه داری. توی XML باید layout و onclick رو جدا مدیریت کنی. توی کامپوز، همه چیز یه تابع ساده‌ست.

بیایم با هم یه «Text» ساده توی کامپوز بسازیم:

@Composable
fun HelloWorld() {
Text(
text = "سلام دنیا!",
color = Color.Blue,
fontSize = 24.sp
)
}


🧠 این کد چیکار می‌کنه؟ کافیه تابع رو با «@Composable» مشخص کنی. بعدش هرچی توش بنویسی، مستقیم توی UI نشون داده میشه. اینجا یه متن آبی با سایز ۲۴ نوشتیم.

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

از همین امروز شروع کن. در قسمت بعدی می‌رسیم به «State» و مدیریتش.

#Codeit #Android #Kotlin #Jetpack #JetpackCompose #AndroidDevelopment #Compose #Beginner
🌐 Codeithttps://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2🔥1🥰1
🗂 «Jetpack Compose» قدم اولت رو برداشتی؟ حالا وقتشه با قلب این فریم‌ورک آشنا بشی: «Composable functions»!

🧠 هر «Composable function» یه تابع معمولی «Kotlin» هست که با افزودن «@Composable» بهش، می‌تونه رابط کاربری بسازه. بدونش هم می‌تونی کد بزنی، ولی با «@Composable» معجزه می‌کنه.

🔧 چرا بهش نیاز داری؟ چون با «Composable»ها می‌تونی UI رو به صورت تابعی و بدون دردسر مدیریت کنی. هر بار که وضعیت (state) تغییر کنه، فقط همون بخش لازم دوباره رندر می‌شه.

📱 مثال واقعی: فرض کن یک صفحه ساده داری که اسم کاربر رو نشون می‌ده. با «Composable» این کار رو خیلی راحت انجام می‌دی:

@Composable
fun Greeting(name: String) {
Text(text = "سلام $name!", fontSize = 24.sp)
}


این کد یه تابع «Composable» به اسم «Greeting» می‌سازه که یک «Text» رو با اسم ورودی نشون می‌ده. با تغییر اسم، فقط همین متن دوباره ساخته می‌شه و بقیه UI دست نمی‌خوره.

💡 نکته مهم: تو «Composable»ها خبری از «return» نیست. تو فقط می‌گی چی نشون بده، و «Compose» خودش بقیه کار رو می‌کنه.

🔗 حالا بیا این «Greeting» رو داخل یه «Activity» صدا بزنیم:

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Greeting(name = "کاربر جان!")
}
}


توضیح: «setContent» یه «block» از «Composable»ها رو به عنوان ریشه UI معرفی می‌کنه. اینجا «Greeting» رو صدا زدیم تا متن خوش‌آمدگویی نمایش داده بشه.

💎 جمع‌بندی: «Composable function»ها پایه‌ترین مفاهیم «Jetpack Compose» هستن. هر UI که می‌سازی، در نهایت از این توابع تشکیل می‌شه. پس خوب یادشون بگیر.

#Codeit #Android #Kotlin #Jetpack #Compose #Composable #UI #AndroidDev
🌐 Codeithttps://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
3🥰1
🎯 «Modifier» مهمترین ابزار شخصیسازی در «Jetpack Compose» است؛ بدون آن فقط یک صفحه خالی دارید!
🛠 «Modifier» مثل یک جعبه ابزار میماند که میتوانید روی هر «Composable» اعمال کنید.
📏 با آن فاصله، رنگ، کلیک، چرخش، اندازه و صدها ویژگی دیگر را تنظیم میکنید.
🔗 نکته طلایی: «Modifier» ها زنجیرهای میشوند؛ ترتیب آنها در نتیجه نهایی تأثیر مستقیم دارد.
📰 مثال واقعی: یک کارت خبری که پسزمینه دارد، قابل کلیک است و دورتادور آن فاصله گذاشتهایم.
کد زیر را ببینید:

Column(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth()
.background(Color.LightGray)
.clickable { openArticle() }
.padding(8.dp)
) {
Text(text = "Hello Codeit! 📰")
}


🧠 این کد ابتدا ۱۶ واحد فاصله بیرونی میگذارد، بعد عرض را کامل میکند و رنگ پسزمینه را روشن میسازد.
👆 سپس کامپوننت را قابل کلیک کرده و در نهایت ۸ واحد فاصله داخلی به محتوا میدهد.
⚠️ نکته مهم: اگر ترتیب «background» و «clickable» را عوض کنید، افکت کلیک زیر رنگ قرار میگیرد!
✍️ تمرین: همین مسیر را روی یک «Image» هم امتحان کنید و نتیجه را ببینید.
💪 با تکرار این الگو، بدنه «Modifier» برایتان کاملاً عادی میشود.

#Codeit #Android #Kotlin #Jetpack #Compose #Modifier #Programming #Learn
🌐 Codeithttps://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2🔥1🥰1
یادگیری بدون ساختن مثل خوندن کتاب رانندگی بدون نشستن پشت فرمونه!

📚 خیلی از برنامه‌نویس‌ها ماه‌ها توی «Tutorial Hell» گیر می‌افتند—همش آموزش می‌بینن ولی هیچی نمی‌سازن.
⚖️ راز موفقیت توازن بین یادگیری و ساختن محصول واقعیه.

🔹 توی مسیر اندروید، تئوری بی‌عمل باعث فرسودگی ذهنی و ناامیدی میشه.
🔹 ساختن بی‌یادگیری هم باعث تولید کدهای ضعیف و «Anti‑Pattern»های خطرناک میشه.

راهکار عملی: قانون ۲۰/۸۰ رو امتحان کن.
۲۰٪ وقتت رو صرف یادگیری یه مفهوم جدید مثل «StateFlow» بکن،
۸۰٪ باقی‌مونده رو برو توی یه پروژه‌ی واقعی ازش استفاده کن.

📱 مثلاً:
یه «To‑Do App» ساده با «Room Database» و «ViewModel» بساز، بعد برو سراغ آموزش «Clean Architecture».
تجربه‌ی مستقیم باعث میشه مفاهیم عمیق‌تر توی ذهنت بمونن.

💡 اگر بعد از سه روز آموزش هنوز هیچ خط کدی ننوشتی، یعنی داری اشتباه می‌کنی.
یادگیری رو با ساختن گره بزن.

#Codeit #Android #Kotlin #Jetpack #DeveloperMindset #GrowthMindset #Balance #LearnByBuilding
🌐 Codeithttps://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2🔥1🥰1
📱 «Text composable» در «Jetpack Compose» ساده‌ترین و در عین حال قدرتمندترین ابزار نمایش متن است.
اگر می‌خواهید متن‌های زیبا، حرفه‌ای و قابل تنظیم در اپلیکیشن «Android» داشته باشید، باید با این کامپوننت آشنا شوید.

🧩 «Text composable» یک تابع «Composable» است که رشته متنی را دریافت کرده و روی صفحه نمایش می‌دهد.
از تنظیم سایز و رنگ گرفته تا فونت و ترازبندی، همه چیز با پارامترهای ساده قابل کنترل است.

📌 کاربرد واقعی: نمایش نام کاربر، عنوان صفحه، توضیحات محصول، یا هر متنی که نیاز به استایل‌دهی داشته باشد.

💻 بیایید یک مثال ساده ببینیم:

@Composable
fun GreetingText(name: String) {
Text(
text = "سلام، $name",
fontSize = 24.sp,
color = Color.Blue,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth().padding(16.dp)
)
}


🔍 توضیح کد:
- «text»: متن اصلی را مشخص می‌کند.
- «fontSize»، «color»، «fontWeight»: ظاهر متن را تنظیم می‌کنند.
- «textAlign»: تراز متن را تعیین می‌کند.
- «modifier»: با «fillMaxWidth» عرض کامل و با «padding» فاصله داخلی اضافه می‌کند.

نکته کاربردی: برای استایل‌دهی حرفه‌ای‌تر می‌توانید از «MaterialTheme.typography» استفاده کنید تا فونت‌های استاندارد پروژه را اعمال کنید.

---

#Codeit #Android #Kotlin #Jetpack #JetpackCompose #TextComposable #UI #MobileDev
🌐 Codeithttps://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1🥰1
🎯 «Jetpack Compose» قسمت ۵: «Button Composable»
یکی از پایهای‌ترین کامپوننت‌های UI در «Jetpack Compose» دکمه‌ها هستند.
بیایید ببینیم چطور می‌تونیم یک دکمه با ظاهر و رفتار دلخواه بسازیم.

🚀 مثال عملی:
فرض کنید یک دکمه «ثبت نام» می‌خواهید که با کلیک روی آن، یک پیام نمایش بدهد.

🛠️ کد ساده برای شروع:
@Composable
fun SimpleButton() {
Button(
onClick = {
println("دکمه کلیک شد!")
},
colors = ButtonDefaults.buttonColors(
containerColor = Color.Blue,
contentColor = Color.White
),
shape = RoundedCornerShape(12.dp)
) {
Text(text = "ثبت نام")
}
}

💡 توضیح:
- onClick: عملی است که بعد از کلیک اجرا می‌شه.
- colors: رنگ پس‌زمینه و متن رو مشخص می‌کنه.
- shape: گوشه‌های دکمه رو گرد می‌کنه (مثلاً ۱۲ پیکسل).

🎨 شخصی‌سازی بیشتر:
می‌تونید Modifier اضافه کنید تا اندازه، حاشیه یا ارتفاع دکمه رو تنظیم کنید:

Button(
onClick = { /* کلیک */ },
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.padding(horizontal = 16.dp)
) {
Text("ورود به حساب")
}

📌 کاربرد:
این کد یک دکمه تمام‌عرض با ارتفاع ثابت و فاصله از کناره‌ها می‌سازه.

نتیجه‌گیری:
با «Button» در «Jetpack Compose» می‌تونید دکمه‌های زیبا و واکنش‌گرا با کمترین کد بسازید.

#Codeit #Android #Kotlin #Jetpack #JetpackCompose #UI #Button #AndroidDev

🌐 Codeithttps://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1🥰1