0Pricing
Android Academy · درس

AnimatedVisibility والانتقالات

حرّك إظهار المحتوى وإخفاءه

AnimatedVisibility والانتقالات درس مجاني في Android Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Android Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Android Academy 4 دروس في المجموع.

تحريك الظهور

يبدو إظهار المحتوى وإخفاؤه فجأةً صادمًا. تعمل AnimatedVisibility في Compose على تحريك العنصر القابل للتركيب عند دخوله التخطيط وخروجه منه.

أحاطوا المحتوى بها وتحكموا في ظهوره باستخدام قيمة منطقية. وعندما تتغير تلك القيمة، ينفّذ Compose رسومًا متحركة للدخول أو الخروج بدلًا من الظهور الفوري.

@Composable
fun Greeting(show: Boolean) {
    AnimatedVisibility(visible = show) {
        Text("Welcome aboard!")
    }
}

انتقالات الدخول والخروج

يمكنكم اختيار الطريقة الدقيقة لدخول المحتوى وخروجه باستخدام المعاملين enter وexit. ومن اللبنات الشائعة fadeIn/fadeOut وslideIn/slideOut وexpandVertically/shrinkVertically.

اجمعوا بينها باستخدام العامل + لتشغيل عدة انتقالات في الوقت نفسه.

@Composable
fun Toast(show: Boolean) {
    AnimatedVisibility(
        visible = show,
        enter = fadeIn() + slideInVertically { it },
        exit = fadeOut() + slideOutVertically { it }
    ) {
        Text("Item added to cart")
    }
}

ضبط مواصفات الانتقال

يقبل كل انتقال للدخول أو الخروج معامل animationSpec، لذا يمكنكم التحكم في المدة والتسهيل كما تفعلون مع animate*AsState.

يتلاشى المحتوى هنا إلى الظهور خلال 300ms، وإلى الاختفاء بسرعة أكبر خلال 150ms؛ وهو نمط شائع يجعل الإغلاق سريع الاستجابة.

AnimatedVisibility(
    visible = show,
    enter = fadeIn(animationSpec = tween(300)),
    exit = fadeOut(animationSpec = tween(150))
) {
    Card { Text("Details") }
}

التوسيع والتقليص

بالنسبة إلى الأقسام التي تكشف عن مزيد من المحتوى، تحرّك expandVertically وshrinkVertically الارتفاع، فتدفعان المحتوى المحيط بسلاسة بعيدًا عن الطريق.

وهذا مناسب جدًا للوحات القابلة للطي وعناصر الأسئلة الشائعة وأقسام «عرض المزيد».

@Composable
fun Details(expanded: Boolean) {
    AnimatedVisibility(
        visible = expanded,
        enter = expandVertically() + fadeIn(),
        exit = shrinkVertically() + fadeOut()
    ) {
        Text("Extra details revealed when expanded.")
    }
}

updateTransition: حالة واحدة وقيم متعددة

عندما يجب أن تتغير عدة خصائص معًا استنادًا إلى حالة واحدة، تنسّق updateTransition هذه التغييرات. فهي تنشئ كائن Transition تتحرك عناصره الفرعية كلها بالتزامن.

حدّدوا الحالة، ثم استخدموا animateColor وanimateDp وغيرهما لكل خاصية باعتبارها دالة في تلك الحالة.

enum class BoxState { Collapsed, Expanded }

@Composable
fun MorphingBox(state: BoxState) {
    val transition = updateTransition(state, label = "box")
    val size by transition.animateDp(label = "size") {
        if (it == BoxState.Expanded) 200.dp else 100.dp
    }
    val color by transition.animateColor(label = "color") {
        if (it == BoxState.Expanded) Color.Magenta else Color.Cyan
    }
    Box(Modifier.size(size).background(color))
}

توقيت مستقل لكل خاصية في الانتقال

من المزايا المهمة لـupdateTransition إمكانية تحديد توقيت مستقل لكل خاصية. إذ يمكن لكل عنصر فرعي من عناصر animate* توفير transitionSpec الخاص به، بحيث يتحرك اللون والحجم بسرعتين مختلفتين مع بقائهما منسقين بواسطة الحالة نفسها.

val size by transition.animateDp(
    transitionSpec = { tween(durationMillis = 300) },
    label = "size"
) { if (it == BoxState.Expanded) 200.dp else 100.dp }

val corner by transition.animateDp(
    transitionSpec = { tween(durationMillis = 600) },
    label = "corner"
) { if (it == BoxState.Expanded) 0.dp else 24.dp }

AnimatedContent: تبديل المحتوى

عندما يتغير المحتوى نفسه، وليس ظهوره فقط، استخدموا AnimatedContent. فهي تحرّك الانتقال بين المحتوى القديم والجديد، مع التلاشي التدريجي افتراضيًا.

وهي مثالية لأشياء مثل العدّاد أو مؤشر الخطوات أو التبديل بين حالتي التحميل والتحميل المكتمل.

@Composable
fun Counter(count: Int) {
    AnimatedContent(
        targetState = count,
        label = "counter"
    ) { value ->
        Text("$value", style = MaterialTheme.typography.headlineLarge)
    }
}

انتقالات AnimatedContent مخصصة

خصّصوا طريقة تبديل AnimatedContent باستخدام transitionSpec. ومن الأساليب التقليدية للعدّاد تحريك القيمة الجديدة إلى الأعلى بينما تنزلق القديمة بعيدًا، مع إقران ذلك بتلاشي تدريجي.

تربط الكلمة المفتاحية using كائن SizeTransform، بحيث يتغير حجم الحاوية بسلاسة أيضًا.

AnimatedContent(
    targetState = count,
    transitionSpec = {
        (slideInVertically { it } + fadeIn()) togetherWith
            (slideOutVertically { -it } + fadeOut())
    },
    label = "counter"
) { value -> Text("$value") }

تحريك عناصر القوائم

داخل LazyColumn، يمكن للعناصر المضافة أو المحذوفة أو المنقولة أن تتحرك إلى مواضعها باستخدام Modifier.animateItem() على محتوى كل عنصر.

يوفّر ذلك إعادة ترتيب وإدراجًا سلسين من دون أي تتبع يدوي.

LazyColumn {
    items(tasks, key = { it.id }) { task ->
        Text(
            task.title,
            modifier = Modifier.animateItem()
        )
    }
}

التلاشي المتبادل للشاشات الكاملة

إن Crossfade أداة مساعدة بسيطة ومركزة تُجري تلاشيًا تدريجيًا بين حالتين، وهي مناسبة للتبديل بين الشاشات الكاملة أو حالات واجهة المستخدم الرئيسية.

مرّروا الحالة الحالية ودالة lambda للمحتوى؛ وعند تغير الحالة، تجعل Crossfade الحالة القديمة تتلاشى إلى الخارج والجديدة تتلاشى إلى الداخل.

@Composable
fun ScreenHost(screen: Screen) {
    Crossfade(targetState = screen, label = "screen") { current ->
        when (current) {
            Screen.Home -> HomeScreen()
            Screen.Profile -> ProfileScreen()
        }
    }
}

تنسيق العناصر الفرعية عند الدخول

داخل كتلة AnimatedVisibility تحصلون على AnimatedVisibilityScope، الذي يوفّر Modifier.animateEnterExit(). ويتيح ذلك للعناصر الفرعية الفردية تنفيذ رسوم متحركة خاصة بها للدخول والخروج، إضافةً إلى انتقال العنصر الأب.

فمثلًا، يمكن أن تنزلق لوحة إلى الداخل بينما يتلاشى عنوانها بعد ذلك بقليل لإضفاء تأثير طبقي.

AnimatedVisibility(visible = show, enter = slideInVertically()) {
    Column {
        Text(
            "Title",
            modifier = Modifier.animateEnterExit(
                enter = fadeIn(tween(delayMillis = 100))
            )
        )
        Text("Body")
    }
}

تحقق سريع

تريدون تحريك التبديل من الرقم 3 إلى الرقم 4، مع جعل القيمة الجديدة تتلاشى إلى الداخل وتنزلق. ما واجهة برمجة التطبيقات الأنسب؟

مراجعة: الظهور والانتقالات

أصبحتم قادرين الآن على تحريك ظهور المحتوى واختفائه وتغيّره:

  • تحرّك AnimatedVisibility الدخول والخروج باستخدام fadeIn/Out وslideIn/Out وexpand/shrink، ويمكن جمعها باستخدام +.
  • تنسّق updateTransition عدة قيم انطلاقًا من حالة واحدة، ولكل قيمة مواصفاتها الخاصة.
  • تحرّك AnimatedContent التبديل بين محتويات مختلفة؛ أما Crossfade فهو المتغير البسيط الذي يستخدم التلاشي.
  • تحرّك Modifier.animateItem() عمليات إدراج عناصر القوائم وإعادة ترتيبها.

التالي: الإيماءات والرسوم المتحركة المعتمدة على النوابض الفيزيائية لحركة طبيعية وتفاعلية.

الأسئلة الشائعة

هل درس «AnimatedVisibility والانتقالات» مجاني؟

نعم — نص درس «AnimatedVisibility والانتقالات» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Android Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Android Academy 4 دروس في المجموع.

ماذا ستتعلم في «AnimatedVisibility والانتقالات»؟

حرّك إظهار المحتوى وإخفاءه تتمرن على Android Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Android Academy؟

لا تُشترط خبرة سابقة. Android Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.

كم من الوقت يستغرق درس «AnimatedVisibility والانتقالات»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Android Academy هذا؟

نعم. كل درس في Android Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. لماذا تهم الرسوم المتحركة
  2. أساسيات animate*AsState
  3. AnimatedVisibility والانتقالات
  4. حركات الإيماءات والنوابض
← العودة إلى Android Academy