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

Kotlin • Android

🚀 آموزش ساده، کاربردی و پروژه‌محور
💡 مخصوص توسعه‌دهندگان موبایل
Download Telegram
سوال درست پرسیدن، نیمی از راه حل است. 🧠
خیلی از برنامه‌نویس‌ها وقتشون رو توی فروم‌ها و گروه‌ها تلف می‌کنن، چون سوالشون رو درست نمی‌پرسن. 😫
وقتی سوال خوب می‌پرسی، هم زودتر جواب می‌گیری، هم بقیه یاد می‌گیرن.

نکته اول: مشکل رو دقیق توصیف کن. نگو «کد من کار نمی‌کنه»، بگو «در «Kotlin» وقتی از «StateFlow» استفاده می‌کنم، مقدار اولیه رو نمی‌گیرم». 🎯
نکته دوم: کدت رو کوتاه و قابل اجرا بذار. خطا رو کامل بنویس.
نکته سوم: بگو چیکار کردی تا حلش کنی. این نشون می‌ده باهوشی و وقت آدم‌ها رو نمی‌گیری. 💡

مثال واقعی: به جای «اپلیکیشنم کرش می‌کنه»، بنویس «در «Jetpack Compose» وقتی روی دکمه کلیک می‌کنم، «NullPointerException» می‌گیرم. کد «Button» رو با «viewModelScope.launch» اجرا کردم ولی هنوز خطا دارم».

نتیجه: سوال خوب = جواب سریع = یادگیری عمیق‌تر. 🚀
از امروز تمرین کن. هر سوالی یه قدم به حرفه‌ای‌تر شدنت نزدیک‌ترت می‌کنه.

#Codeit #Android #Kotlin #Jetpack #ProgrammingTips #ProblemSolving #DeveloperMindset #TechCommunity
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥2
🔹 «Map» در کاتلین یک ساختار کلید-مقدار قدرتمنده که توی ۹۰٪ پروژه‌های اندروید باهاش کار میکنی.
🔸 برخلاف لیست که با ایندکس عددی کار میکنه، اینجا هر مقدار با یه کلید منحصربه‌فرد ذخیره میشه.
🔹 دو نوع اصلی داریم: «immutable» (فقط خواندنی) و «mutable» (قابل تغییر).

📌 یه سناریوی واقعی: ذخیره‌ی تنظیمات کاربر (مثل تم، زبان و اندازه فونت) به‌جای چندتا متغیر جدا.

💡 بیا یه «Map» بسازیم و روش عملیات پایه رو یاد بگیریم:

val settings = mutableMapOf(
"theme" to "dark",
"language" to "en",
"fontSize" to 14
)

// دسترسی به مقدار
println(settings["theme"]) // dark

// اضافه کردن کلید جدید
settings["notifications"] = true

// بروزرسانی مقدار
settings["fontSize"] = 16

// حذف کلید
settings.remove("language")

// بررسی وجود کلید
if (settings.containsKey("theme")) {
println("Theme is set")
}


🔹 «mutableMapOf» یک «MutableMap» میسازه که میتونی مقادیرش رو تغییر بدی.
🔸 با براکت [] هم میتونی بخونی هم بنویسی – اگه کلید نباشه، مقدار null برمی‌گردونه.
🔹 to یه «Pair» میسازه و به‌عنوان ورودی به «mutableMapOf» میره.

🔥 نکته مهم: در کاتلین بهتره تا حد امکان از «immutable map» استفاده کنی تا کدت خطاناپذیرتر بشه.

🚀 تمرین کن: یه «Map» از وضعیت آیتم‌های یه لیست خرید درست کن و عملیات بالا رو روش انجام بده.

#Codeit #Android #Kotlin #Map #Collection #DataStructures
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2
🔹 دوست داری تو یه خط، کل لیست رو تغییر بدی یا فیلتر کنی؟
«map» و «filter» دو تا از قدرتمندترین عملیات‌های مجموعه در «Kotlin» هستن که کدت رو خواناتر و سریع‌تر می‌کنن 😎

🔸 «map» هر المان رو به چیز دیگه‌ای تبدیل می‌کنه. مثلاً لیست اعداد رو به مربع‌شون تبدیل کن.
🔸 «filter» فقط المان‌هایی رو نگه می‌داره که شرط مشخصی داشته باشن. مثلاً فقط اعداد زوج.

📌 کاربرد واقعی: فرض کن لیست قیمت‌های محصولات داری. می‌خوای قیمت‌های بالای ۱۰۰ رو با تخفیف ۲۰٪ نشون بدی.

🔹 اول کد رو ببین:

val prices = listOf(50, 150, 200, 80, 300)

val discounted = prices
.filter { it > 100 }
.map { it * 0.8 }

println(discounted) // [120.0, 160.0, 240.0]


🔸 توضیح: اول با «filter» قیمت‌های بزرگتر از ۱۰۰ رو جدا می‌کنیم، بعد با «map» هر کدوم رو در ۰.۸ ضرب می‌کنیم. نتیجه یه لیست جدید از تخفیف‌هاست.

💡 نکته: این دو عملیات قابل زنجیره شدن هستن و باعث می‌شن نیازی به حلقه‌های تودرتو نباشه. کد تمیزتر و کم‌خطاتر می‌شه.

برداشت عملی: هر وقت خواستی روی یه لیست تغییرات دسته‌جمعی بدی یا فیلترش کنی، از «map» و «filter» استفاده کن. با تمرین، دیگه از «for» بی‌نیاز می‌شی!

#Codeit #Android #Kotlin #Jetpack #FunctionalProgramming #CollectionOperations
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
📦 در دنیای «Kotlin»، وقتی با لیست‌های تو در تو سروکار دارید، دو تا از قدرتمندترین ابزارها «flatMap» و «flatten» هستند.🧩 خیلی ساده بگم: «flatten» یک لیست از لیست‌ها رو به یک لیست تخت تبدیل می‌کنه و «flatMap» همون کار رو انجام میده ولی قبلش به هر عنصر یک نگاشت (مپ) اعمال میکنه.🤯 فرض کنید یک لیست از کاربران دارید که هر کاربر یک لیست از سفارشاتش رو داره. می‌خواید همه سفارشات رو یکجا ببینید. اول با «flatMap» می‌بینیم چطور کار میکنه.

کد عملی:

data class Order(val id: Int, val amount: Double)
data class User(val name: String, val orders: List<Order>)

val users = listOf(
User("Ali", listOf(Order(1, 100.0), Order(2, 200.0))),
User("Sara", listOf(Order(3, 150.0))),
User("Reza", listOf())
)

// استفاده از flatMap برای استخراج همه سفارشات
val allOrders: List<Order> = users.flatMap { it.orders }
println(allOrders) // [Order(1,100.0), Order(2,200.0), Order(3,150.0)]

// flatten فقط برای لیست‌های لیست بدون تغییر عناصر کار میکنه
val listOfLists = listOf(listOf(1,2), listOf(3,4), emptyList())
val flattened = listOfLists.flatten()
println(flattened) // [1, 2, 3, 4]


در این کد: «flatMap» به هر کاربر (عنصر) دسترسی پیدا میکنه، خاصیت «orders» رو برمی‌گردونه و سپس همه لیست‌ها رو در یک لیست تخت می‌ریزه. «flatten» هم برای حالتی که فقط لیست‌های لیست داریم و نمی‌خوایم تغییری در محتوا بدیم عالیه.💡 نکته کلیدی: «flatMap» معادل «map» + «flatten» هستش، ولی خیلی خواناتر و بهینه‌تر.

🔥 کاربرد واقعی: وقتی API‌ای دارید که داده‌های تو در تو برمی‌گردونه (مثلاً لیست گروه‌ها و هر گروه شامل لیست محصولات)، با «flatMap» می‌تونید سریع همه محصولات رو استخراج کنید و در «RecyclerView» نمایش بدید.🚀 این عملیات‌ها باعث میشن کدتون خواناتر، فشرده‌تر و دور از حلقه‌های تودرتو باشه. حتماً توی پروژه‌هاتون امتحان کنید.

#Codeit #Android #Kotlin #Jetpack #KotlinCollections #FlatMap #Flatten #FunctionalProgramming
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🥰1
🧠 «Problem Solving» یکی از مهم‌ترین مهارت‌های یک برنامه‌نویس حرفه‌ای‌ست، ولی خیلی‌ها فقط کد می‌زنن بدون اینکه ذهنشون رو برای حل مسائل عمیق تمرین بدن.

🚀 «Becoming a Better Problem Solver» یعنی یاد بگیری چطور به جای وحشت از باگ‌ها و خطاها، ازشون به عنوان چالش یادگیری استفاده کنی.

💡 اولین قدم: مسئله رو خوب تعریف کن. تا نفهمی دقیقاً مشکل چیه، راه‌حل درست پیدا نمی‌شه.

🔍 دومین قدم: مسئله رو به بخش‌های کوچیکتر بشکن. مثل «Divide and Conquer» تو دنیای الگوریتم‌ها.

🧩 سومین قدم: راه‌حل‌های مختلف رو لیست کن. حتی اون‌هایی که احمقانه به نظر میرسن. گاهی بهترین ایده از عجیب‌ترین جاها میاد.

📝 چهارمین قدم: راه‌حل رو روی کاغذ یا تو ذهنت شبیه‌سازی کن. قبل از نوشتن کد، مطمئن شو منطق کار می‌کنه.

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

🎯 نکته کلیدی: هر روز حداقل یک مسئله کوچیک حل کن. از سایت‌هایی مثل «LeetCode» یا «Codewars» استفاده کن.

🔥 یادت باشه: بهترین برنامه‌نویس‌ها کسایی نیستن که هیچوقت باگ ندارن، بلکه کسایی هستن که بهترین روش حل مسئله رو بلدن.

این مهارت رو می‌تونی تو پروژه‌های واقعی «Android» با «Kotlin» هم تمرین کنی. مثلاً وقتی معماری «Clean Architecture» رو پیاده می‌کنی، ذهنت خودش مسئله‌ها رو به لایه‌های مستقل تقسیم می‌کنه.

📈 نتیجه: هر بار که یه مشکل سخت رو حل می‌کنی، یه قدم به یه برنامه‌نویس حرفه‌تر نزدیک‌تر می‌شی.

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

━━━━━━━━━━━━━━━
@CodeitMobile
1
🔥 توی دنیای واقعی، همیشه داده‌ها رو بر اساس یه ویژگی مشترک دسته‌بندی می‌کنیم. مثلاً مشتری‌ها بر اساس شهر، یا محصولات بر اساس دسته‌بندی. توی «Kotlin» یه تابع خفن به اسم «groupBy» هست که دقیقاً همین کار رو می‌کنه.

🌀 «groupBy» یه عملیات «Collection» هست که لیست رو بر اساس یه کلید مشخص به «Map» تبدیل می‌کنه. هر کلید به لیستی از آیتم‌هایی که اون کلید رو دارند اشاره می‌کنه.

فرض کن لیستی از سفارش‌های یک فروشگاه آنلاین داری. می‌خوای سفارش‌ها رو بر اساس وضعیت (مثلاً «پرداخت شده» یا «در انتظار») دسته‌بندی کنی. اینجا «groupBy» عالیه.

📌 بیا یه مثال ساده ببینیم. اول یه «data class» برای سفارش تعریف می‌کنیم:

data class Order(
val id: Int,
val status: String,
val amount: Double
)


🧩 حالا یه لیست از سفارش‌ها داریم و می‌خوایم با «groupBy» دسته‌بندیشون کنیم:

val orders = listOf(
Order(1, "Paid", 150.0),
Order(2, "Pending", 200.0),
Order(3, "Paid", 300.0),
Order(4, "Canceled", 50.0),
Order(5, "Pending", 120.0)
)

val groupedByStatus = orders.groupBy { it.status }


📊 حالا «groupedByStatus» یه «Map» هست که کلیدش وضعیت و مقدارش لیست سفارش‌های هم‌وضعیت‌ه. مثلاً:

// خروجی:
// {Paid=[Order(1, Paid, 150.0), Order(3, Paid, 300.0)],
// Pending=[Order(2, Pending, 200.0), Order(5, Pending, 120.0)],
// Canceled=[Order(4, Canceled, 50.0)]}


💡 اگه نیاز به دسته‌بندی پیشرفته‌تر داشته باشی، «groupBy» می‌تونه یه «lambda» برای تبدیل مقدار هم قبول کنه. مثلاً فقط اسم سفارش‌ها رو ذخیره کنی:

val groupedIds = orders.groupBy(
keySelector = { it.status },
valueTransform = { it.id }
)
// خروجی: {Paid=[1, 3], Pending=[2, 5], Canceled=[4]}


🚀 این تابع توی هر جایی که نیاز به دسته‌بندی داری به کار میاد: از داشبورد مدیریت تا گزارش‌گیری و تحلیل داده. حتماً تو پروژه‌هات استفاده کن.

#Codeit #Android #Kotlin #Jetpack #CollectionOperations #groupBy #KotlinTips
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
🧩 لیست‌هات رو مرتب می‌کنی، اما می‌خوای بر اساس یه خاصیت مشخص مرتب‌سازی کنی؟ «sortedBy» تو «Kotlin» دقیقاً همین کار رو انجام میده. دیگه نیاز نیست خودت بنویسی که چطور مقایسه کنی.

«sortedBy» یه lambda می‌گیره که مشخص می‌کنه بر اساس کدوم خاصیت (مثلاً اسم، سن، تاریخ) لیست مرتب بشه. برعکس «sorted» که فقط روی خود آیتم‌ها کار می‌کنه (مثلاً اعداد یا رشته‌ها).

💡 فرض کن یه لیست از کاربرا داری و می‌خوای بر اساس «age» (سن) صعودی مرتب بشن. با «sortedBy» خیلی راحت میشه.

کد عملی رو با یه مثال واقعی ببین:

data class User(val name: String, val age: Int)

fun main() {
val users = listOf(
User("Ali", 25),
User("Sara", 30),
User("Reza", 22)
)
val sortedUsers = users.sortedBy { it.age }
println(sortedUsers)
}


تو این کد یه لیست از کاربرا با نام و سن داریم. با «sortedBy { it.age }» لیست رو بر اساس سن به ترتیب صعودی مرتب می‌کنیم. خروجی: «User(name=Reza, age=22), User(name=Ali, age=25), User(name=Sara, age=30)».

نکته مهم: «sortedBy» یه لیست جدید برمی‌گردونه و لیست اصلی رو تغییر نمی‌ده (immutable). اگر نیاز به مرتب‌سازی نزولی داری، از «sortedByDescending» استفاده کن.

با «sortedBy» می‌تونی هر نوع داده‌ای رو بر اساس یه خاصیت به راحتی مرتب کنی. این یه ابزار قدرتمنده برای پردازش لیست‌ها تو «Kotlin».

#Codeit #Android #Kotlin #Jetpack #CollectionOperations #Sorting #KotlinTips
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥2
لاندا اکسپرشن‌ها تو «Kotlin» مثل یک تابع بینام هستن که می‌تونی بدی به یه متد دیگه تا اجرا کنه. 😎 خیلی کدت رو خواناتر و کوتاه‌تر می‌کنه. بیا ببینیم چطور کار می‌کنه.

🔹 یه لاندا اکثراً با {} نوشته میشه و اگه فقط یه پارامتر داشته باشه می‌تونی از it استفاده کنی.

🔸 کاربرد واقعی: مثلاً فیلتر کردن یه لیست از اعداد. بدون لاندا باید یه حلقه می‌نوشتی، ولی با لاندا یه خط کافیه.

کد زیر رو ببین:
val numbers = listOf(1, 2, 3, 10, 15)
val filtered = numbers.filter { it > 5 }
println(filtered) // خروجی: [10, 15]

این کد با استفاده از تابع filter و یه لاندا اکسپرشن، اعداد بزرگ‌تر از ۵ رو برمی‌گردونه. «it» همون عنصر جاری لیسته.

💡 نکته: می‌تونی لاندا رو به عنوان آخرین پارامتر تابع بدی (Trailing Lambda Syntax) که خیلی رایج‌تره.

📌 حالا یه مثال کاربردی‌تر: فرض کن می‌خوای روی یه لیست از کاربران، اونایی که سنشون بالای ۱۸ هست رو پیدا کنی:
data class User(val name: String, val age: Int)
val users = listOf(User("Ali", 20), User("Sara", 17), User("Reza", 25))
val adults = users.filter { it.age >= 18 }
adults.forEach { println(it.name) } // خروجی: Ali, Reza


🧠 لانداها تو «Kotlin» برای callbackها، پردازش مجموعه‌ها و حتی تعریف شنونده‌ها توی «Android» عالی‌ان.

🎯 نتیجه: لاندا اکسپرشن‌ها یکی از قدرتمندترین ابزارهای «Kotlin» هستن. تمرین کن تا کدت حرفه‌ای‌تر بشه.

#Codeit #Android #Kotlin #Jetpack #Lambda #FunctionalProgramming #CleanCode
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
مدیریت زمان برای توسعه‌دهنده‌ها؛ مهارتی که از هر فریمورکی مهم‌تر است!
🕰️ روزها کوتاه‌تر از آن‌اند که غرق در تسک‌های بی‌پایان شوید.

🧠 ذهن ما مثل یک پردازنده‌ست: اگر چند کار همزمان بهش بدهید، همه را ناقص انجام می‌دهد.
قانون طلایی: «تک‌وظیفگی» را جایگزین «چند‌وظیفگی» کنید.

🎯 اولویت‌بندی با متد «آیزنهاور»: کارها را به چهار دسته تقسیم کنید:
۱. مهم و فوری → همین حالا
۲. مهم و غیرفوری → زمان‌بندی
۳. غیرمهم و فوری → برون‌سپاری
۴. غیرمهم و غیرفوری → حذف

⏱️ تکنیک «پومودورو» را امتحان کنید: ۲۵ دقیقه کار متمرکز، ۵ دقیقه استراحت.
📱 ابزارهایی مثل «Todoist» یا «Notion» می‌توانند نقشه راه شما باشند.

💡 یک نکته عملی: هر روز صبح ۳ کار اصلی روز را بنویسید و تا انجام نشدنشان سراغ بقیه نروید.
📉 رشد درآمد و پیشرفت شغلی شما مستقیماً به توانایی مدیریت زمان وابسته است.

🚀 از فردا شروع کنید: دفترچه‌ای بردارید، اولویت‌ها را مشخص کنید و تایمر را بزنید.
🔄 دو هفته بعد، نتیجه را خودتان خواهید دید.

#Codeit #TimeManagement #DeveloperProductivity #Pomodoro #Focus #Android #Kotlin #Jetpack
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥1
🔴 تفاوت اخبار…

#حاشیه
🪙 @CodeitMobile
😨1
🔥 توابع مرتبه‌بالا (Higher-order functions) تو «کاتلین» یه ابزار قدرتمند برای نوشتن کد تمیز و قابل استفاده مجدد هستن. یعنی تابعی که یا تابع دیگه‌ای رو به عنوان ورودی می‌گیره، یا یک تابع رو برمی‌گردونه. این کار کدت رو انعطاف‌پذیر می‌کنه.

📌 توی پروژه‌های واقعی مثلاً می‌خوای عملیات تکراری مثل نمایش پیام خطا یا ذخیره اطلاعات رو با رفتارهای مختلف یکپارچه کنی. به‌جای نوشتن چندین تابع جدا، می‌تونی یک تابع مرتبه‌بالا بنویسی که تابع مورد نظر رو بهش پاس بدی.

🧩 بیایم یه مثال ساده بزنیم:

fun performOperation(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
return operation(a, b)
}

fun main() {
val sum = performOperation(5, 3) { x, y -> x + y }
val product = performOperation(5, 3) { x, y -> x * y }
println("Sum: $sum, Product: $product")
}


📝 این کد یه تابع مرتبه‌بالا به اسم «performOperation» داره که دو عدد و یه تابع به اسم «operation» می‌گیره. بعد توی «main» دو بار با عملیات جمع و ضرب صدا زده شده. نتیجه: بدون تکرار کد، دو رفتار متفاوت داریم.

🎯 نکته مهم: ازش تو «Jetpack Compose» برای مدیریت رویدادها و ترکیب‌های شرطی استفاده می‌کنن. مثلاً تو «StateFlow» و «Callback»ها خیلی به کار میاد.

💡 نتیجه: یادگیری توابع مرتبه‌بالا کدتو خشک‌تر و خواناتر می‌کنه. حتماً تمرین کن.

#Codeit #Android #Kotlin #Jetpack #HigherOrderFunctions #FunctionalProgramming #CleanCode #KotlinTips
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥1🥰1
آیا می‌دونستی می‌تونی نوع یه تابع رو درست مثل نوع داده‌های معمولی تعریف کنی و به عنوان پارامتر یا متغیر استفاده کنی؟ 🔥

تو «Kotlin»، «Function Type» یعنی مشخص کردن ورودی و خروجی یه تابع به عنوان یه نوع داده. مثلاً «(Int) -> String» یعنی تابعی که یک عدد می‌گیره و یک رشته برمی‌گردونه.

خیلی جاها به کار میاد: وقتی می‌خوای یه تابع رو به تابع دیگه بدی (Higher-Order Function) یا یه لیست از توابع داشته باشی.

بیایم یه مثال ساده بزنیم:

fun executeOperation(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
return operation(a, b)
}

fun main() {
val sum = executeOperation(5, 3) { x, y -> x + y }
val product = executeOperation(5, 3) { x, y -> x * y }

println("Sum: $sum")
println("Product: $product")
}


این کد یه تابع به اسم «executeOperation» داره که دو عدد و یه «Function Type» به اسم «operation» می‌گیره. توی «main» دو بار با lambdaهای مختلف صداش می‌زنیم: یکی جمع و یکی ضرب.

کاربرد عملی: می‌تونی با «Function Type» کد خشک‌تر و انعطاف‌پذیرتر بنویسی – مثلاً برای فیلتر کردن لیست یا اعمال تبدیلات مختلف روی داده‌ها. 🚀

#Codeit #Android #Kotlin #Jetpack #FunctionTypes #HigherOrderFunctions #Lambda
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
🔥2
🔹آیا تابه‌حال تابعی نوشته‌اید که فقط برای یک نوع داده کار کند و مجبور شده‌اید بارها کد تکراری بنویسید؟
🔸«Generics» در «Kotlin» این مشکل را یک‌بار برای همیشه حل می‌کند.

💡 Generics چیست؟
به شما اجازه می‌دهد کلاس‌ها، توابع و اینترفیس‌ها را بدون وابستگی به یک نوع خاص تعریف کنید و هم‌زمان «Type Safety» را حفظ کنید.

🛠️ مثال عملی:
یک کلاس جعبه (Box) می‌سازیم که بتواند هر نوع داده‌ای را ذخیره کند:

class Box<T>(private val item: T) {
fun getContent(): T = item
}

fun main() {
val stringBox = Box<String>("Hello")
val intBox = Box<Int>(42)

println(stringBox.getContent()) // Hello
println(intBox.getContent()) // 42
}


این کد نشان می‌دهد که چگونه با یک کلاس «Generic»، هم از رشته و هم از عدد بدون خطا استفاده می‌کنیم.
🔐 «Type Safety» در زمان کامپایل تضمین می‌شود و نیازی به «Casting» دستی نیست.

🧠 نکته کلیدی:
از «Generics» در لیست‌ها، «LiveData»، «Repository»، و حتی «ViewModel» هم استفاده می‌شود. مثلاً «MutableList<T>» یا «LiveData<T>».

📌 جمع‌بندی:
با «Generics» کدتان انعطاف‌پذیرتر، قابل استفاده مجدد و امن‌تر می‌شود.
📅 امروز یک کلاس «Generic» بنویسید و قدرت آن را لمس کنید.

#Codeit #Android #Kotlin #Jetpack #Generics #TypeSafety #CleanCode #KotlinTips

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

━━━━━━━━━━━━━━━
@CodeitMobile
1🥰1
🔰 عادت‌های روزانه‌ی «Senior Developer»ها رو می‌دونی؟ 🧠

روزهایی که فقط کد می‌زنن و تموم می‌شه، گذشته… 🙌

یک «Senior Developer» واقعی هر روز چند کار ساده اما حیاتی انجام می‌ده:

۱. صبح‌ها کد قدیمی خودش رو مرور می‌کنه 👀
۲. قبل از نوشتن یک خط کد، معماری مسئله رو روی کاغذ می‌کشه ✍️
۳. روزش رو با مطالعه‌ی مستندات «API»ها شروع می‌کنه 📚
۴. حتماً یک ساعت رو به یادگیری تکنولوژی جدید اختصاص می‌ده (حتی ۱۵ دقیقه)
۵. کدش رو قبل از «Code Review» خودش بررسی می‌کنه 🔍
۶. با تیمش ارتباط شفاف داره و سوالات «به‌ظاهر احمقانه» رو می‌پرسه 🗣️

این عادت‌ها باعث می‌شه اعتمادبه‌نفس و کیفیت کار به مرور زمان چند برابر بشه. 🚀

💡 نکته‌ی عملی:
همین امروز یک تایمر ۲۵ دقیقه‌ای بذار و فقط روی مستندات یک «API» یا یک «Library» جدید تمرکز کن. بعد از ۲۵ دقیقه، یک یادداشت کوتاه ازش بنویس.

یادت باشه: «Senior» شدن با تعداد سال‌ها اندازه‌گیری نمی‌شه، بلکه با عادت‌های روزانه‌ای که داری. 🎯

#Codeit #Android #Kotlin #Jetpack #DeveloperHabits #SeniorDeveloper #CleanCode #GrowthMindset
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
گاهی وقتا توی «Kotlin» مجبوریم ژنریک رو محدود کنیم تا فقط تایپ‌های خاصی قبول بشن. اینجاست که «Generic Constraints» به کمک میاد! 🎯

مفهومش سادست: می‌تونی یه «Type Parameter» رو به یه کلاس یا اینترفیس خاص محدود کنی. مثلاً بگی این تابع فقط با تایپ‌هایی کار کنه که «Comparable» هستن. اینطوری کدت هم ایمن‌تر میشه هم خطاهای زمان کامپایل کاهش پیدا می‌کنه. 🔒

یه مثال کاربردی: فرض کن می‌خوای یه تابع بنویسی که بزرگ‌ترین عنصر یه لیست رو برگردونه. ولی نه هر لیستی، فقط لیستی از چیزایی که قابل مقایسه باشن. اینجاست که از «upper bound constraint» استفاده می‌کنیم.

کد زیر رو ببین:

fun <T : Comparable<T>> maxOfList(list: List<T>): T? {
if (list.isEmpty()) return null
var max = list[0]
for (item in list) {
if (item > max) max = item
}
return max
}


این تابع فقط تایپ‌هایی رو می‌پذیره که اینترفیس «Comparable» رو پیاده‌سازی کرده باشن. پس اگه بخوایم براش یه لیست از «Int» یا «String» بدیم کار می‌کنه، ولی اگه یه شیء سفارشی بدون «Comparable» بدیم، کامپایلر خطا میده. 🧠

نتیجه: با «Generic Constraints» کدت خواناتر و خطاهای زمان اجرا به حداقل می‌رسه. یه ابزار ضروری برای کتابخونه‌نویسی و API‌های تمیز. 🛠️

#Codeit #Android #Kotlin #Jetpack #Generics #TypeSafety #KotlinTips
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
🎯 می‌خوایم توی «Kotlin» بفهمیم که چطور «Variance» کار می‌کنه و «in» و «out» چطور از خطاهای تایپ جلوگیری می‌کنن.

🧠 فرض کن یه کلاس داری که فقط تولید می‌کنه (مثل «Producer») و یه کلاس دیگه که فقط مصرف می‌کنه (مثل «Consumer»). اگه «Variance» رو درست مدیریت نکنی، کامپایلر ارور می‌ده.

💡 مثال واقعی: توی یک اپلیکیشن اندروید، یه لیست از آیتم‌های مختلف داری که فقط باید بخونی (تولید) یا فقط بنویسی (مصرف). «in» و «out» توی «Generics» این کار رو برات آسون می‌کنن.

🧑‍💻 بیا با یه کد عملی ببینیم:

// تعریف یک کلاس والد و دو کلاس فرزند
open class Animal
class Dog : Animal()
class Cat : Animal()

// Producer فقط خروجی می‌ده (covariant)
class Producer<out T>(private val item: T) {
fun produce(): T = item
}

// Consumer فقط ورودی می‌گیره (contravariant)
class Consumer<in T> {
fun consume(item: T) {
println("Consuming: $item")
}
}

fun main() {
val dogProducer: Producer<Dog> = Producer(Dog())
val animalProducer: Producer<Animal> = dogProducer // مجازه چون out است
val animal: Animal = animalProducer.produce()

val animalConsumer: Consumer<Animal> = Consumer()
val dogConsumer: Consumer<Dog> = animalConsumer // مجازه چون in است
dogConsumer.consume(Dog())
}


📌 کد بالا رو توضیح بدم:
- Producer<out T> یعنی نوع T فقط توی خروجی استفاده می‌شه، پس Producer<Dog> رو می‌تونی به Producer<Animal> نسبت بدی (covariance).
- Consumer<in T> یعنی نوع T فقط توی ورودی استفاده می‌شه، پس Consumer<Animal> رو می‌تونی به Consumer<Dog> نسبت بدی (contravariance).
- این کار باعث می‌شه از ارورهای تایپ در زمان کامپایل جلوگیری بشه و کدت انعطاف‌پذیرتر بشه.

🎯 نکته عملی: وقتی از «LiveData» یا «StateFlow» استفاده می‌کنی، خروجی‌شون «out» هست (فقط خواندنی) و ورودی توی «Room» می‌تونه «in» باشه. این رو توی پروژه‌هات رعایت کن.

🔥 با تسلط به «Variance» کدهای «Kotlin»ت نوع‌محور و خطاناپذیرتر می‌شن.

#Codeit #Kotlin #Android #Jetpack #Generics #Covariance #Contravariance
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
🔥 استثناها رو قورت نده! مدیریت حرفه‌ای خطاها با «try» و «catch» در «Kotlin» 🚀

برنامه‌نویس حرفه‌ای کسی نیست که بدون خطا کد بزنه، کسی‌ست که می‌دونه چطور با خطاها برخورد کنه. توی «Kotlin» مدیریت استثناها با «try-catch» ساده و قدرتمنده.

تصور کن کاربر متنی رو وارد کنه که عدد نیست و برنامه کرش کنه! این اصلاً حرفه‌ای نیست.

باید پیش‌بینی کنی که ممکنه خطا رخ بده و با «try-catch» کنترلش کنی.

📌 کاربرد واقعی: وقتی از کاربر ورودی می‌گیری، حتماً از «try-catch» برای تبدیل امن استفاده کن.

مثال عملی: عدد از کاربر بگیر و اگر اشتباه وارد کرد، خطا رو مدیریت کن:

fun readNumber(): Int? {
return try {
val input = readLine()
input?.toInt()
} catch (e: NumberFormatException) {
println(" ورودی معتبر نیست، لطفاً عدد وارد کنید.")
null
}
}


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

💡 نکته مهم: همیشه «catch» رو برای نوع خاصی از استثنا بنویس، نه همه خطاها. از «Exception» عمومی فقط در مواقع ضروری استفاده کن.

🎯 نتیجه: کدت پایدارتر می‌شه، کاربر تجربه بهتری داره و دیباگ راحت‌تره.

#Codeit #Android #Kotlin #ExceptionHandling #TryCatch #CleanCode #ProgrammingTips
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
1🔥1
کد خواناتر یعنی احترام به خودِ آینده‌ات 😎
خوانایی فقط ظاهر نیست؛ روی سرعت توسعه و دیباگ تأثیر مستقیم داره.
وقتی کدت رو برای دیگران (و خودت) روشن می‌نویسی، اشکال‌زدایی نصف می‌شه.

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

یک مثال ساده از تفاوت کد بد و خوب:

// کد غیرقابل خواندن
fun a(b: List<Int>): Int { var c = 0; for (d in b) { if (d > 0) c += d }; return c }

// کد خوانا
fun sumPositiveNumbers(numbers: List<Int>): Int {
return numbers.filter { it > 0 }.sum()
}


تابع اول با اسم‌های تک‌حرفی و ساختار فشرده، فهمش سخته.
دومی با اسم معنادار و استفاده از «filter» و «sum» در یک خط، هدف رو واضح می‌کنه.

همیشه قبل از نوشتن کد به این فکر کن که آیا ۶ ماه بعد متوجه‌اش می‌شی؟
اگر نه، بازنویسی کن. همین یک عادت، کیفیت کارت رو چند برابر می‌کنه 🚀

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

━━━━━━━━━━━━━━━
@CodeitMobile
1👍1🔥1
🔒 تو کد نویسی، بعضی عملیات‌ها رو باید حتماً تموم کنی حتی اگه خطا بیاد!
«Finally block» در «Kotlin» دقیقاً همین کار رو میکنه.

📌 کاربرد اصلی: بستن فایل، قطع connection یا آزاد کردن حافظه
مهم نیست خطا رخ بده یا نه، کد داخل «finally» همیشه اجرا میشه.

💡 مثال واقعی: فرض کن داری فایل می‌خونی؛ اگه خطا هم بیاد، فایل باید بسته بشه.

یک نمونه ساده از ترکیب try-catch-finally:

fun readFile(path: String): String? {
val file = File(path)
return try {
file.readText()
} catch (e: IOException) {
println("خطا در خواندن فایل: ${e.message}")
null
} finally {
println(" فایل حتماً بسته می‌شه (در عمل اینجا close داریم)")
}
}


🧠 این کد نشون میده که حتی در صورت خطا، finally اجرا شده و پیام چاپ می‌شه.
توی پروژه‌های واقعی، مثلاً close() رو توی finally می‌ذارن تا منبع نشتی نداشته باشه.

🎯 نکته مهم: اگر داخل try یا catch از return استفاده کنی، بازم finally قبل از برگشت اجرا میشه.

پس برای مدیریت مطمئن منابع، هیچ جایگزینی باحال‌تر از «finally block» نیست!

#Codeit #Android #Kotlin #Jetpack #ExceptionHandling #CleanCode #FinallyBlock
🌐 Codeit → https://code-it.ir

━━━━━━━━━━━━━━━
@CodeitMobile
2👍1🔥1
جمله متقاعد کننده امروز: درد دیسیپلین از درد پشیمونی کمتره.

👀@CodeitMobile
👍1🔥1
🔹 توی پروژه‌های واقعی، خطاها رو با «Exception» استاندارد جاوا مدیریت نکن! 🚫
🔸 بیا ببینیم چطور «Custom Exception»های اختصاصی توی «Kotlin» بسازیم که دیباگ و نگهداری کد رو خیلی راحت‌تر کنه.

🔹 فرض کن داری یک اپ پرداخت می‌نویسی. به‌جای اینکه هر بار «IllegalArgumentException» پرت کنی، یک «InsufficientBalanceException» بساز که دقیقاً بگه مشکل چیه.

🔸 این کار خوانایی خطاها رو بالا می‌بره و توی «Log»ها دقیقاً می‌فهمی کجا خطا رخ داده.

🔹 یک مثال ساده از «Custom Exception» در «Kotlin»:

class InsufficientBalanceException(
val currentBalance: Double,
val requiredAmount: Double
) : Exception("موجودی کافی نیست. موجودی: $currentBalance، نیاز: $requiredAmount")

fun processPayment(amount: Double, balance: Double) {
if (amount > balance) {
throw InsufficientBalanceException(balance, amount)
}
println("پرداخت با موفقیت انجام شد")
}


🔸 این کد یک «Exception» سفارشی با دو ویژگی عددی می‌سازه و پیام خطا رو خودش تولید می‌کنه. توی تابع پرداخت هم اگر موجودی کم باشه، این خطا پرتاب می‌شه.

🔹 نکته مهم: می‌تونی توی «Custom Exception» متدها یا پراپرتی‌های اضافه هم تعریف کنی. مثلاً یک متد برای لاگ‌کردن جزئیات خطا.

🔸 حالا توی کد اصلی می‌تونی با «try-catch» دقیقاً این نوع خطا رو بگیر و پیام مناسب به کاربر نشون بدی.

🔹 خلاصه: «Custom Exception» بهت کمک می‌کنه کدت خواناتر، قابل نگهداری‌تر و حرفه‌ای‌تر باشه. همین امروز توی پروژه‌هات استفاده کن! 🚀

#Codeit #Android #Kotlin #Jetpack #CleanCode #Exceptions #KotlinTips
🌐 Codeit → https://code-it.ir

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