برنامه نویسی اندروید با زبان کاتلین
Статистикаآموزش برنامه نویسی اندروید با زبان قدرتمند کاتلین توسط علیرضا احمدی مشاوره رایگان : @alirezaahmadi_79 گروه پرسش و پاسخ : @Lrn_Group وبسایت : www.AlirezaAhmadi.info
- Последний пост
- 7 авг.
- Последнее чтение
- 13 авг.
- Постов за неделю
- 0
- Всего постов
- 26
- Тип
- открытый
- Язык
- персидский
- В каталоге с
- 13 авг.
- 1/24сутки в ленте
- 792
- 1/48двое суток
- 907
- 1/72трое суток
- 978
Оценка по просмотрам недавних постов: пост набирает почти всё за первые сутки.
Посты
#آموزش_اندروید 🚨🚨 چرا نباید رویدادها را داخل State نگه داریم؟! ❗️یکی از رایجترین اشتباهاتی که حتی در پروژههای بزرگ هم دیده میشود، نگهداری رویدادهای یکباره (Single-shot Events) داخل StateFlow یا LiveData است. ❗️فرض کنید بعد از ثبت موفق اطلاعات، میخواهید…
#آموزش_اندروید 🚨🚨 چرا نباید رویدادها را داخل State نگه داریم؟! ❗️یکی از رایجترین اشتباهاتی که حتی در پروژههای بزرگ هم دیده میشود، نگهداری رویدادهای یکباره (Single-shot Events) داخل StateFlow یا LiveData است. ❗️فرض کنید بعد از ثبت موفق اطلاعات، میخواهید یک Snackbar نمایش دهید. خیلی از برنامهنویسها این کار را انجام میدهند: uiState = uiState.copy( showSnackBar = true ) • در نگاه اول همه چیز درست کار میکند؛ اما مشکل از جایی شروع میشود که وضعیت تغییر کند یا صفحه دوباره ساخته شود! مثلاً: ✅ تغییر جهت صفحه (Rotate) ✅ بازگشت از BackStack ✅ ناخواسته Recomposition شدن ✅ شنود مجدد State • در این حالت مقدار showSnackBar همچنان true باقی مانده است و نتیجه چیست؟ نمایش مجدد Snackbar! در حالی که کاربر فقط یکبار باید آن را میدید. 💡 علت چیست؟ مفهوم State برای نگهداری وضعیت فعلی و پایدار صفحه است (مثل اطلاعات کاربر یا حالت لودینگ)، نه اتفاقاتی که فقط یکبار باید رخ دهند. ❕در قسمت بعدی یاد میگیریم که چطور این مشکل را طبق استانداردهای معماری گوگل به صورت اصولی حل کنیم. 🔥 موفق باشید🚀🚀 @KotlinMag
تا حالا شده حس کنی بیشتر از چیزی که الان هستی، ظرفیت داری… اما ندونی از کجا باید شروع کنی؟ تا حالا شده بین هدفهات، انتخاب مسیر درست، رشد شخصی و ساختن آینده بهتر سردرگم بشی؟ دوره Life Spark دقیقاً برای همینه… یک مسیر کامل و کاربردی برای اینکه خودت رو بهتر بشناسی، هدفهات رو مشخص کنی و قدمبهقدم برای ساختن نسخه بهتر خودت حرکت کنی.. در این دوره یاد میگیری چطور: ✅ مسیر رشد شخصی خودت رو پیدا کنی ✅ هدفگذاری اصولی داشته باشی ✅ عادتهای درست بسازی ✅ تصمیمهای بهتری برای آینده بگیری ✅ ذهنیت رشد و مهارتهای لازم برای موفقیت رو تقویت کنی» فقط به مدت یک هفته فرصت داری که این دوره رو با قیمت ویژه تهیه کنی بعد از پایان این زمان، این شرایط و این قیمت دیگر قابل دسترس نخواهد بود! اگر مدتهاست دنبال یک شروع جدی برای رشد خودت هستی، این همون فرصتیه که نباید از دستش بدی..👇 برای تهیه دوره و دریافت اطلاعات بیشتر به پشتیبان پیام بده: @alirezaahmadi_support ✨ Life Spark جرقهای برای شروع مسیر رشد تو
🎙️دانشجویارکست | مسیـر واقعـی رشـد در دنیـای کامپیوتـر هر برند موفقـی، یه داستان برای گفتن داره… اما داستان دانشجویار از کجا شروع شد؟ و چه چالشهایی پشت مسیر شکلگیریش بود؟ در اولین قسمت دانشجویارکست، آقای پاسبان، همبنیانگذار دانشجویار، از روزهای آغازین، چالشها، تصمیمهای مهم و تجربههایی میگن که کمتر درباره صحبت شده✨ 📺 اگر دوست داری پشتصحنه شکلگیری دانشجویار رو از زبان یکی از بنیانگذارانش بشنوی، همین حالا قسمت اول رو در یوتیوب تماشا کن👇 https://youtu.be/hSg5sRdRvuE دانشجویار؛ پل ورود به بازار کار @daneshjooyar
بزرگـتریـن چالـش بعد از یادگـیری کامپیوتـر چیــه؟🤔 مهمترین و پررنگترین مشکل کاربرای ما همیشه پیدا کردن پروژه و ارتباط گرفتن با کارفرما بوده و هنوز هم هست.👀 در واقع، تقریباً هر کسی که وارد دنیای کامپیوتر میشه، یه جا از خودش میپرسه: 👈 حالا دقیقاً باید چه مسیری برم؟ از کجا شروع کنم؟ چطور وارد بازار کار بشم؟ به همین خاطر ما دانشجویارکست رو آماده کردیم؛ مجموعهای از ویدیوها با حضور افراد مختلف و باتجربهی دانشجویار که توی اون، از مسیر شغلی خودشون، چالشهای واقعی بازار کار و تجربههایی که توی این مسیر به دست آوردن صحبت میکنن. هدفمون اینه که با استفاده از تجربههای واقعی این افراد، مسیر شغلی براتون شفافتر و هموارتر بشه.🥰🩵 برای آشنایی بیشتر با دانشجویارکست، حتماً ویدیوی مقدمه رو ببینین. 👇👇 🔗https://youtu.be/a7o0UyVh9Qg
#آموزش_اندروید 🚨🚨 کاتلین ۲.۰ و کامپایلر K2؛ شتابدهنده جدید پروژههای شما! ❗️اگر برنامهنویس اندروید هستید، حتماً بارها موقع بیلد شدن پروژههای سنگین به صفحه مانیتور خیره شدهاید! با انتشار Kotlin 2.0، موتور زیرین این زبان یعنی کامپایلر به طور کامل از نو نوشته شده و «کامپایلر K2» متولد شده است. این آپدیت یک گام رو به جلو برای پرفورمنس و هوشمندی کاتلین است. ✅ ویژگیها و تغییرات کلیدی در Kotlin 2.0: 1️⃣ بهبود محسوس سرعت کامپایل: به لطف معماری جدید K2، در بسیاری از پروژهها، بهویژه پروژههای بزرگ و ماژولار، سرعت کامپایل به شکل محسوسی افزایش یافته و در برخی سناریوها تا حدود دو برابر سریعتر شده است. 2️⃣ همگامسازی کامپایلر Compose: از Kotlin 2.0 به بعد، کامپایلر Jetpack Compose به پروژه کاتلین منتقل شده و همراه با نسخههای جدید کاتلین توسعه داده میشود. با این تغییر، یکی از بزرگترین مشکلات ناسازگاری نسخه کاتلین و کامپایلر Compose برطرف شده و مدیریت نسخهها بسیار سادهتر شده است. 3️⃣ درک عمیقتر جریان کد (Control Flow): کامپایلر K2 بسیار هوشمندتر از قبل عمل میکند و میتواند کدهای شما را عمیقتر تحلیل کند، که در نتیجه خطاهای بیدلیل کمتری در زمان کامپایل خواهید داشت. 🛠 مثال از هوشمندی K2 (Smart Casting پیشرفته): • در نسخههای قبل از ۲.۰، اگر شرط بررسی نوع (Type checking) را داخل یک متغیر محلی ذخیره میکردید، کاتلین نوع آن را در بلوکهای بعدی فراموش میکرد. اما در K2 این ساختار بسیار بهینه شده است: class Kotlin { fun kotlinMag() = println("Kotlin Mag!") } fun channelSuggestion(subject: Any) { // شرط را در یک متغیر ذخیره میکنیم val isKotlin = subject is Kotlin if (isKotlin) { // ❌ در کاتلین 1.9: ارور کامپایل میداد و نیاز به کست دستی داشت // ✅ در کاتلین 2.0: کامپایلر هوشمندانه میفهمد subject یک Kotlin است! subject.kotlinMag() } } ✨ نکته برای مهاجرت: در اغلب پروژهها، مهاجرت به نسخه جدید بدون نیاز به تغییر در کدهای قبلی انجام میشود. در بیشتر سناریوها تنها با ارتقای نسخه کاتلین میتوان از کامپایلر K2 استفاده کرد؛ البته برای پیشگیری از هرگونه تداخل، بهتر است سازگاری نسخه AGP، گریدل و سایر ابزارهای پروژه (مثل KSP یا Kapt) نیز بررسی شود. موفق باشید🚀🚀 @KotlinMag
#آموزش_اندروید 🚨🚨 چرا Composable شما بیدلیل Recompose میشود؟ (بخش اول) ❗️یکی از بزرگترین مزیتهای Jetpack Compose این است که فقط بخشهای لازم رابط کاربری را مجدداً رسم میکند. اما اگر دادهها و کلاسهای شما به درستی طراحی نشده باشند، ممکن است Compose…
#آموزش_اندروید 🚨🚨 چرا Composable شما بیدلیل Recompose میشود؟ (بخش اول) ❗️یکی از بزرگترین مزیتهای Jetpack Compose این است که فقط بخشهای لازم رابط کاربری را مجدداً رسم میکند. اما اگر دادهها و کلاسهای شما به درستی طراحی نشده باشند، ممکن است Compose تصور کند همه چیز تغییر کرده و دوباره Composableها را اجرا کند. ❕در اینجا مفهوم بسیار مهمی به نام Stability وارد میدان میشود. ✅ مفهوم Stability: زمانی که Compose بتواند تشخیص دهد یک آبجکت بعد از ساخته شدن تغییر نمیکند یا تغییراتش قابل ردیابی است، آن را Stable در نظر میگیرد و هنگام رندر صفحه، اگر داده تغییر نکرده باشد، از اجرای مجدد آن Composable صرفنظر (Skip) میکند. 🛠 مثال: data class User( val id: Int, val name: String, val hobbies: List<String> // مشکل اینجاست! ) • در نگاه اول ممکن است این کلاس کاملاً امن به نظر برسد، اما به دلیل وجود اینترفیس List، کامپایلر Compose نمیتواند درباره Stable بودن این کلاس مطمئن شود (چون ذاتاً مشخص نیست لیست زیرین غیرقابل تغییر است یا یک ArrayList معمولی و تغییرپذیر!). برای همین، Compose این کلاس را ناپایدار (Unstable) فرض میکند. ✅ چه عواملی باعث Recomposition اضافی میشوند؟ • ارسال لیستهای استاندارد (List) به Composableها • ساختن آبجکتها و لیستهای جدید داخل بدنه Composable • استفاده از کلاسهایی که فیلد var دارند یا فیلد ناپایدار دارند 🛠 نمونه اشتباه: @Composable fun UserScreen() { // در هر بار Recomposition یک لیست کاملاً جدید ساخته میشود! val users = listOf( User(1, "Ali", listOf("Coding")), User(2, "Sara", listOf("Design")) ) UserList(users) // این کامپوننت مدام بیدلیل اجرا میشود } ❕در پست بعدی یاد میگیریم چگونه با ابزارهای مخصوص Compose، این مشکل پایداری را حل کنیم و عملکرد برنامه را به شدت بالا ببریم. موفق باشید🚀🚀 @KotlinMag
#آموزش_اندروید 🚨🚨 تعامل Predictive Back با Navigation Compose (بخش دوم) ❗️در نسخههای جدید Navigation Compose (از ۲.۷ به بالا)، پشتیبانی داخلی از Predictive Back اضافه شده است. این یعنی اگر انیمیشنهای بازگشت (pop) را تعریف کنید، خودِ کتابخانه Navigation…
#آموزش_اندروید 🚨🚨 هماهنگی با سیستم جدید Predictive Back (بخش اول) ❗️قابلیت Predictive Back به کاربر اجازه میدهد پیش از رها کردن دست، پیشنمایشی از صفحه قبلی را ببیند. برای اینکه اپلیکیشن شما با این سیستم جدید هماهنگ شود، باید پشتیبانی از OnBackInvokedCallback…
#آموزش_اندروید 🚨🚨 هماهنگی با سیستم جدید Predictive Back (بخش اول) ❗️قابلیت Predictive Back به کاربر اجازه میدهد پیش از رها کردن دست، پیشنمایشی از صفحه قبلی را ببیند. برای اینکه اپلیکیشن شما با این سیستم جدید هماهنگ شود، باید پشتیبانی از OnBackInvokedCallback را در مانیفست فعال کنید. این کار به سیستمعامل اجازه میدهد مدیریت انیمیشنهای بازگشت را به دست بگیرد. ✅ مراحل فعالسازی: • اصلاح مانیفست: اعلام پشتیبانی رسمی به سیستمعامل. • هدفگذاری: این قابلیت از Android 13 (API 33) معرفی شده و برای پروژههایی با targetSdkVersion 33 به بالا در دسترس است. • تست در نسخههای قبل: در برخی نسخهها (بهویژه Android 13 و 14) برای مشاهده انیمیشن کامل، باید گزینه Predictive back animations را در Developer Options فعال کنید. 🛠 تغییرات در AndroidManifest.xml: <application ... android:enableOnBackInvokedCallback="true"> <activity ... /> </application> ❕ نکته: در نسخههای جدید اندروید (۱۵ به بعد)، این قابلیت به صورت گستردهتری فعال شده است، اما همچنان رفتار نهایی آن وابسته به تنظیمات اپلیکیشن و مانیفست شماست. موفق باشید🚀🚀 @KotlinMag
اگر میخوای بدونی آینده مشاغل کامپیوتری به چه سمتی میره و چطور میشه برای ۳ تا ۵ سال آینده برنامهریزی کرد…👀 ما فصل دوم دوره لایف اسپارک "جرقه زندگی" رو بهصورت رایگان و مرحلهای در آپارات و یوتیوب دانشجویار منتشر میکنیم تا قبل از تهیه این دوره، با فضای آموزش آشنا بشی😍✌️ قسمتهای منتشرشده: 👈 قسمت اول فصل دوم - آپارات: https://www.aparat.com/v/prf3b9n?refererRef=channel_page - یوتیوب: https://youtu.be/7850rBTAhqk 👈 قسمت دوم فصل دوم - آپارات: https://www.aparat.com/v/obgi0wa?refererRef=channel_page - یوتیوب: https://youtu.be/JLiGV9n0nkE این دوره حاصل ۸ سال تجربه واقعی در مسیر شغلی حوزه کامپیوتره و بهت کمک میکنه دید واضحتری نسبت به آینده کاری و انتخاب مسیرت داشته باشی💻 اگر برات مفید بود، جزئیات کامل دوره رو توی سایت دانشجویار می تونی مشاهده کنی👇 https://www.daneshjooyar.com/life-spark/
حتی تو سختترین روزها، مسیرت رو ادامه بده🌱 وبینـار رایگانِ انگیزشی و توسعه فردی مخصوص کساییه که تو بحرانها گیر کردن و نمیدونن چطور کنترل اوضاع رو دست بگیرن. توش یاد میگیری دوباره با انرژی شروع کنی، مسیرت رو ادامه بدی و حتی تو سختترین شرایط عقب نکشی.🔥 توی این وبینـار یادمیگیری: ✅توی شرایط سخت متوقف نشی؛ ✅بی حوصلگی و اهمال کاری رو کنترل کنی؛ ✅عادت های مثبت و پایدار بسازی ؛ 🎯 اگه میخوای این بار واقعاً تغییر کنی، همین حالا ثبت نام کن👇 ثبت نام وبینـار انگیزشـی ثبت نام وبینـار انگیزشـی ثبت نام وبینـار انگیزشـی @daneshjooyar
#آموزش_اندروید 🚨🚨 خداحافظی با Stringها: Type-Safe Navigation (بخش سوم) ❗️در نسخههای قدیمی ناویگیشن، مجبور بودیم آدرسها را به صورت متنی (String) بنویسیم که احتمال خطا و Crash را بالا میبرد. اما در نسخههای جدید (Navigation 2.8.0 به بالا)، گوگل روش Type-Safe را معرفی کرده است. حالا مقصدها به جای متن، با استفاده از Object و Class تعریف میشوند! ✅ چرا این روش را باید همین امروز یاد بگیرید؟ • تشخیص خطا در زمان کدنویسی: اگر پارامتری را اشتباه بفرستید، پروژه کامپایل نمیشود. • امنیت بالا: دیگر نگران غلط املایی در نام مسیرها یا جابهجایی آرگومانها نباشید. • استخراج خودکار دیتا: با استفاده از تابع toRoute به راحتی به دیتای ارسالی دسترسی دارید. 🛠 پیادهسازی گامبهگام: // ۱. ابتدا مقصدها را با کلاسهای Serializable تعریف کنید @Serializable object HomeRoute @Serializable data class ProfileRoute(val id: Int, val username: String) // ۲. استفاده در NavHost NavHost(navController, startDestination = HomeRoute) { composable<HomeRoute> { HomeScreen(onUserClick = { // ارسال دیتا به صورت یک شیء کلاس navController.navigate(ProfileRoute(id = 1, username = "KotlinMag")) }) } composable<ProfileRoute> { backStackEntry -> // دریافت دیتا به صورت Type-safe بدون نیاز به کلیدهای رشتهای val profile = backStackEntry.toRoute<ProfileRoute>() ProfileScreen(profile.id, profile.username) } } ❕ نکته: برای استفاده از این قابلیت، حتماً باید وابستگی kotlinx-serialization را در فایل build.gradle پروژه خود اضافه کرده باشید. این روش کد شما را تمیزتر و نگهداری آن را در پروژههای بزرگ بسیار سادهتر میکند. برای مطالعه بیشتر کلیک کنید (+) موفق باشید🚀🚀 @KotlinMag
#آموزش_اندروید 🚨🚨 راهنمای جامع Navigation در Jetpack Compose (بخش اول) ❗️دیگر خبری از Fragment Transactionهای پیچیده نیست! در دنیای کامپوز، ناویگیشن بر پایه یک ساختار درختی و ساده بنا شده است. برای شروع، شما به سه مفهوم اصلی نیاز دارید: NavController برای…
#آموزش_اندروید 🚨🚨 راهنمای جامع Navigation در Jetpack Compose (بخش اول) ❗️دیگر خبری از Fragment Transactionهای پیچیده نیست! در دنیای کامپوز، ناویگیشن بر پایه یک ساختار درختی و ساده بنا شده است. برای شروع، شما به سه مفهوم اصلی نیاز دارید: NavController برای جابهجایی، NavHost برای تعریف نقشه مسیرها و Composable برای معرفی مقصدها. ✅ اجزای اصلی که باید بشناسید: • NavHostController: قلب تپنده ناویگیشن که وضعیت پشته (Backstack) را مدیریت میکند. • NavHost: محفظهای که مشخص میکند با هر "آدرس"، کدام صفحه نمایش داده شود. • Composable Destinations: تعریف هر صفحه به عنوان یک مقصد در نقشه. 🛠 مثال پیادهسازی اولیه: @Composable fun AppNavigation() { val navController = rememberNavController() NavHost(navController = navController, startDestination = "home") { composable("home") { HomeScreen(onNavigateToDetails = { navController.navigate("details") }) } composable("details") { DetailsScreen() } } } ❕ نکته: همیشه navController را در بالاترین سطح (Top-level) تعریف کنید و آن را به توابع پایینی پاس ندهید؛ بلکه از کالبکها (مثل onNavigateToDetails) استفاده کنید. موفق باشید🚀🚀 @KotlinMag
#آموزش_کاتلین 🚨🚨 معرفی Sealed Interfaceها: نظم نوین در کاتلین! (بخش اول) ❗️اگر با Sealed Classها کار کرده باشید، میدانید که چقدر برای مدیریت وضعیتها عالی هستند. اما از نسخه 1.5 کاتلین، قابلیت Sealed Interface معرفی شد که انعطافپذیری شما را به سطح جدیدی…
#آموزش_کاتلین 🚨🚨 معرفی Sealed Interfaceها: نظم نوین در کاتلین! (بخش اول) ❗️اگر با Sealed Classها کار کرده باشید، میدانید که چقدر برای مدیریت وضعیتها عالی هستند. اما از نسخه 1.5 کاتلین، قابلیت Sealed Interface معرفی شد که انعطافپذیری شما را به سطح جدیدی میبرد. این رابطها به شما اجازه میدهند سلسلهمراتبهای بستهبندی شده و محدودی تعریف کنید که کامپایلر دقیقاً از تمام اعضای آن باخبر است. ✅ چرا باید از Sealed Interface استفاده کنیم؟ • ارثبری چندگانه: برخلاف کلاسها، یک کلاس میتواند چندین اینترفیس را پیادهسازی کند. • امنیت در When: کامپایلر شما را مجبور میکند تمام حالتها را پوشش دهید (Exhaustive when). • کد تمیزتر: برای تعریف وضعیتهایی که دیتای خاصی ندارند (مثل Objectها) بسیار سبکتر و بهینهتر هستند. • سلسلهمراتب محدود: هیچ کلاس خارجی نمیتواند خارج از ماژول شما این اینترفیس را پیادهسازی کند. 🛠 یک مثال ساده برای درک مفهوم: sealed interface NetworkResponse data class Success(val data: String) : NetworkResponse data class Error(val message: String) : NetworkResponse object Loading : NetworkResponse ❕ در پست بعدی بررسی میکنیم که چطور این قابلیت در پروژههای واقعی اندروید، جایگزین روشهای قدیمی میشود و چه تفاوتی با Sealed Class دارد. موفق باشید🚀🚀 @KotlinMag
#آموزش_کاتلین 🚨🚨 قدرت Extension Functions در کاتلین ❗️تا به حال شده آرزو کنید ای کاش کلاس String یا View در اندروید یک متد خاص داشت که کار شما را راحتتر میکرد؟ توابع الحاقی (Extension Functions) این قدرت را به شما میدهند که بدون تغییر در کد اصلی یک کلاس، قابلیتهای جدیدی به آن اضافه کنید. نتیجه؟ کدی تمیزتر، خواناتر و حرفهایتر! ✅ ویژگیها و مزایا: • حذف Boilerplate: کدهای تکراری را به متدهای کوتاه و کاربردی تبدیل کنید. • خوانایی فوقالعاده: کد شما شبیه به زبان محاوره میشود (مثلاً text.isValidEmail()) • بدون نیاز به ارثبری: نیازی نیست از کلاسها ارثبری کنید یا الگوهای پیچیده به کار ببرید. • دسترسی آسان: این توابع در همه جای پروژه که کلاس اصلی حضور دارد، در دسترس خواهند بود. 🛠 مثال عملی (چند تابع الحاقی پرکاربرد): // ۱. تابعی برای مخفی کردن ویو در اندروید fun View.hide() { this.visibility = View.GONE } // ۲. تابعی برای بررسی معتبر بودن ایمیل fun String.isValidEmail(): Boolean { return android.util.Patterns.EMAIL_ADDRESS.matcher(this).matches() } // نحوه استفاده در پروژه: val userEmail = "info@kotlinmag.ir" if (userEmail.isValidEmail()) { // انجام عملیات loginButton.hide() // استفاده بسیار تمیز و راحت } • با این ترفند، دیگر نیازی به نوشتن کلاسهای طولانی Utils ندارید و مستقیماً روی خود اشیاء عملیات انجام میدهید. موفق باشید🚀🚀 @KotlinMag
#آموزش_اندروید 🚨🚨 افکت چرخش سهبعدی با Modifier.graphicsLayer ❗️آیا میخواهید به اپلیکیشن خود روح بدهید و المانها را از حالت دوبعدی و تخت خارج کنید؟ با استفاده از graphicsLayer در جتپک کامپوز، میتوانید به سادگی هر کامپوننتی را در محورهای X، Y یا Z بچرخانید و افکتهای بصری نیمهسهبعدی و جذابی خلق کنید که چشم کاربر را به خود خیره کند! ✅ ویژگیها و مزایا: • عملکرد فوقالعاده: این تغییرات در لایه گرافیکی انجام میشود و باعث کندی UI نمیشود. • کنترل کامل: امکان تغییر زاویه (Rotation)، مقیاس (Scale) و حتی شفافیت (Alpha) • سادگی در اجرا: بدون نیاز به دانش ریاضی پیچیده یا Canvas • تعاملپذیری: میتوانید آن را به سادگی با انیمیشنهای Compose ترکیب کنید. 🛠 مثال عملی (یک تصویر با چرخش سهبعدی): @Composable fun ThreeDImageCard() { Box( modifier = Modifier .fillMaxSize() .padding(16.dp), contentAlignment = Alignment.Center ) { Image( painter = painterResource(id = R.drawable.kotlin_logo), contentDescription = "Logo", modifier = Modifier .size(200.dp) .graphicsLayer { // چرخش 45 درجه حول محور Y برای ایجاد عمق rotationY = 45f // اضافه کردن سایه برای جذابیت بیشتر shadowElevation = 20f shape = RoundedCornerShape(16.dp) clip = true } ) } } ❕ نکته حرفهای: با ترکیب این ویژگی و animateFloatAsState میتوانید کاری کنید که وقتی کاربر روی تصویر کلیک میکند، تصویر به زیبایی دور خود بچرخد! موفق باشید🚀🚀 @KotlinMag