آموزش انیمیشن در کامپوز و برنامه نویسی اندروید

آموزش انیمیشن در کامپوز و برنامه نویسی اندروید
در این پست می‌خوانید:

همیشه انیمیشن های یکی از اصلی ترین مولفه های توی برنامه نویسیه که باعث میشه اپلیکیشن های ررون تر و جذابتری داشته باشیم.

انیمیشن‌ ها باعث می‌شن رابط کاربری یه حس زنده‌ بودن داشته باشه و کار با اپ برامون لذت‌بخش‌تر بشه.

توی این مطلب میخوایم مطلب انیمیشن ها توی جت پک کامپوز (Animations in Jetpack Compose) رو به طور کامل بررسی و آموزش بدیم.

انیمیشن ها در کامپوز

جت‌پک کامپوز واقعاً نحوه‌ی ساخت رابط کاربری توی اندروید رو متحول کرده؛ چون کل ماجرا رو دکلراتیو، شهودی و سریع‌تر کرده. یکی از ویژگی‌های خیلی جذابش پشتیبانی داخلی از انیمیشنه. animation ها باعث می‌شن رابط کاربری یه حس زنده‌ بودن داشته باشه و کار با اپ برامون لذت‌بخش‌تر بشه.

Compose کلی API ساده و قدرتمند برای ساخت animation های نرم و روون داره که واقعاً تجربه کاربری رو بهتر می‌کنه.

توی این مقاله، می‌خوایم یه نگاه کلی به animation ها توی Compose بندازیم و ببینیم چجوری می‌تونیم ازشون برای ساخت یه رابط کاربری جذاب‌تر استفاده کنیم.

چرا اصلاً از انیمیشن استفاده کنیم؟

چند تا دلیل خوب داره:

  • به کاربر بازخورد بصری می‌ده (مثلاً وقتی یه چیزی رو لمس می‌کنه).
  • کمک می‌کنه توی جابه‌جایی بین صفحات یا حالت‌های مختلف، یه حس روون بودن داشته باشیم.
  • حس تعامل‌پذیری رو بهتر می‌کنه.

و خوبی Compose اینه که چون همه چیزش دکلراتیوئه، پیاده‌سازی انیمیشن‌ هاش هم آسونه. یعنی شما فقط می‌گی فلان چیز از حالت A بره به حالت B، خودش بقیه‌ش رو انجام می‌ده.

انواع animation توی Jetpack Compose

چند مدل animation مختلف داریم:

۱. animation های مبتنی بر حالت (State-based)

برای وقتیه که یه کامپوزابل بین دو یا چند حالت تغییر می‌کنه.

۲. animation های گذار (Transition)

وقتی چند ویژگی با هم باید توی یه روند تغییر کنن.

۳. animation های صریح (Explicit)

کنترل دقیق‌تر روی ویژگی‌هایی مثل اندازه، موقعیت یا رنگ رو بهت می‌دن.

۴. animation های بر اساس ژست (Gesture-based)

واکنش به کارهایی مثل درگ، سوایپ یا کلیک با انیمیشن.

بیا با مثال، هر کدومشون رو دقیق‌تر ببینیم.

۱. animation بر اساس State

توی این مدل، کامپوزابل خودش می‌فهمه که باید از یه حالت به حالت دیگه بره و بینشون animation اجرا کنه.

تابع معروفش animate*AsState هست (مثلاً animateColorAsState یا animateDpAsState).

مثال: انیمیشن رنگ

@Composable

fun ColorAnimationExample() {

    var isRed by remember { mutableStateOf(true) }

   

    val backgroundColor by animateColorAsState(

        targetValue = if (isRed) Color.Red else Color.Blue,

        animationSpec = tween(durationMillis = 1000)

    )




    Box(

        modifier = Modifier

            .size(100.dp)

            .background(backgroundColor)

            .clickable { isRed = !isRed }

    )

}

اینجا چی شده؟

  • وقتی روی باکس کلیک می‌کنی، رنگش بین قرمز و آبی جابه‌جا می‌شه.
  • animateColorAsState یه انیمیشن روون بین دو رنگ ایجاد می‌کنه.

۲. animation Transition

این animation ها برای وقتیه که چند تا ویژگی با هم تغییر می‌کنن. مثل نمایش/پنهان کردن یه ویو با افکت.

مثال: انیمیشن Visibility

@Composable

fun VisibilityAnimationExample() {

    var isVisible by remember { mutableStateOf(true) }

   

    Column(horizontalAlignment = Alignment.CenterHorizontally) {

        Button(onClick = { isVisible = !isVisible }) {

            Text(text = if (isVisible) "Hide Box" else "Show Box")

        }

       

        AnimatedVisibility(visible = isVisible) {

            Box(

                modifier = Modifier

                    .size(100.dp)

                    .background(Color.Green)

            )

        }

    }

}
  • با کلیک روی دکمه، باکس سبز ظاهر یا ناپدید می‌شه.
  • اینکار با یه افکت fade-in/fade-out انجام می‌شه.

۳. animation های Explicit

اگه بخوای دقیق کنترل کنی که اندازه، چرخش یا موقعیت یه ویو چطور و کی تغییر کنه، این مدل به دردت می‌خوره.

مثال: انیمیشن سایز و چرخش

@Composable

fun SizeAndRotationAnimationExample() {

    var isBig by remember { mutableStateOf(false) }

   

    val size by animateDpAsState(targetValue = if (isBig) 200.dp else 100.dp)

    val rotation by animateFloatAsState(targetValue = if (isBig) 360f else 0f)

   

    Box(

        modifier = Modifier

            .size(size)

            .rotate(rotation)

            .background(Color.Magenta)

            .clickable { isBig = !isBig }

    )

}
  • وقتی روی باکس کلیک می‌کنی، هم بزرگ می‌شه هم می‌چرخه.
  • خیلی جذابه وقتی می‌خوای یه افکت وایرال یا واکنشی به تعامل کاربر نشون بدی.

۴. انیمیشن بر اساس Gesture

برای واکنش نشون دادن به حرکات انگشت کاربر (سوایپ، درگ و …) از اینا استفاده می‌شه.

مثال: Swipe to Dismiss

@OptIn(ExperimentalMaterialApi::class)

@Composable

fun SwipeToDismissExample() {

    val dismissState = rememberDismissState()

   

    SwipeToDismiss(

        state = dismissState,

        background = {

            Box(

                modifier = Modifier

                    .fillMaxSize()

                    .background(Color.Red)

            )

        },

        dismissContent = {

            Box(

                modifier = Modifier

                    .fillMaxSize()

                    .background(Color.LightGray)

            ) {

                Text("Swipe me away!", modifier = Modifier.align(Alignment.Center))

            }

        }

    )

}
  • اینجا کاربر می‌تونه اون باکس خاکستری رو با سوایپ حذف کنه.
  • خیلی کاربردیه مثلاً برای بستن نوتیفیکیشن یا حذف آیتم لیست.

انیمیشن‌ های پیشرفته با Animatable

اگه بخوای یه مقدار دلخواه رو انیمیت کنی (نه فقط رنگ یا سایز)، می‌تونی از Animatable استفاده کنی.

مثال: animation مقدار دلخواه

@Composable

fun CustomAnimationExample() {

    val animatable = remember { Animatable(0f) }

   

    LaunchedEffect(Unit) {

        animatable.animateTo(

            targetValue = 1f,

            animationSpec = tween(durationMillis = 2000)

        )

    }

   

    Box(

        modifier = Modifier

            .size(100.dp)

            .graphicsLayer(scaleX = animatable.value, scaleY = animatable.value)

            .background(Color.Cyan)

    )

}
  • اینجا یه مقدار float رو انیمیت کردیم و باهاش اندازه‌ی باکس رو بزرگ کردیم.
  • Animatable قدرت زیادی می‌ده برای انیمیشن‌ های سفارشی و خاص.

اگه درمورد Modifier ها در کامپوز اطلاعاتی نداری پیشنهاد میکنم این مطلب رو بخونی : مدیفایر Modifier‌ ها در جت پک کامپوز 

 چند نوع animationدر Compose داریم؟

در Jetpack Compose، animationها به صورت کلی به این دسته‌ها تقسیم می‌شن:

نوع انیمیشن توضیح
State-based animations ساده‌ترین حالت؛ برای انیمیت کردن تغییر یه مقدار بین دو وضعیت (مثلاً animateDpAsState, animateColorAsState)
Transition animations وقتی چند مقدار مختلف با هم تغییر کنن (مثلاً رنگ، اندازه، شفافیت) با استفاده از updateTransition
Visibility animations نمایش/پنهان‌سازی عناصر با انیمیشن (مثل AnimatedVisibility)
Gesture-based animations وقتی animation وابسته به حرکت انگشت کاربره (مثلاً swipe, drag)؛ مثل Modifier.draggable, swipeable, SwipeToDismiss
Explicit / Low-level animations برای کنترل دقیق و سفارشی‌سازی کامل، با Animatable, AnimationState, TargetBasedAnimation و animate* APIs کار می‌کنیم.

 

  آیا این مقاله برای حرفه‌ای شدن در انیمیشن‌ ها کافی‌ست؟

🟥 پاسخ: نه، کامل نیست.

این مقاله بیشتر مقدمه‌ای ساده و دم‌دستی برای شروع کار با animationهاست. مثلاً فقط نشون می‌ده چطور با animateColorAsState رنگ رو تغییر بدی، اما توضیح نمی‌ده:

  • چرا این تابع اینجوری پیاده‌سازی شده؟
  • اگه بخوای رنگ رو با Animatable بسازی چی؟
  • اگه بخوای توی یه gesture خاص یا روی چند ویژگی همزمان animation داشته باشی چیکار باید بکنی؟

اگه هدفت استادیه، باید بری سراغ لایه‌های پایین‌تر:
Animatable, Transition, AnimationSpec, AnimationScope, و خود animateValueAsState.

 آیا یه فرمول یا قاعده کلی برای ساخت animation داریم؟

بله، یه ذهنیت (mental model) می‌تونیم بسازیم که توی تمام animation ها صدق می‌کنه. اگه اینو بفهمی، دیگه فقط اسم تابع عوض می‌شه، نه اصل قضیه:

🧠 مدل ذهنی انیمیشن در Compose

در Jetpack Compose، هر animation از ۳ بخش اصلی تشکیل شده:

(1) مقدار هدف (targetValue)

+ (2) زمان‌بندی و مشخصات (AnimationSpec)

+ (3) وسیله اجرای انیمیشن (animateX / Animatable / Transition / Modifier)

=> نتیجه: مقدار متحرک‌شونده (State)

مثلاً:

val animatedSize by animateDpAsState(

    targetValue = 100.dp,             // مقدار هدف

    animationSpec = tween(500),       // نوع animation و سرعتش

)

همین منطق توی Animatable هم هست، فقط تو حالت لوول پایین‌تر:

val anim = remember { Animatable(0f) }




LaunchedEffect(true) {

    anim.animateTo(1f, animationSpec = tween(1000))

}

 چجوری اصول کلی انیمیشن رو یاد بگیریم؟

برای حرفه‌ای شدن باید این مسیر رو بری:

مرحله ۱: تسلط روی animate*AsState

  • animateDpAsState, animateFloatAsState, animateColorAsState, …
  • مفهوم State, remember, targetValue و AnimationSpec

مرحله ۲: کار با updateTransition

  • وقتی چند تا مقدار با هم انیمیت می‌شن
  • ساختن حالت‌های پیچیده مثل کارت که وقتی باز می‌شه هم بزرگ بشه، هم رنگش تغییر کنه

مرحله ۳: استفاده از Animatable

  • کنترل کامل روی زمان و رفتار animation
  • قابلیت pause/resume/cancel
  • انیمیت کردن مقادیری که توی animateXAsState وجود ندارن

مرحله ۴: animationهای Gesture-based

  • استفاده از Modifier.draggable, Modifier.swipeable, rememberDraggableState
  • ترکیب gesture + animatable → انیمیشن طبیعی با انگشت کاربر

مرحله ۵: درک مفاهیم ریاضی پشت animation

  • تفاوت بین tween, spring, keyframes, snap
  • مفهوم Easing (مثل easeInOut, linear, FastOutSlowIn)
  • منحنی‌های زمانی (timing curves)

️ پیشنهاد نهایی: یه الگوی ذهنی همه‌کاره

می‌خوای انیمیشن بسازی؟ اول از خودت اینا رو بپرس:

  1. چی داره تغییر می‌کنه؟ (اندازه؟ رنگ؟ موقعیت؟ چرخش؟ شفافیت؟)
  2. چرا تغییر می‌کنه؟ (کلیک؟ gesture؟ رفتن به یه صفحه‌ی دیگه؟)
  3. چجوری باید تغییر کنه؟ (نرمه؟ فنریه؟ لحظه‌ایه؟ چند تا ویژگی با هم؟)
  4. کِی تموم شه؟ (دقیقه؟ وابسته به gesture؟ وابسته به event خاص؟)

جواب این سؤالا رو که بدونی، خودت می‌تونی تصمیم بگیری از کدوم ابزار استفاده کنی:

  • animateXAsState (ساده)
  • updateTransition (هماهنگ)
  • Animatable (پیشرفته)
  • Modifier.draggable/swipeable (gesture)

جمع‌بندی

Jetpack Compose کار انیمیشن ساختن رو خیلی راحت کرده. دیگه لازم نیست کلی کدای پیچیده بنویسی. چه بخوای رنگ و اندازه رو عوض کنی، چه بخوای به ژست کاربر واکنش نشون بدی، همه‌ش راحت و تمیز با چند تا API ساده انجام می‌شه.

اگه مفاهیم پایه‌ی animationهای مختلف رو بفهمی، خیلی راحت می‌تونی رابط کاربری زنده و تعاملی بسازی. با Compose واقعاً animationساختن مثل آب خوردنه!

✌️ مرسی که خوندی 🙌

دیدگاه‌ها ۰
ارسال دیدگاه جدید