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

Kotlin • Android

🚀 آموزش ساده، کاربردی و پروژه‌محور
💡 مخصوص توسعه‌دهندگان موبایل
Download Telegram
🔥 «Coroutines» قسمت دوازدهم؛ نبرد «coroutineScope» و «supervisorScope»!

🧠 مدیریت خطا در «Coroutines» یکی از مهمترین مهارتهاست؛ این دو اسکوپ، رفتار کاملاً متفاوتی با خطای فرزندان دارند.

«coroutineScope»: اگر یک فرزند خطا بدهد، کل اسکوپ نابود شده و بقیه فرزندان هم لغو میشوند.

«supervisorScope»: خطای یک فرزند، فقط خودش را از بین میبرد و بقیه بدون وقفه کار میکنند.

🛠 مثال واقعی: در صفحه «Detail»، همزمان «UserProfile» و «Notifications» لود میشوند. اگر «Notifications» خطا بدهد، نباید پروفایل کاربر از بین برود!

پس از «supervisorScope» استفاده میکنیم:

suspend fun loadDashboard() = supervisorScope {
val profile = async { fetchUserProfile() }
val notifications = async { fetchNotifications() }

try {
// خطای نوتیفیکیشن روی پروفایل تأثیری ندارد
showProfile(profile.await())
} catch (e: Exception) {
showError(e.message)
}
}


📝 خطای «fetchNotifications» فقط همان فرزند را نابود میکند و «fetchUserProfile» نتیجهاش را سالم تحویل میدهد.

🎯 قانون طلایی: «coroutineScope» برای کارهای وابسته و «supervisorScope» برای کارهای مستقل؛ جایی که خطای یکی نباید بقیه را بگیرد.

#Codeit #Android #Kotlin #Jetpack #Coroutines #KotlinCoroutines #SupervisorScope #CoroutineScope

🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
۵ تا از معروف‌ترین قانون‌های دنیا

1️⃣ قانون مورفی
هرچی بیشتر از اتفاق افتادن یه چیز توی زندگیت بترسی، احتمال اتفاق افتادنش بیشتره.

2️⃣ قانون کیدلین
اگه یه مشکل رو به‌صورت خیلی واضح و دقیق بنویسی، نصف مشکل رو حل کردی.

3️⃣ قانون گیلبرت
وقتی می‌خواهی کاری رو انجام بدی، پیدا کردن بهترین راه برای رسیدن به نتیجه‌ی موردنظر فقط و فقط مسئولیت خودته.

4️⃣ قانون ویلسون
اگه دانش، اطلاعات و هوش رو اولویت قرار بدی، پول هم خودش میاد.

5️⃣ قانون فالکلند
اگه مجبور نیستی بین دو تا چیز تصمیم بگیری، اصلاً تصمیم نگیر.

#کاربردی
@CodeitMobile
1
🚀 یک سال دیگه میخوای ببینی کجا هستی؟ همون جای امروزت؟ یا یه نسخهی خیلی بهتر از خودت؟
حقیقت سادهست: پیشرفت بزرگ یهشبه اتفاق نمیافته. اون چیزی که فرق ایجاد میکنه، همون «۱٪ بهتر در روز»ه. 📈

وقتی هر روز فقط یه قدم کوچیک برمیداری، بعد از ۳۶۵ روز نهتنها ۳۶۵ قدم، بلکه هزاران قدم از نقطهی قبلی فاصله گرفتی.
شاید امروز فقط بتونی یه تابع ساده بنویسی و فردا یه باگ رو حل کنی. شاید اینا به نظر کوچیک بیان، ولی دقیقاً همینا هستن که یه «Android Developer» قوی میسازن.

بیایم سراغ دنیای واقعی: یه برنامهنویس مبتدی رو تصور کن که هر روز فقط ۳۰ دقیقه «Kotlin» یاد میگیره. نه بیشتر، نه کمتر.
بعد از ۶ ماه، همون آدم میتونه یه اپ کامل با «Jetpack Compose» بنویسه. بدون فشار و خستگی، فقط با استمرار.

اگه امروز نتونستی یه پروژهی بزرگ رو تموم کنی، اصلاً مهم نیست. مهم اینه که امروز یه کاری کردی که دیروز ازش فرار میکردی. 💪
یه «commit» کوچیک روی «GitHub» بزن، یه مقاله بخون، یه تمرین حل کن، یه ویدیو ببین. همهش حساب میشه.

یادت باشه: سرعت مهم نیست؛ مهم اینه که جهت درسته و حرکتت ادامه داره. 🧭
از امروز بهجای فکر کردن به نتیجهی بزرگ، فقط روی همون قدم کوچیک امروز تمرکز کن. بقیهش خودش درست میشه. 🌱

#Codeit #Android #Kotlin #Jetpack #DeveloperMindset #Consistency #SmallSteps #Growth
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
🧵 «Coroutines» پیشرفته؛ قسمت سیزدهم: «Structured Concurrency»!
تا حالا شده بچهکوریوتینها از حیطهی پدر خارج بشن و برنامه رو به هم بریزن؟ 🤔
«Structured Concurrency» یعنی نظم والد-فرزندی بین «Scope»ها؛ درست مثل تیم کاری منظم. 💼
در این مدل، هر «Coroutine» فرزند فقط تا وقتی زندهست که والدش زنده باشه؛ با تمام شدن کار والد، همهچیز خودکار جمع میشه. 🔄
کاربرد واقعی؟ فرض کن صفحهی پرداخت باید همزمان موجودی، تخفیف و وضعیت درگاه رو بخونه. اگر یکی از اینها خطا بده، بهتره کل عملیات متوقف بشه نه اینکه نیمهکاره بمونه! 🛑

حالا ببینیم با «coroutineScope» چطور این رفتار رو پیاده میکنیم:

suspend fun fetchPaymentData() {
coroutineScope {
val balance = async { getBalance() }
val discount = async { getDiscount() }
val gateway = async { getGatewayStatus() }

showResult(balance.await(), discount.await(), gateway.await())
}
}


اگر «getDiscount» خطا بده، کل «Scope» کَنسل میشه؛ یعنی «balance» و «gateway» هم خودکار لغو میشن. 🧹
اینجا خبری از «Coroutine» سرگردان یا نشت حافظه نیست؛ ساختار خودش مراقب همهچیزه. 🧠
پس همیشه از «CoroutineScope»های والد استفاده کن و «GlobalScope» رو به عنوان ضدالگو به خاطر بسپار. 🔐
اینطوری کدت هم خواناتره، هم مقیاسپذیرتر. 🚀

#Codeit #Android #Kotlin #Jetpack #Coroutines #StructuredConcurrency #AdvancedKotlin #KotlinCoroutines
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
⏱️ تا حالا شده یه عملیات دیتابیس، انقدر طول بکشه که کاربر از برنامه بزنه بیرون؟
اینجاست که «Timeouts» توی «Coroutines» نجاتت میده! 🚀

توی بخش چهاردهم، قراره یاد بگیریم چطور با «withTimeout» و «withTimeoutOrNull» جلوی آویزون موندن برنامه رو بگیریم.

🔹 مشکل: یه فراخوانی شبکه ممکنه هیچوقت جواب نده و برنامه همیشه منتظر بمونه.
🔹 راهحل: یه مهلت مشخص میکنیم؛ اگه تموم نشد، ادامه میدیم یا خطا میگیریم.

💡 کاربرد واقعی: مثلاً در یه اپ خرید، اگه سرور ظرف ۵ ثانیه جواب نداد، به کاربر پیام «اتصال برقرار نشد» نشون بدیم.

اول بذارید یه نمونه کد ساده ببینیم:

fun main() = runBlocking {
val result = withTimeoutOrNull(5000L) {
fetchDataFromServer()
"Done"
}
if (result == null) {
println("درخواست لغو شد؛ دوباره تلاش کنید.")
} else {
println(result)
}
}


📌 این کد یعنی: حداکثر ۵ ثانیه صبر کن؛ اگه «fetchDataFromServer» تموم نشد، به جای خطا، «null» برگردون.
به این ترتیب هم برنامه کرش نمیکنه، هم کاربر بیپاسخ نمیمونه.

📌 اگه به خطا نیاز داری، از «withTimeout» استفاده کن؛ اگه بخوای حالت خالی رو مدیریت کنی، «withTimeoutOrNull» مناسبتره.

نکته مهم: «Timeouts» مخصوص عملیاتهای طولانی مثل شبکه، دیتابیس یا «File I/O» هست و جلوی قفل شدن «UI» رو میگیره.

تمرین کن و توی پروژههات از «withTimeoutOrNull» برای فراخوانیهای شبکه استفاده کن.

#Codeit #Android #Kotlin #Jetpack #Coroutines #Timeouts #Programming #MobileDev
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
🚀 «Coroutines» در اندروید رو جدی میگیری؟ پس این ۵ اصل طلایی رو از دست نده!

🧠 بهترین تمرینها فقط به درد پروژههای بزرگ نمیخورن؛ حتی همون پروژهی سادهی اولت هم میتونه از همین حالا تمیز نوشته بشه.

⚙️ اصل اول: همیشه از «Structured Concurrency» استفاده کن تا همهی کارها با هم لغو بشن.

🔥 اصل دوم: بهجای «GlobalScope» حتماً از «viewModelScope» یا «lifecycleScope» استفاده کن. اینطوری نشت حافظه دیگه به سراغت نمیاد.

🎯 اصل سوم: برای خطاها حتماً «CoroutineExceptionHandler» بذار. خطای ناگهانی نباید برنامه رو کرش کنه.

🛠️ اصل چهارم: از «Dispatchers.Main.immediate» برای دستکاری سریع UI استفاده کن تا ریسک «Race Condition» رو بیاری پایین.

📚 حالا ببینیم این اصول توی کد چطور اجرا میشن:

class MainViewModel : ViewModel() {

private val scope = viewModelScope

fun loadUsers() {
scope.launch {
val users = withContext(Dispatchers.IO) {
userRepository.fetchUsers()
}
userList.value = users
}
}
}


📖 این کد با «viewModelScope» شروع به کار میکنه؛ در نتیجه با نابودی «ViewModel»، همهی تسکها بهصورت خودکار لغو میشن. «withContext» هم فقط بخش سنگین کار رو به «Dispatchers.IO» میفرسته و نتیجه رو امن به «Main» برمیگردونه.

جمعبندی: کدی بنویس که همیشه قابل لغو، خواناتر و بدون نشت حافظه باشه.

#Codeit #Android #Kotlin #Jetpack #Coroutines #BestPractices #CleanArchitecture #ViewModel

🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2🔥1
🧭 نقشه راه یادگیری یعنی همین امروز بدانی چه چیزی یاد میگیری، چرا یاد میگیری و تا کجا باید برسی.

بدون نقشه، هر روز وسط انبوهی از دورهها و مقالهها گیج میشوی و مسیر برایت مبهم باقی میماند. 🌀

با یک نقشهی ساده، تمرکزت روی یک مسیر مشخص میماند و دیر یا زود به نتیجه میرسی. 🎯

قدم اول: هدفت را شفاف بنویس؛ مثلاً رسیدن به شغل «Android Developer».

قدم دوم: مسیر را به مرحلههای کوچک تقسیم کن؛ «Kotlin»، بعد «Jetpack Compose»، بعد «Networking».

قدم سوم: برای هر مرحله یک بازهی زمانی واقعبینانه بگذار؛ مثلاً دو هفته برای «Kotlin».

قدم چهارم: فقط یک یا دو منبع آموزشی معتبر را انتخاب کن. 📚

قدم پنجم: هر درس را با یک تمرین عملی تمام کن؛ یادگیری بدون ساختن، فراموشی است. 🛠️

قدم ششم: یک روز در هفته را به مرور درسهای قبلی اختصاص بده. 🔁

نقشهی تو لازم نیست بینهایت دقیق باشد؛ کافی است ساده باشد و هر هفته آن را بهروز کنی.

مهمترین نکته: مسیر یادگیری را برای خودت بساز، نه برای این که شبیه دیگران باشی. 🗺️

حالا فقط یک قدم به جلو برو؛ شروع امروز، از فردا بهتر است. 🚀

#Codeit #Android #Kotlin #Jetpack #LearningRoadmap #DeveloperMindset #GrowthMindset

🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2
🔥 «Flow» یکی از مهمترین مفاهیم «Kotlin Coroutines» است که خیلیها توی یادگیریش گیر میکنند!
🤔 اگر هنوز نمیدانی «Flow» چیست و چرا در «Android» مهم شده، این پست دقیقا برای تو است.
📦 یک «suspend function» فقط یک مقدار برمیگرداند؛ اما «Flow» میتواند یک جریان از مقادیر را در طول زمان ارسال کند.
🛰️ «Flow» یک «Cold Stream» است؛ یعنی تا وقتی کسی به آن گوش ندهد، هیچ دادهای تولید نمیکند.
📍 کاربرد واقعی: دریافت موقعیت مکانی، دادهی سنسورها یا صفحهبندی خروجی «Room Database».
🧪 بیایید یک «Flow» ساده بسازیم که هر ثانیه یک عدد تولید کند؛ کد را ببینید:

val myFlow = flow {
for (i in 1..3) {
emit(i)
delay(1000)
}
}

lifecycleScope.launch {
myFlow.collect { value ->
Log.d("Flow", "Received: $value")
}
}


🧐 این کد چگونه کار میکند؟ تابع «flow» یک بلوک میگیرد و با «emit» مقدار تولید میکند؛ «delay» هم یک مکث یکثانیهای ایجاد میکند.
👂 در سمت مصرفکننده با «collect» به جریان گوش میدهیم و هر مقدار را لاگ میکنیم.
💡 چون «Flow» سرد است، تا وقتی «collect» صدا زده نشود، حتی یک عدد تولید نمیشود.
🎯 جمعبندی: «Flow» یعنی تولید چند مقدار ناهمگام در طول زمان؛ در پست بعدی سراغ «StateFlow» و «SharedFlow» میرویم. 🚀

#Codeit #Android #Kotlin #Jetpack #Flow #Coroutines #KotlinFlow
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2
🚀 سری «Flow» قسمت دوم؛ وقتشه خودمون یک «Flow» بسازیم!

اول از همه بدونیم ساخت «Flow» سه راه اصلی داره:

۱️⃣ «flowOf» برای ساخت از مقادیر ثابت
۲️⃣ «asFlow» برای تبدیل «Collection» یا «Range» به «Flow»
۳️⃣ «flow builder» برای ساخت جریان داده‌های ناهمزمان

💡 مثلاً فرض کن داری لیست کارهای یک کاربر رو از «Room Database» می‌خونی؛ بهترین راه برگردوندن «Flow» هست.

بریم سراغ کد، ساده‌ترین حالت ساختن «Flow»:

val numberFlow: Flow<Int> = flowOf(1, 2, 3, 4, 5)

val rangeFlow: Flow<Int> = (1..5).asFlow()

val customFlow: Flow<String> = flow {
emit("شروع")
delay(1000)
emit("پایان")
}


توی «flow builder»، تابع «emit» مقدار تولید می‌کنه و «delay» فقط یه شبیه‌سازی از کار سنگینه.

بعداً با «Flow» حاصل می‌تونی از «StateFlow» یا «SharedFlow» هم استفاده کنی.

📌 نکته: «Flow» یه جریان «cold» هست؛ یعنی تا کسی جمعش نکنه، اجرا نمی‌شه.

🎯 پس هر وقت داده‌ای داری که به‌مرور تولید می‌شه، «Flow» بهترین انتخابه.

بگو کدوم بخش برات مبهمه تا توی پست بعدی عمیق‌تر بریم.

#Codeit #Android #Kotlin #Jetpack #Flow #Coroutines #StateFlow #ReactiveProgramming
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
🔥 در قسمت سوم آموزش «Flow»، وقتشه با «collect» آشنا بشیم؛ همون نقطهای که جریان داده بالاخره مصرف میشه! 💡
توی «Kotlin»، «Flow» یک جریان دادهست و «collect» عملگر پایانیه که اون رو فعال میکنه و هر آیتم رو پردازش میکنه. ⚙️
بدون «collect»، هیچ اتفاقی نمیافته؛ درست مثل اینکه شیر آب رو باز کنی ولی ظرفی زیرش نذاری! 🚰
نکته اساسی: «collect» یک تابع «suspend» هست و باید داخل یک «CoroutineScope» مثل «ViewModel» صدا زده بشه. 🧠
اگه نیاز داری فقط جدیدترین مقدار پردازش بشه، «collectLatest» انتخاب هوشمندانهتری نسبت به «collect» است. 🎯
بذار یک مثال ساده و عملی از «collect» ببینیم:

flowOf(1, 2, 3).collect { println(it) }


این کد سه عدد رو بهصورت پشتسرهم چاپ میکنه؛ «Flow» اینجا یک جریان سرد هست. 📡
در پروژههای واقعی، معمولاً «collect» رو با «StateFlow» و داخل «ViewModel» ترکیب میکنم تا «UI» همیشه بهروز باشه. 📱
فراموش نکن با ذخیره «Job» میتونی جمعآوری رو با «cancel()» متوقف کنی. حالا برو امتحانش کن! 🚀
#Codeit #Android #Kotlin #Jetpack #Flow #Coroutines
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
🧠 چرا وقتی کد میزنیم، تمرکزمون اینقدر راحت پرت میشه؟

🚀 مشکل فقط گوشی نیست؛ ذهن ما عادت کرده سریع جواب بگیره، ولی کدنویسی یک کار عمیقه و دقیقاً به «Deep Work» نیاز داره.

📱 هر نوتیفیکیشن یعنی چند دقیقه وقت برای برگشتن به حالت قبلی؛ یعنی ساعتهای طلایی روزت داره هدر میره.

🎯 تکنیک «Pomodoro» رو امتحان کن: ۲۵ دقیقه فقط کدنویسی، ۵ دقیقه استراحت. این چرخه رو ۴ بار تکرار کن.

🔕 گوشی رو بذار روی «Do Not Disturb» و مرورگرت رو توی حالت «Focus Mode» قرار بده.

✂️ قبل از شروع، کارت رو به بخشهای خیلی کوچیک بشکن؛ مثلاً «رسیدن به یک «Response» درست» نه «تکمیل کل پروژه».

🔄 اگه حس کردی ذهنت پرت شده، از تکنیک «State Switch» استفاده کن: بلند شو، آب بخور، به یک نقطه ثابت نگاه کن و بعد برگرد سراغ کد.

💡 تمرکز مثل «Muscle» میمونه؛ هر بار که پرت میشی و دوباره برمیگردی، قویترش میکنی.

با همین ۳ قدم شروع کن: برنامهریزی کوچیک، حذف نوتیفیکیشنها و پذیرش اینکه مغزت هم خسته میشه.

🛠 اپلیکیشنهایی مثل «Forest» یا «Cold Turkey» هم کمک میکنن، ولی هیچکدوم جای اراده خودت رو نمیگیرن.

📌 یادت باشه: کیفیت کدی که با تمرکز نوشته میشه، همیشه از کد عجلهای بهتره.

#Codeit #Android #Kotlin #Jetpack #Focus #Productivity #DeveloperMindset
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥21
🚀 قسمت چهارم از سری «Flow»؛ اینبار با «map» و «filter» دادهها رو شکل میدیم!
🧠 این دو اپراتور بهت اجازه میدن دادههای در حال جریان رو تبدیل کنی یا ناخواستهها رو حذف کنی.
📱 مثال واقعی: لیست سفارشها از سرور میاد و فقط قیمتهای بالای ۱۰۰ هزار تومن مهم هستن.

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

flowOf(50_000, 120_000, 80_000, 200_000)
.filter { it > 100_000 }
.map { "Order: $it Toman" }
.collect { println(it) }


خروجی: فقط «Order: 120000 Toman» و «Order: 200000 Toman» میمونه.
«filter» اول دادههای اضافی رو حذف میکنه، بعد «map» فرمت نهایی رو میسازه.
💡 نکته: ترتیب این دو اپراتور مهمه؛ اگر «map» اول باشه، همه آیتمها تبدیل میشن و بعد فیلتر.
در «Jetpack Compose» با «StateFlow» این ترکیب برای مدیریت وضعیت «UI» خیلی کاربردیه.
🔥 پس دفعه بعد بهجای حلقههای پیچیده، از «map» و «filter» استفاده کن.

#Codeit #Android #Kotlin #Jetpack #Flow #Coroutines #Filter #Map
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥21
توی قسمت پنجم سری آموزشی «Flow»، سراغ «onEach» و «launchIn» میریم؛ دو ابزار قدرتمند برای مدیریت هوشمندانه جریان دادهها! 🧩
«onEach» بهت اجازه میده قبل از اینکه مقدار به دست مصرفکننده برسه، یه عملیات میانی روش انجام بدی؛ مثل ذخیرهسازی یا لاگ گرفتن. 📝
«launchIn» هم کار «collect» رو انجام میده ولی بدون اینکه مجبور باشی خودت «Coroutine» بسازی؛ فقط کافیه «Scope» رو بدی. 🚀
این دو باهم یه ترکیب عالی برای «ViewModel» هستن؛ دادهها رو دریافت میکنی، پردازش میکنی و رابط کاربری رو هم بلاک نمیکنی. 🔥
فرض کن دادههای دمای سنسور رو میگیری و باید هر مقدار رو توی «Room Database» ذخیره کنی؛ کد زیر رو ببین:

sensorRepository.sensorFlow
.onEach { data ->
localCache.save(data)
}
.launchIn(viewModelScope)


توی این کد، «onEach» هر مقدار خروجی سنسور رو قبل از ارسال به مصرفکننده ذخیره میکنه و «launchIn» مطمئن میشه همهچیز توی «viewModelScope» اجرا بشه. 🎯
یعنی نه خبری از «collect» دستیه، نه «launch» اضافه؛ کدت خلوت و خواناتر میشه.
یه نکته حرفهای: «launchIn» یه «Job» برمیگردونه؛ با «cancel» کردنش میتونی هر موقع خواستی جمعآوری رو متوقف کنی. 💡
اگه این الگو رو یاد بگیری، دیگه مجبور نیستی توی هر «Fragment» یا «ViewModel» کد تکراری بنویسی و مدیریت «Coroutine» هم دقیق و اصولی میشه. 📈
تمرین کن و این دو تا رو جایگزین «collect» های اضافی کن؛ نتیجه رو توی تمیزی کدهات فوراً حس میکنی.

#Codeit #Android #Kotlin #Jetpack #KotlinFlow #Flow #Coroutine #AndroidDev
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2🔥1
اگه دو تا «Flow» داشته باشی که بخوای همزمان وضعیتشون رو باهم ترکیب کنی، «combine» دقیقاً همون چیزیه که بهش نیاز داری. 🔗

فرقش با «zip» اینه که «zip» فقط جفت‌های هم‌ردیف رو ترکیب می‌کنه، ولی «combine» با هر بار انتشار از هر کدوم از «Flow»ها، آخرین مقدار هر دو رو برداشته و نتیجه جدید می‌سازه. 📡

این رفتار توی اپ‌های واقعی خیلی به کار میاد؛ مثلاً فرم ورود که هم‌زمان باید username و password رو چک کنی. 🧠

فرض کن یه صفحه لاگین داری که دکمه ورود فقط وقتی فعال بشه که نام کاربری پر باشه و رمز حداقل ۶ کاراکتر داشته باشه.

با «combine» می‌تونی این دو «Flow» رو به یه «StateFlow» بولین تبدیل کنی و UI به‌صورت خودکار واکنش نشون بده.

بذار یه نمونه ساده رو ببینیم:

val username = MutableStateFlow("")
val password = MutableStateFlow("")

val isLoginEnabled = combine(username, password) { user, pass ->
user.isNotBlank() && pass.length >= 6
}.stateIn(viewModelScope, SharingStarted.Eagerly, false)


این کد هر بار که یکی از فیلدها تغییر کنه، شرط رو از روی آخرین مقادیر دوباره ارزیابی می‌کنه. نتیجه یه فرآیند Reactive کاملاً شفافه. 💡

حالا اگه بخوای چند «Flow» رو باهم ترکیب کنی، «combine» می‌تونه تا ۵ پارامتر مختلف پشتیبانی کنه. 🚀

پس به‌جای مدیریت دستی چند «Flow» جدا، بذار «combine» کار ترکیب رو برات انجام بده. اینطوری کدت کوتاه‌تر و خواناتر میشه. 🔥

اگه قسمت قبل سری رو ندیدی، حتماً از اول مرور کن که مفاهیم «Flow» و «StateFlow» کامل برات جا بیفته.

#Codeit #Android #Kotlin #Jetpack #Flow #Coroutines #StateFlow #Reactive
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2🔥1
همیشه «هوش مصنوعی» رو به‌عنوان دستیار ببین نه جایگزین ذهنت 🧠
اگر هر سوال رو مستقیم از «ChatGPT» بپرسی، کم‌کم عضله فکری‌ات ضعیف می‌شه 💪⚠️

بهترین راهکار: اول خودت تحلیل کن، بعد از «AI» برای تکمیل یا تصحیح استفاده کن 📝
مثلاً توی «Android Debugging» به جای اینکه خطا رو بدی به «AI»، اول خودت «Logcat» رو بخون 🐞

نمونه عملی:
وقتی با «Crash» توی «Kotlin» مواجه می‌شی، اول «Stack Trace» رو بررسی کن، بعد از «AI» برای درک بهتر کمک بگیر 👇

// مرحله اول: خودت تحلیل کن
val errorMessage = "NullPointerException: cannot read field"
val possibleCause = "maybe the variable is not initialized"

// مرحله دوم: از AI برای تأیید یا تکمیل استفاده کن
// "AI, check my analysis: NullPointerException in Kotlin - possible cause: "


با این روش، هم یاد می‌گیری، هم وابسته نمی‌شی 🚀
نکته مهم: همیشه قبل از استفاده از «AI»، جواب خودت رو داشته باش 🎯

#Codeit #Android #Kotlin #Jetpack #AI #Productivity #DeveloperMindset
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1👍1🔥1
🔄 ترکیب دو «Flow» با عملگر «zip» — دقیقاً مثل زیپ کاپشن!

وقتی دو جریان داده دارید و می‌خواهید هر جفت مقدار رو به‌هم بچسبونید و یه خروجی جدید بسازید، «zip» بهترین انتخاب است.

🧠 فرض کنید از دو سنسور مجزا دما و رطوبت دریافت می‌کنید. «zip» جفت‌های هم‌ترتیب رو ترکیب می‌کند.

مثال عملی: ترکیب اطلاعات کاربران از دو منبع مختلف.

💻 کد ساده با «zip» در «Kotlin»:
val flowA = flowOf("دما: ۲۵°", "دما: ۲۶°", "دما: ۲۷°")
val flowB = flowOf("رطوبت: ۴۰%", "رطوبت: ۴۲%")

flowA.zip(flowB) { temp, humidity ->
"$temp — $humidity"
}.collect { combined ->
println(combined)
}
// خروجی:
// دما: ۲۵° — رطوبت: ۴۰%
// دما: ۲۶° — رطوبت: ۴۲%
// (جفت سوم چون جفت ندارد، نادیده گرفته می‌شود)

📌 نکته: اگر تعداد جفت‌ها نامساوی باشد، جفت‌های اضافی حذف می‌شوند.

«zip» برای ترکیب دقیق دو جریان موازی عالی است.

🎯 این عملگر رو در سناریوهای real-time فراموش نکنید.

#Codeit #Android #Kotlin #Jetpack #Flow #KotlinFlows #ReactiveProgramming
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2
🚀 جستجوی هوشمند با «debounce» در «Kotlin Flow»
بالاخره وقتشه تایپ کاربر رو بهینه مدیریت کنیم!

تا حالا شده کاربر توی سرچ باکس تند تند تایپ کنه و هر کاراکتر باعث یه درخواست جدید بشه؟
این یعنی ترافیک بی‌فایده و کندی UI!

🔥 راه‌حل ساده: اپراتور «debounce» تو «Kotlin Flow»
این قابلیت باعث میشه فقط بعد از توقف تایپ (مثلاً ۳۰۰ میلی‌ثانیه) درخواست ارسال بشه.

📱 مثال واقعی: یه اپ لیست محصولات که کاربر اسم کالا رو تایپ میکنه:

class SearchViewModel : ViewModel() {

private val _query = MutableStateFlow("")

val searchResults: StateFlow<List<Product>> = _query
.debounce(300) // صبر کن 300 میلی‌ثانیه بعد از آخرین تغییر
.filter { it.length >= 2 } // حداقل 2 کاراکتر
.distinctUntilChanged() // فقط مقدار جدید
.flatMapLatest { query ->
repository.searchProducts(query) // API call
}
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyList()
)

fun onQueryChanged(query: String) {
_query.value = query
}
}


این کد چیکار میکنه؟
- وقتی کاربر تایپ میکنه، ۳۰۰ میلی‌ثانیه صبر میکنه
- اگر تایپ قطع بشه، درخواست API میره
- از تکرار مقادیر تکراری جلوگیری میکنه
- نتیجه رو به صورت خودکار به UI میرسونه

💡 مزیت بزرگ:
کاهش ۸۰٪ درخواست‌های اضافی + تجربه کاربری عالی
بدون نیاز به Handler یا Timer سنتی!

🌟 نکته حرفه‌ای:
مقدار debounce رو متناسب با سرعت تایپ کاربر تنظیم کن.
برای جستجوی فوری (مثل جستجوی زنده) ۳۰۰-۵۰۰ میلی‌ثانیه عالیه.

#Codeit #Android #Kotlin #Jetpack #Flow #Coroutines #CleanCode #AndroidDev
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2🔥1
در دنیای پر دادهٔ امروز، پردازش تکراری‌ها فقط مصرف منابع و کند شدن اپ رو به دنبال داره. 🚀

آیا می‌دونستی «Flow» می‌تونه مقادیر تکراری متوالی رو قبل از رسیدن به «collector» حذف کنه؟ 🧠

با استفاده از «distinctUntilChanged»، فقط زمانی مقدار جدید به مصرف‌کننده می‌رسه که باهاش متفاوت باشه. این یعنی پردازش هوشمند و بی‌دغدغه. 🎯

کاربرد عملیش کجاست؟ مثلاً «StateFlow» در «ViewModel» که فقط تغییرات واقعی رو به UI بفرسته. از نمایش دوبارهٔ لیست با همون داده جلوگیری کن.

حالا یه مثال ساده:

val numberFlow = flowOf(1, 1, 2, 2, 3, 3, 1, 2, 2)
.distinctUntilChanged()

numberFlow.collect { value ->
println("Received: $value")
}


در این کد، فقط مقادیر «1» و «2» و «3» و «1» و «2» خروجی داده می‌شن. تکرارهای متوالی مثل «1,1» یا «2,2» نادیده گرفته می‌شن. یعنی حذف هوشمند داده‌های تکراری بدون از دست دادن توالی منطقی. 🧹

یادت باشه: «distinctUntilChanged» رو با مقایسهٔ عمیق «distinctUntilChangedBy» اشتباه نگیری. اولی برابر ساده (با «equals») و دومی بر اساس «selector» دلخواه عمل می‌کنه. 🛠️

پس توی پروژه‌های حرفه‌ای، از این اپراتور برای بهینه‌سازی «Recomposition» در «Jetpack Compose» و کاهش بار پردازشی استفاده کن. 🚀

#Codeit #Android #Kotlin #Jetpack #Flow #Coroutines #DistinctUntilChanged #Performance
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2👍1
This media is not supported in your browser
VIEW IN TELEGRAM
🔥 در کاتلین، ما استانداردهای آموزش رو جابه‌جا می‌کنیم!
برنامه‌نویسی اندروید فقط یادگیری چند خط کد ساده نیست؛ اجرا کردن ایده‌های بزرگ با کدهای تمیز، سریع و بهینه‌ست. Kotlin ​تا این مسیر رو برات هموار کنیم.
ما توی کدایت با قدرت، تخصص و به صورت کاملاً عمیق روی آموزش کاتلین — از مفاهیم اولیه تا پیچیده‌ترین سطوح پیشرفته — تمرکز کردیم. هدف ما اینه که به جای یادگیری سطحی، به تسلط واقعی و بازارکاری برسی.
💡 چرا محتوای آموزشی کدایت؟
⚡️ مسیر سناریومحور: یادگیری مفاهیم در قالب پروژه‌ها و نیازهای واقعی بازار
⚡️ معماری‌های مدرن اندروید
⚡️ Guide to Clean Code: Clean Code (Best Practices)
اگر می‌خوای توی دنیای کاتلین یک لول بالاتر از بقیه قرار بگیری، جای درستی اومدی. ما پرقدرت کنارت هستیم! 💪

#Codeit #Android #Kotlin #Jetpack #Flow #Coroutines #DistinctUntilChanged #Performance
🌐 Codeit → https://code-it.ir

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