কম্পোজে অ্যানিমেশনের জন্য দ্রুত নির্দেশিকা

রচনার অনেকগুলি অন্তর্নির্মিত অ্যানিমেশন প্রক্রিয়া রয়েছে এবং কোনটি বেছে নেবেন তা জানা অপ্রতিরোধ্য হতে পারে৷ নীচে সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রের একটি তালিকা রয়েছে। আপনার কাছে উপলব্ধ বিভিন্ন API বিকল্পগুলির সম্পূর্ণ সেট সম্পর্কে আরও বিশদ তথ্যের জন্য, সম্পূর্ণ রচনা অ্যানিমেশন ডকুমেন্টেশন পড়ুন।

অ্যানিমেট সাধারণ কম্পোজেবল বৈশিষ্ট্য

কম্পোজ সুবিধাজনক API প্রদান করে যা আপনাকে অনেক সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রে সমাধান করতে দেয়। এই বিভাগটি দেখায় কিভাবে আপনি একটি কম্পোজেবলের সাধারণ বৈশিষ্ট্যগুলিকে অ্যানিমেট করতে পারেন।

অ্যানিমেট উপস্থিত / অদৃশ্য হয়ে যাওয়া

সবুজ কম্পোজেবল দেখাচ্ছে এবং নিজেকে লুকিয়ে
চিত্র 1. একটি কলামে একটি আইটেমের উপস্থিতি এবং অদৃশ্য হওয়া অ্যানিমেটিং

কম্পোজেবল লুকাতে বা দেখানোর জন্য AnimatedVisibility ব্যবহার করুন। AnimatedVisibility ভিতরে থাকা শিশুরা তাদের নিজস্ব প্রবেশ বা প্রস্থান পরিবর্তনের জন্য Modifier.animateEnterExit() ব্যবহার করতে পারে।

var visible by remember {
    mutableStateOf(true)
}
// Animated visibility will eventually remove the item from the composition once the animation has finished.
AnimatedVisibility(visible) {
    // your composable here
    // ...
}

AnimatedVisibility প্রবেশ এবং প্রস্থান পরামিতিগুলি আপনাকে একটি কম্পোজেবল যখন এটি প্রদর্শিত এবং অদৃশ্য হয়ে যায় তখন কীভাবে আচরণ করে তা কনফিগার করার অনুমতি দেয়। আরও তথ্যের জন্য সম্পূর্ণ ডকুমেন্টেশন পড়ুন.

একটি কম্পোজেবলের দৃশ্যমানতা অ্যানিমেট করার জন্য আরেকটি বিকল্প হল animateFloatAsState ব্যবহার করে সময়ের সাথে আলফাকে অ্যানিমেট করা:

var visible by remember {
    mutableStateOf(true)
}
val animatedAlpha by animateFloatAsState(
    targetValue = if (visible) 1.0f else 0f,
    label = "alpha"
)
Box(
    modifier = Modifier
        .size(200.dp)
        .graphicsLayer {
            alpha = animatedAlpha
        }
        .clip(RoundedCornerShape(8.dp))
        .background(colorGreen)
        .align(Alignment.TopCenter)
) {
}

যাইহোক, আলফা পরিবর্তনের সাথে সতর্কতা আসে যে কম্পোজেবলটি কম্পোজিশনের মধ্যেই থেকে যায় এবং এটির মধ্যে যে স্থানটি স্থাপন করা হয়েছে সেটি দখল করতে থাকে। এর ফলে স্ক্রীন রিডার এবং অন্যান্য অ্যাক্সেসিবিলিটি মেকানিজম এখনও স্ক্রিনে আইটেমটিকে বিবেচনা করতে পারে। অন্যদিকে, AnimatedVisibility শেষ পর্যন্ত কম্পোজিশন থেকে আইটেমটিকে সরিয়ে দেয়।

একটি কম্পোজেবল এর আলফা অ্যানিমেটিং
চিত্র 2. একটি কম্পোজেবলের আলফা অ্যানিমেটিং

অ্যানিমেট পটভূমির রঙ

অ্যানিমেশন হিসাবে সময়ের সাথে সাথে পটভূমির রঙ পরিবর্তিত হওয়ার সাথে কম্পোজযোগ্য, যেখানে রঙগুলি একে অপরের মধ্যে বিবর্ণ হয়ে যাচ্ছে।
চিত্র 3. কম্পোজেবলের অ্যানিমেটিং ব্যাকগ্রাউন্ড কালার

val animatedColor by animateColorAsState(
    if (animateBackgroundColor) colorGreen else colorBlue,
    label = "color"
)
Column(
    modifier = Modifier.drawBehind {
        drawRect(animatedColor)
    }
) {
    // your composable here
}

এই বিকল্পটি Modifier.background() ব্যবহার করার চেয়ে বেশি কার্যকরী। Modifier.background() একটি এক-শট রঙের সেটিং এর জন্য গ্রহণযোগ্য, কিন্তু সময়ের সাথে সাথে একটি রঙ অ্যানিমেট করার সময়, এটি প্রয়োজনের চেয়ে বেশি পুনর্গঠনের কারণ হতে পারে।

পটভূমির রঙ অসীমভাবে অ্যানিমেট করার জন্য, একটি অ্যানিমেশন বিভাগের পুনরাবৃত্তি দেখুন।

একটি কম্পোজেবল আকার অ্যানিমেট

সবুজ সংমিশ্রণযোগ্য অ্যানিমেটিং এর আকার মসৃণভাবে পরিবর্তন করে।
চিত্র 4. কম্পোজযোগ্য মসৃণভাবে একটি ছোট এবং একটি বড় আকারের মধ্যে অ্যানিমেটিং

রচনা আপনাকে কয়েকটি ভিন্ন উপায়ে কম্পোজেবলের আকার অ্যানিমেট করতে দেয়। কম্পোজযোগ্য আকার পরিবর্তনের মধ্যে অ্যানিমেশনের জন্য animateContentSize() ব্যবহার করুন।

উদাহরণস্বরূপ, যদি আপনার একটি বাক্স থাকে যাতে পাঠ্য থাকে যা এক থেকে একাধিক লাইনে প্রসারিত হতে পারে আপনি একটি মসৃণ রূপান্তর অর্জন করতে Modifier.animateContentSize() ব্যবহার করতে পারেন:

var expanded by remember { mutableStateOf(false) }
Box(
    modifier = Modifier
        .background(colorBlue)
        .animateContentSize()
        .height(if (expanded) 400.dp else 200.dp)
        .fillMaxWidth()
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            expanded = !expanded
        }

) {
}

আকার পরিবর্তন কিভাবে ঘটতে হবে তা বর্ণনা করতে আপনি একটি SizeTransform সহ AnimatedContent ব্যবহার করতে পারেন।

কম্পোজেবলের অ্যানিমেট অবস্থান

সবুজ কম্পোজযোগ্য মসৃণভাবে নিচে এবং ডানদিকে অ্যানিমেটিং
চিত্র 5. একটি অফসেট দ্বারা কম্পোজেবল চলন্ত

কম্পোজেবলের অবস্থান অ্যানিমেট করতে, animateIntOffsetAsState() এর সাথে মিলিত Modifier.offset{ } ব্যবহার করুন।

var moved by remember { mutableStateOf(false) }
val pxToMove = with(LocalDensity.current) {
    100.dp.toPx().roundToInt()
}
val offset by animateIntOffsetAsState(
    targetValue = if (moved) {
        IntOffset(pxToMove, pxToMove)
    } else {
        IntOffset.Zero
    },
    label = "offset"
)

Box(
    modifier = Modifier
        .offset {
            offset
        }
        .background(colorBlue)
        .size(100.dp)
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            moved = !moved
        }
)

আপনি যদি নিশ্চিত করতে চান যে অবস্থান বা আকার অ্যানিমেট করার সময় কম্পোজেবলগুলি অন্য কম্পোজেবলের উপরে বা নীচে আঁকা না হয়, Modifier.layout{ } । এই সংশোধকটি পিতামাতার কাছে আকার এবং অবস্থানের পরিবর্তনগুলি প্রচার করে, যা পরে অন্যান্য শিশুদের প্রভাবিত করে।

উদাহরণস্বরূপ, যদি আপনি একটি Column মধ্যে একটি Box সরান এবং Box নড়াচড়া করার সময় অন্যান্য শিশুদের সরাতে হয়, তাহলে নিম্নরূপ Modifier.layout{ } এর সাথে অফসেট তথ্য অন্তর্ভুক্ত করুন:

var toggled by remember {
    mutableStateOf(false)
}
val interactionSource = remember {
    MutableInteractionSource()
}
Column(
    modifier = Modifier
        .padding(16.dp)
        .fillMaxSize()
        .clickable(indication = null, interactionSource = interactionSource) {
            toggled = !toggled
        }
) {
    val offsetTarget = if (toggled) {
        IntOffset(150, 150)
    } else {
        IntOffset.Zero
    }
    val offset = animateIntOffsetAsState(
        targetValue = offsetTarget, label = "offset"
    )
    Box(
        modifier = Modifier
            .size(100.dp)
            .background(colorBlue)
    )
    Box(
        modifier = Modifier
            .layout { measurable, constraints ->
                val offsetValue = if (isLookingAhead) offsetTarget else offset.value
                val placeable = measurable.measure(constraints)
                layout(placeable.width + offsetValue.x, placeable.height + offsetValue.y) {
                    placeable.placeRelative(offsetValue)
                }
            }
            .size(100.dp)
            .background(colorGreen)
    )
    Box(
        modifier = Modifier
            .size(100.dp)
            .background(colorBlue)
    )
}

২য় বক্সের সাথে ২য় বক্স তার X,Y অবস্থানকে অ্যানিমেট করে, তৃতীয় বক্সটিও Y পরিমাণে নিজেকে সরিয়ে সাড়া দেয়।
চিত্র 6. Modifier.layout{ }

একটি রচনাযোগ্য প্যাডিং অ্যানিমেট

সবুজ সংমিশ্রণযোগ্য প্যাডিং অ্যানিমেটেড সহ ক্লিকে ছোট এবং বড় হচ্ছে
চিত্র 7. এর প্যাডিং অ্যানিমেটিং সহ কম্পোজযোগ্য

একটি কম্পোজেবলের প্যাডিং অ্যানিমেট করতে, Modifier.padding() এর সাথে মিলিত animateDpAsState ব্যবহার করুন :

var toggled by remember {
    mutableStateOf(false)
}
val animatedPadding by animateDpAsState(
    if (toggled) {
        0.dp
    } else {
        20.dp
    },
    label = "padding"
)
Box(
    modifier = Modifier
        .aspectRatio(1f)
        .fillMaxSize()
        .padding(animatedPadding)
        .background(Color(0xff53D9A1))
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            toggled = !toggled
        }
)

একটি কম্পোজেবল এর অ্যানিমেট উচ্চতা

চিত্র 8. ক্লিকে কম্পোজেবলের উচ্চতা অ্যানিমেটিং

একটি কম্পোজেবলের উচ্চতা অ্যানিমেট করতে, Modifier.graphicsLayer{ } এর সাথে মিলিত animateDpAsState ব্যবহার করুন{ }। একবার-বন্ধ উচ্চতা পরিবর্তনের জন্য, Modifier.shadow() ব্যবহার করুন। আপনি যদি ছায়াটিকে অ্যানিমেটিং করেন, Modifier.graphicsLayer{ } modifier ব্যবহার করা হল আরও কার্যকরী বিকল্প।

val mutableInteractionSource = remember {
    MutableInteractionSource()
}
val pressed = mutableInteractionSource.collectIsPressedAsState()
val elevation = animateDpAsState(
    targetValue = if (pressed.value) {
        32.dp
    } else {
        8.dp
    },
    label = "elevation"
)
Box(
    modifier = Modifier
        .size(100.dp)
        .align(Alignment.Center)
        .graphicsLayer {
            this.shadowElevation = elevation.value.toPx()
        }
        .clickable(interactionSource = mutableInteractionSource, indication = null) {
        }
        .background(colorGreen)
) {
}

বিকল্পভাবে, Card কম্পোজেবল ব্যবহার করুন, এবং উচ্চতা সম্পত্তি প্রতি রাজ্যে বিভিন্ন মান সেট করুন।

অ্যানিমেট টেক্সট স্কেল, অনুবাদ বা ঘূর্ণন

টেক্সট কম্পোজেবল উক্তি
চিত্র 9. দুটি আকারের মধ্যে মসৃণভাবে টেক্সট অ্যানিমেটিং

স্কেল, অনুবাদ বা পাঠ্যের ঘূর্ণন অ্যানিমেটিং করার সময়, TextStyletextMotion প্যারামিটার সেট করুন। TextMotion.Animated । এটি পাঠ্য অ্যানিমেশনগুলির মধ্যে মসৃণ রূপান্তর নিশ্চিত করে। টেক্সট অনুবাদ করতে, ঘোরাতে বা স্কেল করতে Modifier.graphicsLayer{ } ব্যবহার করুন।

val infiniteTransition = rememberInfiniteTransition(label = "infinite transition")
val scale by infiniteTransition.animateFloat(
    initialValue = 1f,
    targetValue = 8f,
    animationSpec = infiniteRepeatable(tween(1000), RepeatMode.Reverse),
    label = "scale"
)
Box(modifier = Modifier.fillMaxSize()) {
    Text(
        text = "Hello",
        modifier = Modifier
            .graphicsLayer {
                scaleX = scale
                scaleY = scale
                transformOrigin = TransformOrigin.Center
            }
            .align(Alignment.Center),
        // Text composable does not take TextMotion as a parameter.
        // Provide it via style argument but make sure that we are copying from current theme
        style = LocalTextStyle.current.copy(textMotion = TextMotion.Animated)
    )
}

অ্যানিমেট টেক্সট রঙ

শব্দ
চিত্র 10. অ্যানিমেটিং টেক্সট রঙ দেখানোর উদাহরণ

টেক্সট কালার অ্যানিমেট করতে, BasicText কম্পোজেবলে color ল্যাম্বডা ব্যবহার করুন:

val infiniteTransition = rememberInfiniteTransition(label = "infinite transition")
val animatedColor by infiniteTransition.animateColor(
    initialValue = Color(0xFF60DDAD),
    targetValue = Color(0xFF4285F4),
    animationSpec = infiniteRepeatable(tween(1000), RepeatMode.Reverse),
    label = "color"
)

BasicText(
    text = "Hello Compose",
    color = {
        animatedColor
    },
    // ...
)

বিভিন্ন ধরনের সামগ্রীর মধ্যে স্যুইচ করুন

সবুজ পর্দা বলছে
চিত্র 11. অ্যানিমেটেড কনটেন্ট ব্যবহার করে বিভিন্ন কম্পোজেবলের মধ্যে পরিবর্তন অ্যানিমেট করা (ধীরগতির)

বিভিন্ন কম্পোজেবলের মধ্যে অ্যানিমেট করতে AnimatedContent ব্যবহার করুন, আপনি যদি কম্পোজেবলের মধ্যে একটি স্ট্যান্ডার্ড ফেইড চান, Crossfade ব্যবহার করুন।

var state by remember {
    mutableStateOf(UiState.Loading)
}
AnimatedContent(
    state,
    transitionSpec = {
        fadeIn(
            animationSpec = tween(3000)
        ) togetherWith fadeOut(animationSpec = tween(3000))
    },
    modifier = Modifier.clickable(
        interactionSource = remember { MutableInteractionSource() },
        indication = null
    ) {
        state = when (state) {
            UiState.Loading -> UiState.Loaded
            UiState.Loaded -> UiState.Error
            UiState.Error -> UiState.Loading
        }
    },
    label = "Animated Content"
) { targetState ->
    when (targetState) {
        UiState.Loading -> {
            LoadingScreen()
        }
        UiState.Loaded -> {
            LoadedScreen()
        }
        UiState.Error -> {
            ErrorScreen()
        }
    }
}

AnimatedContent বিভিন্ন ধরণের এন্টার এবং এক্সিট ট্রানজিশন দেখানোর জন্য কাস্টমাইজ করা যেতে পারে। আরও তথ্যের জন্য, AnimatedContent এ ডকুমেন্টেশন পড়ুন বা AnimatedContent এ এই ব্লগ পোস্ট পড়ুন।

বিভিন্ন গন্তব্যে নেভিগেট করার সময় অ্যানিমেট করুন

দুটি কম্পোজেবল, একটি সবুজ বলছে ল্যান্ডিং এবং একটি নীল বলছে ডিটেইল, ল্যান্ডিং কম্পোজেবলের উপর বিশদ কম্পোজযোগ্য স্লাইড করে অ্যানিমেটিং।
চিত্র 12. নেভিগেশন-কম্পোজ ব্যবহার করে কম্পোজেবলের মধ্যে অ্যানিমেটিং

নেভিগেশন-কম্পোজ আর্টিফ্যাক্ট ব্যবহার করার সময় কম্পোজেবলের মধ্যে ট্রানজিশন অ্যানিমেট করতে, একটি কম্পোজেবলের enterTransition এবং exitTransition নির্দিষ্ট করুন। আপনি শীর্ষ স্তরের NavHost এ সমস্ত গন্তব্যের জন্য ব্যবহার করার জন্য ডিফল্ট অ্যানিমেশন সেট করতে পারেন:

val navController = rememberNavController()
NavHost(
    navController = navController, startDestination = "landing",
    enterTransition = { EnterTransition.None },
    exitTransition = { ExitTransition.None }
) {
    composable("landing") {
        ScreenLanding(
            // ...
        )
    }
    composable(
        "detail/{photoUrl}",
        arguments = listOf(navArgument("photoUrl") { type = NavType.StringType }),
        enterTransition = {
            fadeIn(
                animationSpec = tween(
                    300, easing = LinearEasing
                )
            ) + slideIntoContainer(
                animationSpec = tween(300, easing = EaseIn),
                towards = AnimatedContentTransitionScope.SlideDirection.Start
            )
        },
        exitTransition = {
            fadeOut(
                animationSpec = tween(
                    300, easing = LinearEasing
                )
            ) + slideOutOfContainer(
                animationSpec = tween(300, easing = EaseOut),
                towards = AnimatedContentTransitionScope.SlideDirection.End
            )
        }
    ) { backStackEntry ->
        ScreenDetails(
            // ...
        )
    }
}

বিভিন্ন ধরণের এন্টার এবং এক্সিট ট্রানজিশন রয়েছে যা ইনকামিং এবং আউটগোয়িং কন্টেন্টে বিভিন্ন প্রভাব প্রয়োগ করে, আরও তথ্যের জন্য ডকুমেন্টেশন দেখুন।

একটি অ্যানিমেশন পুনরাবৃত্তি করুন

একটি সবুজ পটভূমি যা একটি নীল পটভূমিতে রূপান্তরিত হয়, অসীমভাবে দুটি রঙের মধ্যে অ্যানিমেট করে।
চিত্র 13. পটভূমির রঙ দুটি মানের মধ্যে অ্যানিমেটিং, অসীমভাবে

আপনার অ্যানিমেশন ক্রমাগত পুনরাবৃত্তি করতে একটি infiniteRepeatable animationSpec এর সাথে rememberInfiniteTransition ব্যবহার করুন। RepeatModes কীভাবে সামনে পিছনে যেতে হবে তা নির্দিষ্ট করতে পরিবর্তন করুন।

নির্দিষ্ট সংখ্যক বার পুনরাবৃত্তি করতে finiteRepeatable ব্যবহার করুন।

val infiniteTransition = rememberInfiniteTransition(label = "infinite")
val color by infiniteTransition.animateColor(
    initialValue = Color.Green,
    targetValue = Color.Blue,
    animationSpec = infiniteRepeatable(
        animation = tween(1000, easing = LinearEasing),
        repeatMode = RepeatMode.Reverse
    ),
    label = "color"
)
Column(
    modifier = Modifier.drawBehind {
        drawRect(color)
    }
) {
    // your composable here
}

একটি কম্পোজেবল চালু করার সময় একটি অ্যানিমেশন শুরু করুন

LaunchedEffect চলে যখন একটি কম্পোজেবল কম্পোজিশনে প্রবেশ করে। এটি একটি কম্পোজেবল চালু করার সময় একটি অ্যানিমেশন শুরু করে, আপনি অ্যানিমেশনের অবস্থা পরিবর্তন করতে এটি ব্যবহার করতে পারেন। লঞ্চে অ্যানিমেশন শুরু করতে animateTo পদ্ধতির সাথে Animatable ব্যবহার করুন:

val alphaAnimation = remember {
    Animatable(0f)
}
LaunchedEffect(Unit) {
    alphaAnimation.animateTo(1f)
}
Box(
    modifier = Modifier.graphicsLayer {
        alpha = alphaAnimation.value
    }
)

ক্রমিক অ্যানিমেশন তৈরি করুন

সবুজ তীর সহ চারটি চেনাশোনা প্রতিটির মধ্যে অ্যানিমেট করছে, একের পর এক অ্যানিমেট করছে।
চিত্র 14. একটি অনুক্রমিক অ্যানিমেশন কীভাবে একের পর এক অগ্রসর হয় তা নির্দেশ করে চিত্র।

অনুক্রমিক বা সমসাময়িক অ্যানিমেশনগুলি সম্পাদন করতে Animatable কোরোটিন API ব্যবহার করুন। Animatable একের পর এক animateTo কল করার ফলে প্রতিটি অ্যানিমেশন এগিয়ে যাওয়ার আগে পূর্ববর্তী অ্যানিমেশনগুলি শেষ হওয়ার জন্য অপেক্ষা করে। কারণ এটি একটি সাসপেন্ড ফাংশন।

val alphaAnimation = remember { Animatable(0f) }
val yAnimation = remember { Animatable(0f) }

LaunchedEffect("animationKey") {
    alphaAnimation.animateTo(1f)
    yAnimation.animateTo(100f)
    yAnimation.animateTo(500f, animationSpec = tween(100))
}

সমসাময়িক অ্যানিমেশন তৈরি করুন

সবুজ তীর সহ তিনটি চেনাশোনা প্রতিটিতে অ্যানিমেট করছে, একই সময়ে সবগুলিকে অ্যানিমেট করছে৷
চিত্র 15. ডায়াগ্রামটি নির্দেশ করে কিভাবে সমসাময়িক অ্যানিমেশনগুলি একই সময়ে অগ্রসর হয়।

সমসাময়িক অ্যানিমেশনগুলি অর্জন করতে coroutine APIs ( Animatable#animateTo() বা animate ), বা Transition API ব্যবহার করুন৷ আপনি যদি কোরোটিন প্রসঙ্গে একাধিক লঞ্চ ফাংশন ব্যবহার করেন, তবে এটি একই সময়ে অ্যানিমেশনগুলি চালু করে:

val alphaAnimation = remember { Animatable(0f) }
val yAnimation = remember { Animatable(0f) }

LaunchedEffect("animationKey") {
    launch {
        alphaAnimation.animateTo(1f)
    }
    launch {
        yAnimation.animateTo(100f)
    }
}

আপনি একই সময়ে বিভিন্ন সম্পত্তি অ্যানিমেশন চালানোর জন্য একই অবস্থা ব্যবহার করতে updateTransition API ব্যবহার করতে পারেন। নীচের উদাহরণটি রাষ্ট্রীয় পরিবর্তন, rect এবং borderWidth দ্বারা নিয়ন্ত্রিত দুটি বৈশিষ্ট্যকে অ্যানিমেট করে:

var currentState by remember { mutableStateOf(BoxState.Collapsed) }
val transition = updateTransition(currentState, label = "transition")

val rect by transition.animateRect(label = "rect") { state ->
    when (state) {
        BoxState.Collapsed -> Rect(0f, 0f, 100f, 100f)
        BoxState.Expanded -> Rect(100f, 100f, 300f, 300f)
    }
}
val borderWidth by transition.animateDp(label = "borderWidth") { state ->
    when (state) {
        BoxState.Collapsed -> 1.dp
        BoxState.Expanded -> 0.dp
    }
}

অ্যানিমেশন কর্মক্ষমতা অপ্টিমাইজ করুন

কম্পোজে অ্যানিমেশন কর্মক্ষমতা সমস্যা সৃষ্টি করতে পারে। এটি একটি অ্যানিমেশনের প্রকৃতির কারণে: স্ক্রিনে পিক্সেলগুলি দ্রুত সরানো বা পরিবর্তন করা, নড়াচড়ার বিভ্রম তৈরি করতে ফ্রেম-বাই-ফ্রেম।

রচনার বিভিন্ন ধাপ বিবেচনা করুন: রচনা, বিন্যাস এবং অঙ্কন। যদি আপনার অ্যানিমেশন লেআউট ফেজ পরিবর্তন করে, তাহলে রিলেআউট এবং পুনরায় আঁকার জন্য সমস্ত প্রভাবিত কম্পোজেবল প্রয়োজন। যদি আপনার অ্যানিমেশনটি ড্র পর্বে ঘটে থাকে, তবে এটি ডিফল্টভাবে আপনি যদি লেআউট পর্বে অ্যানিমেশন চালাতে চান তার চেয়ে বেশি পারফরম্যান্স হবে, কারণ এতে সামগ্রিকভাবে কম কাজ করতে হবে।

অ্যানিমেট করার সময় আপনার অ্যাপ যতটা সম্ভব কম করে তা নিশ্চিত করতে, যেখানে সম্ভব সেখানে একটি Modifier ল্যাম্বডা সংস্করণ বেছে নিন। এটি পুনর্গঠন এড়িয়ে যায় এবং কম্পোজিশন পর্বের বাইরে অ্যানিমেশন সম্পাদন করে, অন্যথায় Modifier.graphicsLayer{ } ব্যবহার করুন, কারণ এই মডিফায়ারটি সবসময় ড্র পর্বে চলে। এই বিষয়ে আরও তথ্যের জন্য, কর্মক্ষমতা ডকুমেন্টেশনে ডিফারিং রিডস বিভাগটি দেখুন।

অ্যানিমেশনের সময় পরিবর্তন করুন

বেশিরভাগ অ্যানিমেশনের জন্য ডিফল্টভাবে কম্পোজ স্প্রিং অ্যানিমেশন ব্যবহার করে। স্প্রিংস, বা পদার্থবিদ্যা-ভিত্তিক অ্যানিমেশনগুলি আরও প্রাকৃতিক অনুভব করে। তারা একটি নির্দিষ্ট সময়ের পরিবর্তে বস্তুর বর্তমান বেগ বিবেচনায় নেওয়ায় বাধাযোগ্য। আপনি যদি ডিফল্টটিকে ওভাররাইড করতে চান, উপরে প্রদর্শিত সমস্ত অ্যানিমেশন API-এ একটি অ্যানিমেশন কীভাবে চলবে তা কাস্টমাইজ করার জন্য একটি animationSpec সেট করার ক্ষমতা রয়েছে, আপনি এটি একটি নির্দিষ্ট সময়কাল ধরে চালাতে চান বা আরও বাউন্সি হতে চান।

নিম্নলিখিত animationSpec বিকল্পগুলির একটি সারাংশ:

  • spring : পদার্থবিদ্যা-ভিত্তিক অ্যানিমেশন, সমস্ত অ্যানিমেশনের জন্য ডিফল্ট। আপনি একটি ভিন্ন অ্যানিমেশন চেহারা এবং অনুভূতি অর্জন করতে কঠোরতা বা স্যাঁতসেঁতে অনুপাত পরিবর্তন করতে পারেন।
  • tween ( এর মধ্যে সংক্ষিপ্ত): সময়কাল-ভিত্তিক অ্যানিমেশন, একটি Easing ফাংশন সহ দুটি মানের মধ্যে অ্যানিমেট করে।
  • keyframes : একটি অ্যানিমেশনের কিছু মূল পয়েন্টে মান নির্দিষ্ট করার জন্য বিশেষ।
  • repeatable : সময়কাল-ভিত্তিক বৈশিষ্ট্য যা একটি নির্দিষ্ট সংখ্যক বার চলে, RepeatMode দ্বারা নির্দিষ্ট করা হয়।
  • infiniteRepeatable : সময়কাল-ভিত্তিক বৈশিষ্ট্য যা চিরকাল চলে।
  • snap : কোনো অ্যানিমেশন ছাড়াই তাত্ক্ষণিকভাবে শেষ মান পর্যন্ত স্ন্যাপ করে।
এখানে আপনার বিকল্প টেক্সট লিখুন
চিত্র 16. কোন স্পেক সেট বনাম কাস্টম স্প্রিং স্পেক সেট নেই

অ্যানিমেশনস্পেকস সম্পর্কে আরও তথ্যের জন্য সম্পূর্ণ ডকুমেন্টেশন পড়ুন।

অতিরিক্ত সম্পদ

রচনায় মজাদার অ্যানিমেশনের আরও উদাহরণের জন্য, নিম্নলিখিতগুলি দেখুন:

,

রচনার অনেকগুলি অন্তর্নির্মিত অ্যানিমেশন প্রক্রিয়া রয়েছে এবং কোনটি বেছে নেবেন তা জানা অপ্রতিরোধ্য হতে পারে৷ নীচে সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রের একটি তালিকা রয়েছে। আপনার কাছে উপলব্ধ বিভিন্ন API বিকল্পগুলির সম্পূর্ণ সেট সম্পর্কে আরও বিশদ তথ্যের জন্য, সম্পূর্ণ রচনা অ্যানিমেশন ডকুমেন্টেশন পড়ুন।

অ্যানিমেট সাধারণ কম্পোজেবল বৈশিষ্ট্য

কম্পোজ সুবিধাজনক API প্রদান করে যা আপনাকে অনেক সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রে সমাধান করতে দেয়। এই বিভাগটি দেখায় কিভাবে আপনি একটি কম্পোজেবলের সাধারণ বৈশিষ্ট্যগুলিকে অ্যানিমেট করতে পারেন।

অ্যানিমেট উপস্থিত / অদৃশ্য হয়ে যাওয়া

সবুজ কম্পোজেবল দেখাচ্ছে এবং নিজেকে লুকিয়ে
চিত্র 1. একটি কলামে একটি আইটেমের উপস্থিতি এবং অদৃশ্য হওয়া অ্যানিমেটিং

কম্পোজেবল লুকাতে বা দেখানোর জন্য AnimatedVisibility ব্যবহার করুন। AnimatedVisibility ভিতরে থাকা শিশুরা তাদের নিজস্ব প্রবেশ বা প্রস্থান পরিবর্তনের জন্য Modifier.animateEnterExit() ব্যবহার করতে পারে।

var visible by remember {
    mutableStateOf(true)
}
// Animated visibility will eventually remove the item from the composition once the animation has finished.
AnimatedVisibility(visible) {
    // your composable here
    // ...
}

AnimatedVisibility প্রবেশ এবং প্রস্থান পরামিতিগুলি আপনাকে একটি কম্পোজেবল যখন এটি প্রদর্শিত এবং অদৃশ্য হয়ে যায় তখন কীভাবে আচরণ করে তা কনফিগার করার অনুমতি দেয়। আরও তথ্যের জন্য সম্পূর্ণ ডকুমেন্টেশন পড়ুন.

একটি কম্পোজেবলের দৃশ্যমানতা অ্যানিমেট করার জন্য আরেকটি বিকল্প হল animateFloatAsState ব্যবহার করে সময়ের সাথে আলফাকে অ্যানিমেট করা:

var visible by remember {
    mutableStateOf(true)
}
val animatedAlpha by animateFloatAsState(
    targetValue = if (visible) 1.0f else 0f,
    label = "alpha"
)
Box(
    modifier = Modifier
        .size(200.dp)
        .graphicsLayer {
            alpha = animatedAlpha
        }
        .clip(RoundedCornerShape(8.dp))
        .background(colorGreen)
        .align(Alignment.TopCenter)
) {
}

যাইহোক, আলফা পরিবর্তনের সাথে সতর্কতা আসে যে কম্পোজেবলটি কম্পোজিশনের মধ্যেই থেকে যায় এবং এটির মধ্যে যে স্থানটি স্থাপন করা হয়েছে সেটি দখল করতে থাকে। এর ফলে স্ক্রীন রিডার এবং অন্যান্য অ্যাক্সেসিবিলিটি মেকানিজম এখনও স্ক্রিনে আইটেমটিকে বিবেচনা করতে পারে। অন্যদিকে, AnimatedVisibility শেষ পর্যন্ত কম্পোজিশন থেকে আইটেমটিকে সরিয়ে দেয়।

একটি কম্পোজেবল এর আলফা অ্যানিমেটিং
চিত্র 2. একটি কম্পোজেবলের আলফা অ্যানিমেটিং

অ্যানিমেট পটভূমির রঙ

অ্যানিমেশন হিসাবে সময়ের সাথে সাথে পটভূমির রঙ পরিবর্তিত হওয়ার সাথে কম্পোজযোগ্য, যেখানে রঙগুলি একে অপরের মধ্যে বিবর্ণ হয়ে যাচ্ছে।
চিত্র 3. কম্পোজেবলের অ্যানিমেটিং ব্যাকগ্রাউন্ড কালার

val animatedColor by animateColorAsState(
    if (animateBackgroundColor) colorGreen else colorBlue,
    label = "color"
)
Column(
    modifier = Modifier.drawBehind {
        drawRect(animatedColor)
    }
) {
    // your composable here
}

এই বিকল্পটি Modifier.background() ব্যবহার করার চেয়ে বেশি কার্যকরী। Modifier.background() একটি এক-শট রঙের সেটিং এর জন্য গ্রহণযোগ্য, কিন্তু সময়ের সাথে সাথে একটি রঙ অ্যানিমেট করার সময়, এটি প্রয়োজনের চেয়ে বেশি পুনর্গঠনের কারণ হতে পারে।

পটভূমির রঙ অসীমভাবে অ্যানিমেট করার জন্য, একটি অ্যানিমেশন বিভাগের পুনরাবৃত্তি দেখুন।

একটি কম্পোজেবল আকার অ্যানিমেট

সবুজ সংমিশ্রণযোগ্য অ্যানিমেটিং এর আকার মসৃণভাবে পরিবর্তন করে।
চিত্র 4. কম্পোজযোগ্য মসৃণভাবে একটি ছোট এবং একটি বড় আকারের মধ্যে অ্যানিমেটিং

রচনা আপনাকে কয়েকটি ভিন্ন উপায়ে কম্পোজেবলের আকার অ্যানিমেট করতে দেয়। কম্পোজযোগ্য আকার পরিবর্তনের মধ্যে অ্যানিমেশনের জন্য animateContentSize() ব্যবহার করুন।

উদাহরণস্বরূপ, যদি আপনার একটি বাক্স থাকে যাতে পাঠ্য থাকে যা এক থেকে একাধিক লাইনে প্রসারিত হতে পারে আপনি একটি মসৃণ রূপান্তর অর্জন করতে Modifier.animateContentSize() ব্যবহার করতে পারেন:

var expanded by remember { mutableStateOf(false) }
Box(
    modifier = Modifier
        .background(colorBlue)
        .animateContentSize()
        .height(if (expanded) 400.dp else 200.dp)
        .fillMaxWidth()
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            expanded = !expanded
        }

) {
}

আকার পরিবর্তন কিভাবে ঘটতে হবে তা বর্ণনা করতে আপনি একটি SizeTransform সহ AnimatedContent ব্যবহার করতে পারেন।

কম্পোজেবলের অ্যানিমেট অবস্থান

সবুজ কম্পোজযোগ্য মসৃণভাবে নিচে এবং ডানদিকে অ্যানিমেটিং
চিত্র 5. একটি অফসেট দ্বারা কম্পোজেবল চলন্ত

কম্পোজেবলের অবস্থান অ্যানিমেট করতে, animateIntOffsetAsState() এর সাথে মিলিত Modifier.offset{ } ব্যবহার করুন।

var moved by remember { mutableStateOf(false) }
val pxToMove = with(LocalDensity.current) {
    100.dp.toPx().roundToInt()
}
val offset by animateIntOffsetAsState(
    targetValue = if (moved) {
        IntOffset(pxToMove, pxToMove)
    } else {
        IntOffset.Zero
    },
    label = "offset"
)

Box(
    modifier = Modifier
        .offset {
            offset
        }
        .background(colorBlue)
        .size(100.dp)
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            moved = !moved
        }
)

আপনি যদি নিশ্চিত করতে চান যে অবস্থান বা আকার অ্যানিমেট করার সময় কম্পোজেবলগুলি অন্য কম্পোজেবলের উপরে বা নীচে আঁকা না হয়, Modifier.layout{ } । এই সংশোধকটি পিতামাতার কাছে আকার এবং অবস্থানের পরিবর্তনগুলি প্রচার করে, যা পরে অন্যান্য শিশুদের প্রভাবিত করে।

উদাহরণস্বরূপ, যদি আপনি একটি Column মধ্যে একটি Box সরান এবং Box নড়াচড়া করার সময় অন্যান্য শিশুদের সরাতে হয়, তাহলে নিম্নরূপ Modifier.layout{ } এর সাথে অফসেট তথ্য অন্তর্ভুক্ত করুন:

var toggled by remember {
    mutableStateOf(false)
}
val interactionSource = remember {
    MutableInteractionSource()
}
Column(
    modifier = Modifier
        .padding(16.dp)
        .fillMaxSize()
        .clickable(indication = null, interactionSource = interactionSource) {
            toggled = !toggled
        }
) {
    val offsetTarget = if (toggled) {
        IntOffset(150, 150)
    } else {
        IntOffset.Zero
    }
    val offset = animateIntOffsetAsState(
        targetValue = offsetTarget, label = "offset"
    )
    Box(
        modifier = Modifier
            .size(100.dp)
            .background(colorBlue)
    )
    Box(
        modifier = Modifier
            .layout { measurable, constraints ->
                val offsetValue = if (isLookingAhead) offsetTarget else offset.value
                val placeable = measurable.measure(constraints)
                layout(placeable.width + offsetValue.x, placeable.height + offsetValue.y) {
                    placeable.placeRelative(offsetValue)
                }
            }
            .size(100.dp)
            .background(colorGreen)
    )
    Box(
        modifier = Modifier
            .size(100.dp)
            .background(colorBlue)
    )
}

২য় বক্সের সাথে ২য় বক্স তার X,Y অবস্থানকে অ্যানিমেট করে, তৃতীয় বক্সটিও Y পরিমাণে নিজেকে সরিয়ে সাড়া দেয়।
চিত্র 6. Modifier.layout{ }

একটি রচনাযোগ্য প্যাডিং অ্যানিমেট

সবুজ সংমিশ্রণযোগ্য প্যাডিং অ্যানিমেটেড সহ ক্লিকে ছোট এবং বড় হচ্ছে
চিত্র 7. এর প্যাডিং অ্যানিমেটিং সহ কম্পোজযোগ্য

একটি কম্পোজেবলের প্যাডিং অ্যানিমেট করতে, Modifier.padding() এর সাথে মিলিত animateDpAsState ব্যবহার করুন :

var toggled by remember {
    mutableStateOf(false)
}
val animatedPadding by animateDpAsState(
    if (toggled) {
        0.dp
    } else {
        20.dp
    },
    label = "padding"
)
Box(
    modifier = Modifier
        .aspectRatio(1f)
        .fillMaxSize()
        .padding(animatedPadding)
        .background(Color(0xff53D9A1))
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            toggled = !toggled
        }
)

একটি কম্পোজেবল এর অ্যানিমেট উচ্চতা

চিত্র 8. ক্লিকে কম্পোজেবলের উচ্চতা অ্যানিমেটিং

একটি কম্পোজেবলের উচ্চতা অ্যানিমেট করতে, Modifier.graphicsLayer{ } এর সাথে মিলিত animateDpAsState ব্যবহার করুন{ }। একবার-বন্ধ উচ্চতা পরিবর্তনের জন্য, Modifier.shadow() ব্যবহার করুন। আপনি যদি ছায়াটিকে অ্যানিমেটিং করেন, Modifier.graphicsLayer{ } modifier ব্যবহার করা হল আরও কার্যকরী বিকল্প।

val mutableInteractionSource = remember {
    MutableInteractionSource()
}
val pressed = mutableInteractionSource.collectIsPressedAsState()
val elevation = animateDpAsState(
    targetValue = if (pressed.value) {
        32.dp
    } else {
        8.dp
    },
    label = "elevation"
)
Box(
    modifier = Modifier
        .size(100.dp)
        .align(Alignment.Center)
        .graphicsLayer {
            this.shadowElevation = elevation.value.toPx()
        }
        .clickable(interactionSource = mutableInteractionSource, indication = null) {
        }
        .background(colorGreen)
) {
}

বিকল্পভাবে, Card কম্পোজেবল ব্যবহার করুন, এবং উচ্চতা সম্পত্তি প্রতি রাজ্যে বিভিন্ন মান সেট করুন।

অ্যানিমেট টেক্সট স্কেল, অনুবাদ বা ঘূর্ণন

টেক্সট কম্পোজেবল উক্তি
চিত্র 9. দুটি আকারের মধ্যে মসৃণভাবে টেক্সট অ্যানিমেটিং

স্কেল, অনুবাদ বা পাঠ্যের ঘূর্ণন অ্যানিমেটিং করার সময়, TextStyletextMotion প্যারামিটার সেট করুন। TextMotion.Animated । এটি পাঠ্য অ্যানিমেশনগুলির মধ্যে মসৃণ রূপান্তর নিশ্চিত করে। টেক্সট অনুবাদ করতে, ঘোরাতে বা স্কেল করতে Modifier.graphicsLayer{ } ব্যবহার করুন।

val infiniteTransition = rememberInfiniteTransition(label = "infinite transition")
val scale by infiniteTransition.animateFloat(
    initialValue = 1f,
    targetValue = 8f,
    animationSpec = infiniteRepeatable(tween(1000), RepeatMode.Reverse),
    label = "scale"
)
Box(modifier = Modifier.fillMaxSize()) {
    Text(
        text = "Hello",
        modifier = Modifier
            .graphicsLayer {
                scaleX = scale
                scaleY = scale
                transformOrigin = TransformOrigin.Center
            }
            .align(Alignment.Center),
        // Text composable does not take TextMotion as a parameter.
        // Provide it via style argument but make sure that we are copying from current theme
        style = LocalTextStyle.current.copy(textMotion = TextMotion.Animated)
    )
}

অ্যানিমেট টেক্সট রঙ

শব্দ
চিত্র 10. অ্যানিমেটিং টেক্সট রঙ দেখানোর উদাহরণ

টেক্সট কালার অ্যানিমেট করতে, BasicText কম্পোজেবলে color ল্যাম্বডা ব্যবহার করুন:

val infiniteTransition = rememberInfiniteTransition(label = "infinite transition")
val animatedColor by infiniteTransition.animateColor(
    initialValue = Color(0xFF60DDAD),
    targetValue = Color(0xFF4285F4),
    animationSpec = infiniteRepeatable(tween(1000), RepeatMode.Reverse),
    label = "color"
)

BasicText(
    text = "Hello Compose",
    color = {
        animatedColor
    },
    // ...
)

বিভিন্ন ধরনের সামগ্রীর মধ্যে স্যুইচ করুন

সবুজ পর্দা বলছে
চিত্র 11. অ্যানিমেটেড কনটেন্ট ব্যবহার করে বিভিন্ন কম্পোজেবলের মধ্যে পরিবর্তন অ্যানিমেট করা (ধীরগতির)

বিভিন্ন কম্পোজেবলের মধ্যে অ্যানিমেট করতে AnimatedContent ব্যবহার করুন, আপনি যদি কম্পোজেবলের মধ্যে একটি স্ট্যান্ডার্ড ফেইড চান, Crossfade ব্যবহার করুন।

var state by remember {
    mutableStateOf(UiState.Loading)
}
AnimatedContent(
    state,
    transitionSpec = {
        fadeIn(
            animationSpec = tween(3000)
        ) togetherWith fadeOut(animationSpec = tween(3000))
    },
    modifier = Modifier.clickable(
        interactionSource = remember { MutableInteractionSource() },
        indication = null
    ) {
        state = when (state) {
            UiState.Loading -> UiState.Loaded
            UiState.Loaded -> UiState.Error
            UiState.Error -> UiState.Loading
        }
    },
    label = "Animated Content"
) { targetState ->
    when (targetState) {
        UiState.Loading -> {
            LoadingScreen()
        }
        UiState.Loaded -> {
            LoadedScreen()
        }
        UiState.Error -> {
            ErrorScreen()
        }
    }
}

AnimatedContent বিভিন্ন ধরণের এন্টার এবং এক্সিট ট্রানজিশন দেখানোর জন্য কাস্টমাইজ করা যেতে পারে। আরও তথ্যের জন্য, AnimatedContent এ ডকুমেন্টেশন পড়ুন বা AnimatedContent এ এই ব্লগ পোস্ট পড়ুন।

বিভিন্ন গন্তব্যে নেভিগেট করার সময় অ্যানিমেট করুন

দুটি কম্পোজেবল, একটি সবুজ বলছে ল্যান্ডিং এবং একটি নীল বলছে ডিটেইল, ল্যান্ডিং কম্পোজেবলের উপর বিশদ কম্পোজযোগ্য স্লাইড করে অ্যানিমেটিং।
চিত্র 12. নেভিগেশন-কম্পোজ ব্যবহার করে কম্পোজেবলের মধ্যে অ্যানিমেটিং

নেভিগেশন-কম্পোজ আর্টিফ্যাক্ট ব্যবহার করার সময় কম্পোজেবলের মধ্যে ট্রানজিশন অ্যানিমেট করতে, একটি কম্পোজেবলের enterTransition এবং exitTransition নির্দিষ্ট করুন। আপনি শীর্ষ স্তরের NavHost এ সমস্ত গন্তব্যের জন্য ব্যবহার করার জন্য ডিফল্ট অ্যানিমেশন সেট করতে পারেন:

val navController = rememberNavController()
NavHost(
    navController = navController, startDestination = "landing",
    enterTransition = { EnterTransition.None },
    exitTransition = { ExitTransition.None }
) {
    composable("landing") {
        ScreenLanding(
            // ...
        )
    }
    composable(
        "detail/{photoUrl}",
        arguments = listOf(navArgument("photoUrl") { type = NavType.StringType }),
        enterTransition = {
            fadeIn(
                animationSpec = tween(
                    300, easing = LinearEasing
                )
            ) + slideIntoContainer(
                animationSpec = tween(300, easing = EaseIn),
                towards = AnimatedContentTransitionScope.SlideDirection.Start
            )
        },
        exitTransition = {
            fadeOut(
                animationSpec = tween(
                    300, easing = LinearEasing
                )
            ) + slideOutOfContainer(
                animationSpec = tween(300, easing = EaseOut),
                towards = AnimatedContentTransitionScope.SlideDirection.End
            )
        }
    ) { backStackEntry ->
        ScreenDetails(
            // ...
        )
    }
}

বিভিন্ন ধরণের এন্টার এবং এক্সিট ট্রানজিশন রয়েছে যা ইনকামিং এবং আউটগোয়িং কন্টেন্টে বিভিন্ন প্রভাব প্রয়োগ করে, আরও তথ্যের জন্য ডকুমেন্টেশন দেখুন।

একটি অ্যানিমেশন পুনরাবৃত্তি করুন

একটি সবুজ পটভূমি যা একটি নীল পটভূমিতে রূপান্তরিত হয়, অসীমভাবে দুটি রঙের মধ্যে অ্যানিমেট করে।
চিত্র 13. পটভূমির রঙ দুটি মানের মধ্যে অ্যানিমেটিং, অসীমভাবে

আপনার অ্যানিমেশন ক্রমাগত পুনরাবৃত্তি করতে একটি infiniteRepeatable animationSpec এর সাথে rememberInfiniteTransition ব্যবহার করুন। RepeatModes কীভাবে সামনে পিছনে যেতে হবে তা নির্দিষ্ট করতে পরিবর্তন করুন।

নির্দিষ্ট সংখ্যক বার পুনরাবৃত্তি করতে finiteRepeatable ব্যবহার করুন।

val infiniteTransition = rememberInfiniteTransition(label = "infinite")
val color by infiniteTransition.animateColor(
    initialValue = Color.Green,
    targetValue = Color.Blue,
    animationSpec = infiniteRepeatable(
        animation = tween(1000, easing = LinearEasing),
        repeatMode = RepeatMode.Reverse
    ),
    label = "color"
)
Column(
    modifier = Modifier.drawBehind {
        drawRect(color)
    }
) {
    // your composable here
}

একটি কম্পোজেবল চালু করার সময় একটি অ্যানিমেশন শুরু করুন

LaunchedEffect চলে যখন একটি কম্পোজেবল কম্পোজিশনে প্রবেশ করে। এটি একটি কম্পোজেবল চালু করার সময় একটি অ্যানিমেশন শুরু করে, আপনি অ্যানিমেশনের অবস্থা পরিবর্তন করতে এটি ব্যবহার করতে পারেন। লঞ্চে অ্যানিমেশন শুরু করতে animateTo পদ্ধতির সাথে Animatable ব্যবহার করুন:

val alphaAnimation = remember {
    Animatable(0f)
}
LaunchedEffect(Unit) {
    alphaAnimation.animateTo(1f)
}
Box(
    modifier = Modifier.graphicsLayer {
        alpha = alphaAnimation.value
    }
)

ক্রমিক অ্যানিমেশন তৈরি করুন

সবুজ তীর সহ চারটি চেনাশোনা প্রতিটির মধ্যে অ্যানিমেট করছে, একের পর এক অ্যানিমেট করছে।
চিত্র 14. একটি অনুক্রমিক অ্যানিমেশন কীভাবে একের পর এক অগ্রসর হয় তা নির্দেশ করে চিত্র।

অনুক্রমিক বা সমসাময়িক অ্যানিমেশনগুলি সম্পাদন করতে Animatable কোরোটিন API ব্যবহার করুন। Animatable একের পর এক animateTo কল করার ফলে প্রতিটি অ্যানিমেশন এগিয়ে যাওয়ার আগে পূর্ববর্তী অ্যানিমেশনগুলি শেষ হওয়ার জন্য অপেক্ষা করে। কারণ এটি একটি সাসপেন্ড ফাংশন।

val alphaAnimation = remember { Animatable(0f) }
val yAnimation = remember { Animatable(0f) }

LaunchedEffect("animationKey") {
    alphaAnimation.animateTo(1f)
    yAnimation.animateTo(100f)
    yAnimation.animateTo(500f, animationSpec = tween(100))
}

সমসাময়িক অ্যানিমেশন তৈরি করুন

সবুজ তীর সহ তিনটি চেনাশোনা প্রতিটিতে অ্যানিমেট করছে, একই সময়ে সবগুলিকে অ্যানিমেট করছে৷
চিত্র 15. ডায়াগ্রামটি নির্দেশ করে যে কীভাবে সমসাময়িক অ্যানিমেশনগুলি একই সময়ে অগ্রসর হয়।

সমসাময়িক অ্যানিমেশনগুলি অর্জন করতে coroutine APIs ( Animatable#animateTo() বা animate ), বা Transition API ব্যবহার করুন৷ আপনি যদি কোরোটিন প্রসঙ্গে একাধিক লঞ্চ ফাংশন ব্যবহার করেন, তবে এটি একই সময়ে অ্যানিমেশনগুলি চালু করে:

val alphaAnimation = remember { Animatable(0f) }
val yAnimation = remember { Animatable(0f) }

LaunchedEffect("animationKey") {
    launch {
        alphaAnimation.animateTo(1f)
    }
    launch {
        yAnimation.animateTo(100f)
    }
}

আপনি একই সময়ে বিভিন্ন সম্পত্তি অ্যানিমেশন চালানোর জন্য একই অবস্থা ব্যবহার করতে updateTransition API ব্যবহার করতে পারেন। নীচের উদাহরণটি রাষ্ট্রীয় পরিবর্তন, rect এবং borderWidth দ্বারা নিয়ন্ত্রিত দুটি বৈশিষ্ট্যকে অ্যানিমেট করে:

var currentState by remember { mutableStateOf(BoxState.Collapsed) }
val transition = updateTransition(currentState, label = "transition")

val rect by transition.animateRect(label = "rect") { state ->
    when (state) {
        BoxState.Collapsed -> Rect(0f, 0f, 100f, 100f)
        BoxState.Expanded -> Rect(100f, 100f, 300f, 300f)
    }
}
val borderWidth by transition.animateDp(label = "borderWidth") { state ->
    when (state) {
        BoxState.Collapsed -> 1.dp
        BoxState.Expanded -> 0.dp
    }
}

অ্যানিমেশন কর্মক্ষমতা অপ্টিমাইজ করুন

কম্পোজে অ্যানিমেশন কর্মক্ষমতা সমস্যা সৃষ্টি করতে পারে। এটি একটি অ্যানিমেশনের প্রকৃতির কারণে: স্ক্রিনে পিক্সেলগুলি দ্রুত সরানো বা পরিবর্তন করা, নড়াচড়ার বিভ্রম তৈরি করতে ফ্রেম-বাই-ফ্রেম।

রচনার বিভিন্ন ধাপ বিবেচনা করুন: রচনা, বিন্যাস এবং অঙ্কন। যদি আপনার অ্যানিমেশন লেআউট ফেজ পরিবর্তন করে, তাহলে রিলেআউট এবং পুনরায় আঁকার জন্য সমস্ত প্রভাবিত কম্পোজেবল প্রয়োজন। যদি আপনার অ্যানিমেশনটি ড্র পর্বে ঘটে থাকে, তবে এটি ডিফল্টভাবে আপনি যদি লেআউট পর্বে অ্যানিমেশন চালাতে চান তার চেয়ে বেশি পারফরম্যান্স হবে, কারণ এতে সামগ্রিকভাবে কম কাজ করতে হবে।

অ্যানিমেট করার সময় আপনার অ্যাপ যতটা সম্ভব কম করে তা নিশ্চিত করতে, যেখানে সম্ভব সেখানে একটি Modifier ল্যাম্বডা সংস্করণ বেছে নিন। এটি পুনর্গঠন এড়িয়ে যায় এবং কম্পোজিশন পর্বের বাইরে অ্যানিমেশন সম্পাদন করে, অন্যথায় Modifier.graphicsLayer{ } ব্যবহার করুন, কারণ এই মডিফায়ারটি সবসময় ড্র পর্বে চলে। এই বিষয়ে আরও তথ্যের জন্য, কর্মক্ষমতা ডকুমেন্টেশনে ডিফারিং রিডস বিভাগটি দেখুন।

অ্যানিমেশনের সময় পরিবর্তন করুন

বেশিরভাগ অ্যানিমেশনের জন্য ডিফল্টভাবে কম্পোজ স্প্রিং অ্যানিমেশন ব্যবহার করে। স্প্রিংস, বা পদার্থবিদ্যা-ভিত্তিক অ্যানিমেশনগুলি আরও প্রাকৃতিক অনুভব করে। তারা একটি নির্দিষ্ট সময়ের পরিবর্তে বস্তুর বর্তমান বেগ বিবেচনায় নেওয়ায় বাধাযোগ্য। আপনি যদি ডিফল্টটিকে ওভাররাইড করতে চান, উপরে প্রদর্শিত সমস্ত অ্যানিমেশন API-এ একটি অ্যানিমেশন কীভাবে চলবে তা কাস্টমাইজ করার জন্য একটি animationSpec সেট করার ক্ষমতা রয়েছে, আপনি এটি একটি নির্দিষ্ট সময়কাল ধরে চালাতে চান বা আরও বাউন্সি হতে চান।

নিম্নলিখিত animationSpec বিকল্পগুলির একটি সারাংশ:

  • spring : পদার্থবিদ্যা-ভিত্তিক অ্যানিমেশন, সমস্ত অ্যানিমেশনের জন্য ডিফল্ট। আপনি একটি ভিন্ন অ্যানিমেশন চেহারা এবং অনুভূতি অর্জন করতে কঠোরতা বা স্যাঁতসেঁতে অনুপাত পরিবর্তন করতে পারেন।
  • tween ( এর মধ্যে সংক্ষিপ্ত): সময়কাল-ভিত্তিক অ্যানিমেশন, একটি Easing ফাংশন সহ দুটি মানের মধ্যে অ্যানিমেট করে।
  • keyframes : একটি অ্যানিমেশনের কিছু মূল পয়েন্টে মান নির্দিষ্ট করার জন্য বিশেষ।
  • repeatable : সময়কাল-ভিত্তিক বৈশিষ্ট্য যা একটি নির্দিষ্ট সংখ্যক বার চলে, RepeatMode দ্বারা নির্দিষ্ট করা হয়।
  • infiniteRepeatable : সময়কাল-ভিত্তিক বৈশিষ্ট্য যা চিরকাল চলে।
  • snap : কোনো অ্যানিমেশন ছাড়াই তাত্ক্ষণিকভাবে শেষ মান পর্যন্ত স্ন্যাপ করে।
এখানে আপনার বিকল্প টেক্সট লিখুন
চিত্র 16. কোন স্পেক সেট বনাম কাস্টম স্প্রিং স্পেক সেট নেই

অ্যানিমেশনস্পেকস সম্পর্কে আরও তথ্যের জন্য সম্পূর্ণ ডকুমেন্টেশন পড়ুন।

অতিরিক্ত সম্পদ

রচনায় মজাদার অ্যানিমেশনের আরও উদাহরণের জন্য, নিম্নলিখিতগুলি দেখুন:

,

রচনার অনেকগুলি অন্তর্নির্মিত অ্যানিমেশন প্রক্রিয়া রয়েছে এবং কোনটি বেছে নেবেন তা জানা অপ্রতিরোধ্য হতে পারে৷ নীচে সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রের একটি তালিকা রয়েছে। আপনার কাছে উপলব্ধ বিভিন্ন API বিকল্পগুলির সম্পূর্ণ সেট সম্পর্কে আরও বিশদ তথ্যের জন্য, সম্পূর্ণ রচনা অ্যানিমেশন ডকুমেন্টেশন পড়ুন।

অ্যানিমেট সাধারণ কম্পোজেবল বৈশিষ্ট্য

কম্পোজ সুবিধাজনক API প্রদান করে যা আপনাকে অনেক সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রে সমাধান করতে দেয়। এই বিভাগটি দেখায় কিভাবে আপনি একটি কম্পোজেবলের সাধারণ বৈশিষ্ট্যগুলিকে অ্যানিমেট করতে পারেন।

অ্যানিমেট উপস্থিত / অদৃশ্য হয়ে যাওয়া

সবুজ কম্পোজেবল দেখাচ্ছে এবং নিজেকে লুকিয়ে
চিত্র 1. একটি কলামে একটি আইটেমের উপস্থিতি এবং অদৃশ্য হওয়া অ্যানিমেটিং

কম্পোজেবল লুকাতে বা দেখানোর জন্য AnimatedVisibility ব্যবহার করুন। AnimatedVisibility ভিতরে থাকা শিশুরা তাদের নিজস্ব প্রবেশ বা প্রস্থান পরিবর্তনের জন্য Modifier.animateEnterExit() ব্যবহার করতে পারে।

var visible by remember {
    mutableStateOf(true)
}
// Animated visibility will eventually remove the item from the composition once the animation has finished.
AnimatedVisibility(visible) {
    // your composable here
    // ...
}

AnimatedVisibility প্রবেশ এবং প্রস্থান পরামিতিগুলি আপনাকে একটি কম্পোজেবল যখন এটি প্রদর্শিত এবং অদৃশ্য হয়ে যায় তখন কীভাবে আচরণ করে তা কনফিগার করার অনুমতি দেয়। আরও তথ্যের জন্য সম্পূর্ণ ডকুমেন্টেশন পড়ুন.

একটি কম্পোজেবলের দৃশ্যমানতা অ্যানিমেট করার জন্য আরেকটি বিকল্প হল animateFloatAsState ব্যবহার করে সময়ের সাথে আলফাকে অ্যানিমেট করা:

var visible by remember {
    mutableStateOf(true)
}
val animatedAlpha by animateFloatAsState(
    targetValue = if (visible) 1.0f else 0f,
    label = "alpha"
)
Box(
    modifier = Modifier
        .size(200.dp)
        .graphicsLayer {
            alpha = animatedAlpha
        }
        .clip(RoundedCornerShape(8.dp))
        .background(colorGreen)
        .align(Alignment.TopCenter)
) {
}

যাইহোক, আলফা পরিবর্তনের সাথে সতর্কতা আসে যে কম্পোজেবলটি কম্পোজিশনের মধ্যেই থেকে যায় এবং এটির মধ্যে যে স্থানটি স্থাপন করা হয়েছে সেটি দখল করতে থাকে। এর ফলে স্ক্রীন রিডার এবং অন্যান্য অ্যাক্সেসিবিলিটি মেকানিজম এখনও স্ক্রিনে আইটেমটিকে বিবেচনা করতে পারে। অন্যদিকে, AnimatedVisibility শেষ পর্যন্ত কম্পোজিশন থেকে আইটেমটিকে সরিয়ে দেয়।

একটি কম্পোজেবল এর আলফা অ্যানিমেটিং
চিত্র 2. একটি কম্পোজেবলের আলফা অ্যানিমেটিং

অ্যানিমেট পটভূমির রঙ

অ্যানিমেশন হিসাবে সময়ের সাথে সাথে পটভূমির রঙ পরিবর্তিত হওয়ার সাথে কম্পোজযোগ্য, যেখানে রঙগুলি একে অপরের মধ্যে বিবর্ণ হয়ে যাচ্ছে।
চিত্র 3. কম্পোজেবলের অ্যানিমেটিং ব্যাকগ্রাউন্ড কালার

val animatedColor by animateColorAsState(
    if (animateBackgroundColor) colorGreen else colorBlue,
    label = "color"
)
Column(
    modifier = Modifier.drawBehind {
        drawRect(animatedColor)
    }
) {
    // your composable here
}

এই বিকল্পটি Modifier.background() ব্যবহার করার চেয়ে বেশি কার্যকরী। Modifier.background() একটি এক-শট রঙের সেটিং এর জন্য গ্রহণযোগ্য, কিন্তু সময়ের সাথে সাথে একটি রঙ অ্যানিমেট করার সময়, এটি প্রয়োজনের চেয়ে বেশি পুনর্গঠনের কারণ হতে পারে।

পটভূমির রঙ অসীমভাবে অ্যানিমেট করার জন্য, একটি অ্যানিমেশন বিভাগের পুনরাবৃত্তি দেখুন।

একটি কম্পোজেবল আকার অ্যানিমেট

সবুজ সংমিশ্রণযোগ্য অ্যানিমেটিং এর আকার মসৃণভাবে পরিবর্তন করে।
চিত্র 4. কম্পোজযোগ্য মসৃণভাবে একটি ছোট এবং একটি বড় আকারের মধ্যে অ্যানিমেটিং

রচনা আপনাকে কয়েকটি ভিন্ন উপায়ে কম্পোজেবলের আকার অ্যানিমেট করতে দেয়। কম্পোজযোগ্য আকার পরিবর্তনের মধ্যে অ্যানিমেশনের জন্য animateContentSize() ব্যবহার করুন।

উদাহরণস্বরূপ, যদি আপনার একটি বাক্স থাকে যাতে পাঠ্য থাকে যা এক থেকে একাধিক লাইনে প্রসারিত হতে পারে আপনি একটি মসৃণ রূপান্তর অর্জন করতে Modifier.animateContentSize() ব্যবহার করতে পারেন:

var expanded by remember { mutableStateOf(false) }
Box(
    modifier = Modifier
        .background(colorBlue)
        .animateContentSize()
        .height(if (expanded) 400.dp else 200.dp)
        .fillMaxWidth()
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            expanded = !expanded
        }

) {
}

আকার পরিবর্তন কিভাবে ঘটতে হবে তা বর্ণনা করতে আপনি একটি SizeTransform সহ AnimatedContent ব্যবহার করতে পারেন।

কম্পোজেবলের অ্যানিমেট অবস্থান

সবুজ কম্পোজযোগ্য মসৃণভাবে নিচে এবং ডানদিকে অ্যানিমেটিং
চিত্র 5. একটি অফসেট দ্বারা কম্পোজেবল চলন্ত

কম্পোজেবলের অবস্থান অ্যানিমেট করতে, animateIntOffsetAsState() এর সাথে মিলিত Modifier.offset{ } ব্যবহার করুন।

var moved by remember { mutableStateOf(false) }
val pxToMove = with(LocalDensity.current) {
    100.dp.toPx().roundToInt()
}
val offset by animateIntOffsetAsState(
    targetValue = if (moved) {
        IntOffset(pxToMove, pxToMove)
    } else {
        IntOffset.Zero
    },
    label = "offset"
)

Box(
    modifier = Modifier
        .offset {
            offset
        }
        .background(colorBlue)
        .size(100.dp)
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            moved = !moved
        }
)

আপনি যদি নিশ্চিত করতে চান যে অবস্থান বা আকার অ্যানিমেট করার সময় কম্পোজেবলগুলি অন্য কম্পোজেবলের উপরে বা নীচে আঁকা না হয়, Modifier.layout{ } । এই সংশোধকটি পিতামাতার কাছে আকার এবং অবস্থানের পরিবর্তনগুলি প্রচার করে, যা পরে অন্যান্য শিশুদের প্রভাবিত করে।

উদাহরণস্বরূপ, যদি আপনি একটি Column মধ্যে একটি Box সরান এবং Box নড়াচড়া করার সময় অন্যান্য শিশুদের সরাতে হয়, তাহলে নিম্নরূপ Modifier.layout{ } এর সাথে অফসেট তথ্য অন্তর্ভুক্ত করুন:

var toggled by remember {
    mutableStateOf(false)
}
val interactionSource = remember {
    MutableInteractionSource()
}
Column(
    modifier = Modifier
        .padding(16.dp)
        .fillMaxSize()
        .clickable(indication = null, interactionSource = interactionSource) {
            toggled = !toggled
        }
) {
    val offsetTarget = if (toggled) {
        IntOffset(150, 150)
    } else {
        IntOffset.Zero
    }
    val offset = animateIntOffsetAsState(
        targetValue = offsetTarget, label = "offset"
    )
    Box(
        modifier = Modifier
            .size(100.dp)
            .background(colorBlue)
    )
    Box(
        modifier = Modifier
            .layout { measurable, constraints ->
                val offsetValue = if (isLookingAhead) offsetTarget else offset.value
                val placeable = measurable.measure(constraints)
                layout(placeable.width + offsetValue.x, placeable.height + offsetValue.y) {
                    placeable.placeRelative(offsetValue)
                }
            }
            .size(100.dp)
            .background(colorGreen)
    )
    Box(
        modifier = Modifier
            .size(100.dp)
            .background(colorBlue)
    )
}

২য় বক্সের সাথে ২য় বক্স তার X,Y অবস্থানকে অ্যানিমেট করে, তৃতীয় বক্সটিও Y পরিমাণে নিজেকে সরিয়ে সাড়া দেয়।
চিত্র 6. Modifier.layout{ }

একটি রচনাযোগ্য প্যাডিং অ্যানিমেট

সবুজ সংমিশ্রণযোগ্য প্যাডিং অ্যানিমেটেড সহ ক্লিকে ছোট এবং বড় হচ্ছে
চিত্র 7. এর প্যাডিং অ্যানিমেটিং সহ কম্পোজযোগ্য

একটি কম্পোজেবলের প্যাডিং অ্যানিমেট করতে, Modifier.padding() এর সাথে মিলিত animateDpAsState ব্যবহার করুন :

var toggled by remember {
    mutableStateOf(false)
}
val animatedPadding by animateDpAsState(
    if (toggled) {
        0.dp
    } else {
        20.dp
    },
    label = "padding"
)
Box(
    modifier = Modifier
        .aspectRatio(1f)
        .fillMaxSize()
        .padding(animatedPadding)
        .background(Color(0xff53D9A1))
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            toggled = !toggled
        }
)

একটি কম্পোজেবল এর অ্যানিমেট উচ্চতা

চিত্র 8. ক্লিকে কম্পোজেবলের উচ্চতা অ্যানিমেটিং

একটি কম্পোজেবলের উচ্চতা অ্যানিমেট করতে, Modifier.graphicsLayer{ } এর সাথে মিলিত animateDpAsState ব্যবহার করুন{ }। একবার-বন্ধ উচ্চতা পরিবর্তনের জন্য, Modifier.shadow() ব্যবহার করুন। আপনি যদি ছায়াটিকে অ্যানিমেটিং করেন, Modifier.graphicsLayer{ } modifier ব্যবহার করা হল আরও কার্যকরী বিকল্প।

val mutableInteractionSource = remember {
    MutableInteractionSource()
}
val pressed = mutableInteractionSource.collectIsPressedAsState()
val elevation = animateDpAsState(
    targetValue = if (pressed.value) {
        32.dp
    } else {
        8.dp
    },
    label = "elevation"
)
Box(
    modifier = Modifier
        .size(100.dp)
        .align(Alignment.Center)
        .graphicsLayer {
            this.shadowElevation = elevation.value.toPx()
        }
        .clickable(interactionSource = mutableInteractionSource, indication = null) {
        }
        .background(colorGreen)
) {
}

বিকল্পভাবে, Card কম্পোজেবল ব্যবহার করুন, এবং উচ্চতা সম্পত্তি প্রতি রাজ্যে বিভিন্ন মান সেট করুন।

অ্যানিমেট টেক্সট স্কেল, অনুবাদ বা ঘূর্ণন

টেক্সট কম্পোজেবল উক্তি
চিত্র 9. দুটি আকারের মধ্যে মসৃণভাবে টেক্সট অ্যানিমেটিং

স্কেল, অনুবাদ বা পাঠ্যের ঘূর্ণন অ্যানিমেটিং করার সময়, TextStyletextMotion প্যারামিটার সেট করুন। TextMotion.Animated । এটি পাঠ্য অ্যানিমেশনগুলির মধ্যে মসৃণ রূপান্তর নিশ্চিত করে। টেক্সট অনুবাদ করতে, ঘোরাতে বা স্কেল করতে Modifier.graphicsLayer{ } ব্যবহার করুন।

val infiniteTransition = rememberInfiniteTransition(label = "infinite transition")
val scale by infiniteTransition.animateFloat(
    initialValue = 1f,
    targetValue = 8f,
    animationSpec = infiniteRepeatable(tween(1000), RepeatMode.Reverse),
    label = "scale"
)
Box(modifier = Modifier.fillMaxSize()) {
    Text(
        text = "Hello",
        modifier = Modifier
            .graphicsLayer {
                scaleX = scale
                scaleY = scale
                transformOrigin = TransformOrigin.Center
            }
            .align(Alignment.Center),
        // Text composable does not take TextMotion as a parameter.
        // Provide it via style argument but make sure that we are copying from current theme
        style = LocalTextStyle.current.copy(textMotion = TextMotion.Animated)
    )
}

অ্যানিমেট টেক্সট রঙ

শব্দ
চিত্র 10. অ্যানিমেটিং টেক্সট রঙ দেখানোর উদাহরণ

টেক্সট কালার অ্যানিমেট করতে, BasicText কম্পোজেবলে color ল্যাম্বডা ব্যবহার করুন:

val infiniteTransition = rememberInfiniteTransition(label = "infinite transition")
val animatedColor by infiniteTransition.animateColor(
    initialValue = Color(0xFF60DDAD),
    targetValue = Color(0xFF4285F4),
    animationSpec = infiniteRepeatable(tween(1000), RepeatMode.Reverse),
    label = "color"
)

BasicText(
    text = "Hello Compose",
    color = {
        animatedColor
    },
    // ...
)

বিভিন্ন ধরনের সামগ্রীর মধ্যে স্যুইচ করুন

সবুজ পর্দা বলছে
চিত্র 11. অ্যানিমেটেড কনটেন্ট ব্যবহার করে বিভিন্ন কম্পোজেবলের মধ্যে পরিবর্তন অ্যানিমেট করা (ধীরগতির)

বিভিন্ন কম্পোজেবলের মধ্যে অ্যানিমেট করতে AnimatedContent ব্যবহার করুন, আপনি যদি কম্পোজেবলের মধ্যে একটি স্ট্যান্ডার্ড ফেইড চান, Crossfade ব্যবহার করুন।

var state by remember {
    mutableStateOf(UiState.Loading)
}
AnimatedContent(
    state,
    transitionSpec = {
        fadeIn(
            animationSpec = tween(3000)
        ) togetherWith fadeOut(animationSpec = tween(3000))
    },
    modifier = Modifier.clickable(
        interactionSource = remember { MutableInteractionSource() },
        indication = null
    ) {
        state = when (state) {
            UiState.Loading -> UiState.Loaded
            UiState.Loaded -> UiState.Error
            UiState.Error -> UiState.Loading
        }
    },
    label = "Animated Content"
) { targetState ->
    when (targetState) {
        UiState.Loading -> {
            LoadingScreen()
        }
        UiState.Loaded -> {
            LoadedScreen()
        }
        UiState.Error -> {
            ErrorScreen()
        }
    }
}

AnimatedContent বিভিন্ন ধরণের এন্টার এবং এক্সিট ট্রানজিশন দেখানোর জন্য কাস্টমাইজ করা যেতে পারে। আরও তথ্যের জন্য, AnimatedContent এ ডকুমেন্টেশন পড়ুন বা AnimatedContent এ এই ব্লগ পোস্ট পড়ুন।

বিভিন্ন গন্তব্যে নেভিগেট করার সময় অ্যানিমেট করুন

দুটি কম্পোজেবল, একটি সবুজ বলছে ল্যান্ডিং এবং একটি নীল বলছে ডিটেইল, ল্যান্ডিং কম্পোজেবলের উপর বিশদ কম্পোজযোগ্য স্লাইড করে অ্যানিমেটিং।
চিত্র 12. নেভিগেশন-কম্পোজ ব্যবহার করে কম্পোজেবলের মধ্যে অ্যানিমেটিং

নেভিগেশন-কম্পোজ আর্টিফ্যাক্ট ব্যবহার করার সময় কম্পোজেবলের মধ্যে ট্রানজিশন অ্যানিমেট করতে, একটি কম্পোজেবলের enterTransition এবং exitTransition নির্দিষ্ট করুন। আপনি শীর্ষ স্তরের NavHost এ সমস্ত গন্তব্যের জন্য ব্যবহার করার জন্য ডিফল্ট অ্যানিমেশন সেট করতে পারেন:

val navController = rememberNavController()
NavHost(
    navController = navController, startDestination = "landing",
    enterTransition = { EnterTransition.None },
    exitTransition = { ExitTransition.None }
) {
    composable("landing") {
        ScreenLanding(
            // ...
        )
    }
    composable(
        "detail/{photoUrl}",
        arguments = listOf(navArgument("photoUrl") { type = NavType.StringType }),
        enterTransition = {
            fadeIn(
                animationSpec = tween(
                    300, easing = LinearEasing
                )
            ) + slideIntoContainer(
                animationSpec = tween(300, easing = EaseIn),
                towards = AnimatedContentTransitionScope.SlideDirection.Start
            )
        },
        exitTransition = {
            fadeOut(
                animationSpec = tween(
                    300, easing = LinearEasing
                )
            ) + slideOutOfContainer(
                animationSpec = tween(300, easing = EaseOut),
                towards = AnimatedContentTransitionScope.SlideDirection.End
            )
        }
    ) { backStackEntry ->
        ScreenDetails(
            // ...
        )
    }
}

বিভিন্ন ধরণের এন্টার এবং এক্সিট ট্রানজিশন রয়েছে যা ইনকামিং এবং আউটগোয়িং কন্টেন্টে বিভিন্ন প্রভাব প্রয়োগ করে, আরও তথ্যের জন্য ডকুমেন্টেশন দেখুন।

একটি অ্যানিমেশন পুনরাবৃত্তি করুন

একটি সবুজ পটভূমি যা একটি নীল পটভূমিতে রূপান্তরিত হয়, অসীমভাবে দুটি রঙের মধ্যে অ্যানিমেট করে।
চিত্র 13. পটভূমির রঙ দুটি মানের মধ্যে অ্যানিমেটিং, অসীমভাবে

আপনার অ্যানিমেশন ক্রমাগত পুনরাবৃত্তি করতে একটি infiniteRepeatable animationSpec এর সাথে rememberInfiniteTransition ব্যবহার করুন। RepeatModes কীভাবে সামনে পিছনে যেতে হবে তা নির্দিষ্ট করতে পরিবর্তন করুন।

নির্দিষ্ট সংখ্যক বার পুনরাবৃত্তি করতে finiteRepeatable ব্যবহার করুন।

val infiniteTransition = rememberInfiniteTransition(label = "infinite")
val color by infiniteTransition.animateColor(
    initialValue = Color.Green,
    targetValue = Color.Blue,
    animationSpec = infiniteRepeatable(
        animation = tween(1000, easing = LinearEasing),
        repeatMode = RepeatMode.Reverse
    ),
    label = "color"
)
Column(
    modifier = Modifier.drawBehind {
        drawRect(color)
    }
) {
    // your composable here
}

একটি কম্পোজেবল চালু করার সময় একটি অ্যানিমেশন শুরু করুন

LaunchedEffect চলে যখন একটি কম্পোজেবল কম্পোজিশনে প্রবেশ করে। এটি একটি কম্পোজেবল চালু করার সময় একটি অ্যানিমেশন শুরু করে, আপনি অ্যানিমেশনের অবস্থা পরিবর্তন করতে এটি ব্যবহার করতে পারেন। লঞ্চে অ্যানিমেশন শুরু করতে animateTo পদ্ধতির সাথে Animatable ব্যবহার করুন:

val alphaAnimation = remember {
    Animatable(0f)
}
LaunchedEffect(Unit) {
    alphaAnimation.animateTo(1f)
}
Box(
    modifier = Modifier.graphicsLayer {
        alpha = alphaAnimation.value
    }
)

ক্রমিক অ্যানিমেশন তৈরি করুন

সবুজ তীর সহ চারটি চেনাশোনা প্রতিটির মধ্যে অ্যানিমেট করছে, একের পর এক অ্যানিমেট করছে।
চিত্র 14. একটি অনুক্রমিক অ্যানিমেশন কীভাবে একের পর এক অগ্রসর হয় তা নির্দেশ করে চিত্র।

অনুক্রমিক বা সমসাময়িক অ্যানিমেশনগুলি সম্পাদন করতে Animatable কোরোটিন API ব্যবহার করুন। Animatable একের পর এক animateTo কল করার ফলে প্রতিটি অ্যানিমেশন এগিয়ে যাওয়ার আগে পূর্ববর্তী অ্যানিমেশনগুলি শেষ হওয়ার জন্য অপেক্ষা করে। কারণ এটি একটি সাসপেন্ড ফাংশন।

val alphaAnimation = remember { Animatable(0f) }
val yAnimation = remember { Animatable(0f) }

LaunchedEffect("animationKey") {
    alphaAnimation.animateTo(1f)
    yAnimation.animateTo(100f)
    yAnimation.animateTo(500f, animationSpec = tween(100))
}

সমসাময়িক অ্যানিমেশন তৈরি করুন

সবুজ তীর সহ তিনটি চেনাশোনা প্রতিটিতে অ্যানিমেট করছে, একই সময়ে সবগুলিকে অ্যানিমেট করছে৷
চিত্র 15. ডায়াগ্রামটি নির্দেশ করে কিভাবে সমসাময়িক অ্যানিমেশনগুলি একই সময়ে অগ্রসর হয়।

সমসাময়িক অ্যানিমেশনগুলি অর্জন করতে coroutine APIs ( Animatable#animateTo() বা animate ), বা Transition API ব্যবহার করুন৷ আপনি যদি কোরোটিন প্রসঙ্গে একাধিক লঞ্চ ফাংশন ব্যবহার করেন, তবে এটি একই সময়ে অ্যানিমেশনগুলি চালু করে:

val alphaAnimation = remember { Animatable(0f) }
val yAnimation = remember { Animatable(0f) }

LaunchedEffect("animationKey") {
    launch {
        alphaAnimation.animateTo(1f)
    }
    launch {
        yAnimation.animateTo(100f)
    }
}

আপনি একই সময়ে বিভিন্ন সম্পত্তি অ্যানিমেশন চালানোর জন্য একই অবস্থা ব্যবহার করতে updateTransition API ব্যবহার করতে পারেন। নীচের উদাহরণটি রাষ্ট্রীয় পরিবর্তন, rect এবং borderWidth দ্বারা নিয়ন্ত্রিত দুটি বৈশিষ্ট্যকে অ্যানিমেট করে:

var currentState by remember { mutableStateOf(BoxState.Collapsed) }
val transition = updateTransition(currentState, label = "transition")

val rect by transition.animateRect(label = "rect") { state ->
    when (state) {
        BoxState.Collapsed -> Rect(0f, 0f, 100f, 100f)
        BoxState.Expanded -> Rect(100f, 100f, 300f, 300f)
    }
}
val borderWidth by transition.animateDp(label = "borderWidth") { state ->
    when (state) {
        BoxState.Collapsed -> 1.dp
        BoxState.Expanded -> 0.dp
    }
}

অ্যানিমেশন কর্মক্ষমতা অপ্টিমাইজ করুন

কম্পোজে অ্যানিমেশন কর্মক্ষমতা সমস্যা সৃষ্টি করতে পারে। এটি একটি অ্যানিমেশনের প্রকৃতির কারণে: স্ক্রিনে পিক্সেলগুলি দ্রুত সরানো বা পরিবর্তন করা, নড়াচড়ার বিভ্রম তৈরি করতে ফ্রেম-বাই-ফ্রেম।

রচনার বিভিন্ন ধাপ বিবেচনা করুন: রচনা, বিন্যাস এবং অঙ্কন। যদি আপনার অ্যানিমেশন লেআউট ফেজ পরিবর্তন করে, তাহলে রিলেআউট এবং পুনরায় আঁকার জন্য সমস্ত প্রভাবিত কম্পোজেবল প্রয়োজন। যদি আপনার অ্যানিমেশনটি ড্র পর্বে ঘটে থাকে, তবে এটি ডিফল্টভাবে আপনি যদি লেআউট পর্বে অ্যানিমেশন চালাতে চান তার চেয়ে বেশি পারফরম্যান্স হবে, কারণ এতে সামগ্রিকভাবে কম কাজ করতে হবে।

অ্যানিমেট করার সময় আপনার অ্যাপ যতটা সম্ভব কম করে তা নিশ্চিত করতে, যেখানে সম্ভব সেখানে একটি Modifier ল্যাম্বডা সংস্করণ বেছে নিন। এটি পুনর্গঠন এড়িয়ে যায় এবং কম্পোজিশন পর্বের বাইরে অ্যানিমেশন সম্পাদন করে, অন্যথায় Modifier.graphicsLayer{ } ব্যবহার করুন, কারণ এই মডিফায়ারটি সবসময় ড্র পর্বে চলে। এই বিষয়ে আরও তথ্যের জন্য, কর্মক্ষমতা ডকুমেন্টেশনে ডিফারিং রিডস বিভাগটি দেখুন।

অ্যানিমেশনের সময় পরিবর্তন করুন

বেশিরভাগ অ্যানিমেশনের জন্য ডিফল্টভাবে কম্পোজ স্প্রিং অ্যানিমেশন ব্যবহার করে। স্প্রিংস, বা পদার্থবিদ্যা-ভিত্তিক অ্যানিমেশনগুলি আরও প্রাকৃতিক অনুভব করে। তারা একটি নির্দিষ্ট সময়ের পরিবর্তে বস্তুর বর্তমান বেগ বিবেচনায় নেওয়ায় বাধাযোগ্য। আপনি যদি ডিফল্টটি ওভাররাইড করতে চান তবে উপরে প্রদর্শিত সমস্ত অ্যানিমেশন এপিআইগুলির একটি অ্যানিমেশন কীভাবে চালিত হয় তা কাস্টমাইজ করার জন্য একটি animationSpec সেট করার ক্ষমতা রয়েছে, আপনি এটি একটি নির্দিষ্ট সময়কালের জন্য কার্যকর করতে চান বা আরও বাউন্সি হতে চান।

নীচে বিভিন্ন animationSpec বিকল্পগুলির সংক্ষিপ্তসার রয়েছে:

  • spring : পদার্থবিজ্ঞান ভিত্তিক অ্যানিমেশন, সমস্ত অ্যানিমেশনগুলির জন্য ডিফল্ট। আলাদা অ্যানিমেশন চেহারা এবং অনুভূতি অর্জন করতে আপনি কঠোরতা বা স্যাঁতসেঁতে বা স্যাঁতসেঁতে পরিবর্তন করতে পারেন।
  • tween ( এর মধ্যে সংক্ষিপ্ত): সময়কাল-ভিত্তিক অ্যানিমেশন, একটি Easing ফাংশন সহ দুটি মানের মধ্যে অ্যানিমেট করে।
  • keyframes : অ্যানিমেশনে নির্দিষ্ট কী পয়েন্টগুলিতে মান নির্দিষ্ট করার জন্য স্পেস।
  • repeatable : সময়কাল-ভিত্তিক স্পেক যা নির্দিষ্ট সংখ্যক বার চালায়, RepeatMode দ্বারা নির্দিষ্ট করা হয়।
  • infiniteRepeatable : সময়কাল ভিত্তিক স্পেক যা চিরকাল চলে।
  • snap : তাত্ক্ষণিকভাবে কোনও অ্যানিমেশন ছাড়াই শেষ মানটিতে স্ন্যাপ করে।
আপনার Alt পাঠ্য এখানে লিখুন
চিত্র 16. কোনও স্পেস সেট বনাম কাস্টম স্প্রিং স্পেস সেট

অ্যানিমেশনসপেকগুলি সম্পর্কে আরও তথ্যের জন্য সম্পূর্ণ ডকুমেন্টেশন পড়ুন।

অতিরিক্ত সম্পদ

রচনাটিতে মজাদার অ্যানিমেশনগুলির আরও উদাহরণের জন্য, নিম্নলিখিতটি একবার দেখুন:

,

রচনাটিতে অনেকগুলি অন্তর্নির্মিত অ্যানিমেশন প্রক্রিয়া রয়েছে এবং কোনটি বেছে নেওয়া উচিত তা জানতে পেরে এটি অপ্রতিরোধ্য হতে পারে। নীচে সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রে একটি তালিকা রয়েছে। আপনার কাছে উপলব্ধ বিভিন্ন এপিআই বিকল্পগুলির সম্পূর্ণ সেট সম্পর্কে আরও বিশদ তথ্যের জন্য, সম্পূর্ণ রচনা অ্যানিমেশন ডকুমেন্টেশন পড়ুন।

সাধারণ কমপোজেবল বৈশিষ্ট্যগুলি অ্যানিমেটেড

রচনাটি সুবিধাজনক এপিআই সরবরাহ করে যা আপনাকে অনেকগুলি সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রে সমাধান করতে দেয়। এই বিভাগটি দেখায় যে আপনি কীভাবে একটি কম্পোজেবলের সাধারণ বৈশিষ্ট্যগুলি সঞ্চার করতে পারেন।

অ্যানিমেট উপস্থিত / অদৃশ্য

সবুজ কমপোজেবল নিজেকে দেখানো এবং লুকিয়ে রাখা
চিত্র 1. একটি কলামে কোনও আইটেমের উপস্থিতি এবং নিখোঁজ হওয়া অ্যানিমেটেড

একটি কমপোজেবল আড়াল বা প্রদর্শন করতে AnimatedVisibility ব্যবহার করুন। AnimatedVisibility অভ্যন্তরীণ শিশুরা তাদের নিজস্ব এন্টার বা প্রস্থান ট্রানজিশনের জন্য Modifier.animateEnterExit() ব্যবহার করতে পারে।

var visible by remember {
    mutableStateOf(true)
}
// Animated visibility will eventually remove the item from the composition once the animation has finished.
AnimatedVisibility(visible) {
    // your composable here
    // ...
}

AnimatedVisibility এন্টার এবং প্রস্থান পরামিতিগুলি আপনাকে যখন কোনও কম্পোজেবল প্রদর্শিত হয় এবং অদৃশ্য হয়ে যায় তখন কীভাবে আচরণ করে তা কনফিগার করতে দেয়। আরও তথ্যের জন্য সম্পূর্ণ ডকুমেন্টেশন পড়ুন।

একটি কম্পোজেবলের দৃশ্যমানতা অ্যানিমেট করার জন্য আরেকটি বিকল্প হ'ল animateFloatAsState ব্যবহার করে সময়ের সাথে আলফা অ্যানিমেট করা:

var visible by remember {
    mutableStateOf(true)
}
val animatedAlpha by animateFloatAsState(
    targetValue = if (visible) 1.0f else 0f,
    label = "alpha"
)
Box(
    modifier = Modifier
        .size(200.dp)
        .graphicsLayer {
            alpha = animatedAlpha
        }
        .clip(RoundedCornerShape(8.dp))
        .background(colorGreen)
        .align(Alignment.TopCenter)
) {
}

যাইহোক, আলফা পরিবর্তন করা সাবধানতার সাথে আসে যে কম্পোজেবলটি রচনাটিতে থাকে এবং এটি যে স্থানটি স্থাপন করা হয় তা দখল করে চলেছে This এটি স্ক্রিন পাঠক এবং অন্যান্য অ্যাক্সেসিবিলিটি প্রক্রিয়াগুলি এখনও স্ক্রিনের আইটেমটি বিবেচনা করতে পারে। অন্যদিকে, AnimatedVisibility অবশেষে আইটেমটি রচনা থেকে সরিয়ে দেয়।

একটি কমপোজেবলের আলফা অ্যানিমেটিং
চিত্র 2. একটি কমপোজেবলের আলফা অ্যানিমেটেড

অ্যানিমেট ব্যাকগ্রাউন্ড রঙ

অ্যানিমেশন হিসাবে সময়ের সাথে সাথে পটভূমির রঙ পরিবর্তনের সাথে কমপোজেবল, যেখানে রঙগুলি একে অপরের মধ্যে বিবর্ণ হচ্ছে।
চিত্র 3. কমপোজেবলের পটভূমি রঙ অ্যানিমেটেড

val animatedColor by animateColorAsState(
    if (animateBackgroundColor) colorGreen else colorBlue,
    label = "color"
)
Column(
    modifier = Modifier.drawBehind {
        drawRect(animatedColor)
    }
) {
    // your composable here
}

এই বিকল্পটি Modifier.background() ব্যবহারের চেয়ে বেশি পারফরম্যান্ট। Modifier.background() এক-শট রঙের সেটিংয়ের জন্য গ্রহণযোগ্য, তবে সময়ের সাথে সাথে কোনও রঙ অ্যানিমেট করার সময়, এটি প্রয়োজনের চেয়ে আরও বেশি পুনঃনির্মাণের কারণ হতে পারে।

পটভূমির রঙ অসীমভাবে অ্যানিমেট করার জন্য, একটি অ্যানিমেশন বিভাগ পুনরাবৃত্তি দেখুন।

একটি কম্পোজেবল আকার অ্যানিমেট

সবুজ কমপোজেবল এর আকার পরিবর্তনটি সুচারুভাবে অ্যানিমেট করে।
চিত্র 4. একটি ছোট এবং বৃহত্তর আকারের মধ্যে কমপোজেবল সহজেই অ্যানিমেটিং

রচনা আপনাকে কয়েকটি ভিন্ন উপায়ে কমপোজেবলের আকার অ্যানিমেট করতে দেয়। কমপোজেবল আকার পরিবর্তনের মধ্যে অ্যানিমেশনগুলির জন্য animateContentSize() ব্যবহার করুন।

উদাহরণস্বরূপ, যদি আপনার কাছে এমন একটি বাক্স থাকে যাতে পাঠ্য থাকে যা এক থেকে একাধিক লাইনে প্রসারিত করতে পারে আপনি Modifier.animateContentSize() ব্যবহার করতে পারেন e

var expanded by remember { mutableStateOf(false) }
Box(
    modifier = Modifier
        .background(colorBlue)
        .animateContentSize()
        .height(if (expanded) 400.dp else 200.dp)
        .fillMaxWidth()
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            expanded = !expanded
        }

) {
}

আকার পরিবর্তন কিভাবে ঘটতে হবে তা বর্ণনা করতে আপনি একটি SizeTransform সহ AnimatedContent ব্যবহার করতে পারেন।

কমপোজেবলের অ্যানিমেট অবস্থান

সবুজ কমপোজেবল মসৃণভাবে অ্যানিমেটিং ডাউন এবং ডানদিকে
চিত্র 5. একটি অফসেট দ্বারা কমপোজেবল মুভিং

একটি কমপোজেবলের অবস্থান সঞ্চার করতে, Modifier.offset{ } animateIntOffsetAsState() এর সাথে মিলিত ব্যবহার করুন।

var moved by remember { mutableStateOf(false) }
val pxToMove = with(LocalDensity.current) {
    100.dp.toPx().roundToInt()
}
val offset by animateIntOffsetAsState(
    targetValue = if (moved) {
        IntOffset(pxToMove, pxToMove)
    } else {
        IntOffset.Zero
    },
    label = "offset"
)

Box(
    modifier = Modifier
        .offset {
            offset
        }
        .background(colorBlue)
        .size(100.dp)
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            moved = !moved
        }
)

আপনি যদি নিশ্চিত করতে চান যে অবস্থান বা আকার অ্যানিমেট করার সময় কমপোজেবলগুলি অন্য কমপোজেবলের উপরে বা এর অধীনে আঁকা না হয় তবে Modifier.layout{ } এই সংশোধক পিতামাতার আকার এবং অবস্থানের পরিবর্তনগুলি প্রচার করে, যা পরে অন্যান্য শিশুদের প্রভাবিত করে।

উদাহরণস্বরূপ, আপনি যদি কোনও Column মধ্যে একটি Box সরিয়ে নিচ্ছেন এবং Box সরানোর সময় অন্যান্য বাচ্চাদের সরানো দরকার, Modifier.layout{ }

var toggled by remember {
    mutableStateOf(false)
}
val interactionSource = remember {
    MutableInteractionSource()
}
Column(
    modifier = Modifier
        .padding(16.dp)
        .fillMaxSize()
        .clickable(indication = null, interactionSource = interactionSource) {
            toggled = !toggled
        }
) {
    val offsetTarget = if (toggled) {
        IntOffset(150, 150)
    } else {
        IntOffset.Zero
    }
    val offset = animateIntOffsetAsState(
        targetValue = offsetTarget, label = "offset"
    )
    Box(
        modifier = Modifier
            .size(100.dp)
            .background(colorBlue)
    )
    Box(
        modifier = Modifier
            .layout { measurable, constraints ->
                val offsetValue = if (isLookingAhead) offsetTarget else offset.value
                val placeable = measurable.measure(constraints)
                layout(placeable.width + offsetValue.x, placeable.height + offsetValue.y) {
                    placeable.placeRelative(offsetValue)
                }
            }
            .size(100.dp)
            .background(colorGreen)
    )
    Box(
        modifier = Modifier
            .size(100.dp)
            .background(colorBlue)
    )
}

২ য় বাক্সের সাথে 2 টি বাক্স তার x, y অবস্থানকে অ্যানিমেট করে, তৃতীয় বাক্সটি y পরিমাণ দ্বারা নিজেকে সরিয়ে নিয়ে প্রতিক্রিয়া জানায়।
চিত্র 6. Modifier.layout{ }

একটি কমপোজেবলের প্যাডিং অ্যানিমেট

প্যাডিং অ্যানিমেটেড হওয়ায় ক্লিকে আরও ছোট এবং আরও বড় হয়ে উঠছে সবুজ কমপোজেবল
চিত্র 7. এর প্যাডিং অ্যানিমেটিং সহ কমপোজেবল

একটি কমপোজেবলের প্যাডিং অ্যানিমেট করতে, Modifier.padding() এর সাথে মিলিত animateDpAsState ব্যবহার করুন:

var toggled by remember {
    mutableStateOf(false)
}
val animatedPadding by animateDpAsState(
    if (toggled) {
        0.dp
    } else {
        20.dp
    },
    label = "padding"
)
Box(
    modifier = Modifier
        .aspectRatio(1f)
        .fillMaxSize()
        .padding(animatedPadding)
        .background(Color(0xff53D9A1))
        .clickable(
            interactionSource = remember { MutableInteractionSource() },
            indication = null
        ) {
            toggled = !toggled
        }
)

একটি কমপোজেবলের উচ্চতা সঞ্চারিত

চিত্র 8. ক্লিক এ কমপোজেবলের উচ্চতা অ্যানিমেটিং

একটি কমপোজেবলের উচ্চতা সঞ্চার করতে, Modifier.graphicsLayer{ } এর সাথে মিলিত animateDpAsState ব্যবহার করুন} একবারের উচ্চতা পরিবর্তনের জন্য, Modifier.shadow() ব্যবহার করুন। আপনি যদি ছায়া অ্যানিমেট করে থাকেন তবে Modifier.graphicsLayer{ }

val mutableInteractionSource = remember {
    MutableInteractionSource()
}
val pressed = mutableInteractionSource.collectIsPressedAsState()
val elevation = animateDpAsState(
    targetValue = if (pressed.value) {
        32.dp
    } else {
        8.dp
    },
    label = "elevation"
)
Box(
    modifier = Modifier
        .size(100.dp)
        .align(Alignment.Center)
        .graphicsLayer {
            this.shadowElevation = elevation.value.toPx()
        }
        .clickable(interactionSource = mutableInteractionSource, indication = null) {
        }
        .background(colorGreen)
) {
}

বিকল্পভাবে, Card কমপোজেবল ব্যবহার করুন এবং উচ্চতা সম্পত্তিটি প্রতি রাজ্যে বিভিন্ন মানগুলিতে সেট করুন।

অ্যানিমেট পাঠ্য স্কেল, অনুবাদ বা ঘূর্ণন

পাঠ্য কমপোজেবল কথা
চিত্র 9. পাঠ্য দুটি আকারের মধ্যে মসৃণভাবে অ্যানিমেটিং

অ্যানিমেটিং স্কেল, অনুবাদ বা পাঠ্যের ঘূর্ণন করার সময়, TextMotion.Animated textMotion প্যারামিটারটি TextStyle সেট করুন। এটি পাঠ্য অ্যানিমেশনগুলির মধ্যে মসৃণ রূপান্তর নিশ্চিত করে। পাঠ্যটি অনুবাদ, ঘোরানো বা স্কেল করতে Modifier.graphicsLayer{ } ব্যবহার করুন।

val infiniteTransition = rememberInfiniteTransition(label = "infinite transition")
val scale by infiniteTransition.animateFloat(
    initialValue = 1f,
    targetValue = 8f,
    animationSpec = infiniteRepeatable(tween(1000), RepeatMode.Reverse),
    label = "scale"
)
Box(modifier = Modifier.fillMaxSize()) {
    Text(
        text = "Hello",
        modifier = Modifier
            .graphicsLayer {
                scaleX = scale
                scaleY = scale
                transformOrigin = TransformOrigin.Center
            }
            .align(Alignment.Center),
        // Text composable does not take TextMotion as a parameter.
        // Provide it via style argument but make sure that we are copying from current theme
        style = LocalTextStyle.current.copy(textMotion = TextMotion.Animated)
    )
}

পাঠ্য রঙ অ্যানিমেট

শব্দ
চিত্র 10. উদাহরণ অ্যানিমেটিং পাঠ্য রঙ দেখানো হচ্ছে

পাঠ্য রঙ সঞ্চার করতে, BasicText কমপোজেবলের color ল্যাম্বডা ব্যবহার করুন:

val infiniteTransition = rememberInfiniteTransition(label = "infinite transition")
val animatedColor by infiniteTransition.animateColor(
    initialValue = Color(0xFF60DDAD),
    targetValue = Color(0xFF4285F4),
    animationSpec = infiniteRepeatable(tween(1000), RepeatMode.Reverse),
    label = "color"
)

BasicText(
    text = "Hello Compose",
    color = {
        animatedColor
    },
    // ...
)

বিভিন্ন ধরণের সামগ্রীর মধ্যে স্যুইচ করুন

সবুজ পর্দা বলছে
চিত্র 11. বিভিন্ন কম্পোজেবলের মধ্যে পরিবর্তনগুলি অ্যানিমেটেড করতে অ্যানিমেটেড কনটেন্ট ব্যবহার করা (ধীর হয়ে গেছে)

বিভিন্ন কম্পোজেবলের মধ্যে AnimatedContent ব্যবহার করুন, আপনি যদি কেবল কমপোজেবলগুলির মধ্যে একটি স্ট্যান্ডার্ড ফেইড চান তবে Crossfade ব্যবহার করুন।

var state by remember {
    mutableStateOf(UiState.Loading)
}
AnimatedContent(
    state,
    transitionSpec = {
        fadeIn(
            animationSpec = tween(3000)
        ) togetherWith fadeOut(animationSpec = tween(3000))
    },
    modifier = Modifier.clickable(
        interactionSource = remember { MutableInteractionSource() },
        indication = null
    ) {
        state = when (state) {
            UiState.Loading -> UiState.Loaded
            UiState.Loaded -> UiState.Error
            UiState.Error -> UiState.Loading
        }
    },
    label = "Animated Content"
) { targetState ->
    when (targetState) {
        UiState.Loading -> {
            LoadingScreen()
        }
        UiState.Loaded -> {
            LoadedScreen()
        }
        UiState.Error -> {
            ErrorScreen()
        }
    }
}

AnimatedContent বিভিন্ন ধরণের এন্টার এবং প্রস্থান ট্রানজিশনগুলি দেখানোর জন্য কাস্টমাইজ করা যেতে পারে। আরও তথ্যের জন্য, AnimatedContent কনটেন্টে ডকুমেন্টেশনটি পড়ুন বা AnimatedContent কনটেন্টে এই ব্লগ পোস্টটি পড়ুন।

বিভিন্ন গন্তব্যে নেভিগেট করার সময় অ্যানিমেট

দুটি কম্পোজেবল, একটি সবুজ ল্যান্ডিং এবং একটি নীল বলার বিশদ বিবরণ, অবতরণ কমপোজেবলের উপর বিশদটি কমপোজেবল স্লাইড করে অ্যানিমেট করে।
চিত্র 12. নেভিগেশন-কমপোজ ব্যবহার করে কম্পোজেবলগুলির মধ্যে অ্যানিমেটিং

নেভিগেশন-কমপোজ আর্টিফ্যাক্ট ব্যবহার করার সময় কম্পোজেবলগুলির মধ্যে রূপান্তরগুলি সঞ্চারিত করতে, একটি কমপোজেবলের উপর enterTransition এবং exitTransition নির্দিষ্ট করুন। আপনি শীর্ষ স্তরের NavHost সমস্ত গন্তব্যগুলির জন্য ব্যবহার করতে ডিফল্ট অ্যানিমেশনটি সেট করতে পারেন:

val navController = rememberNavController()
NavHost(
    navController = navController, startDestination = "landing",
    enterTransition = { EnterTransition.None },
    exitTransition = { ExitTransition.None }
) {
    composable("landing") {
        ScreenLanding(
            // ...
        )
    }
    composable(
        "detail/{photoUrl}",
        arguments = listOf(navArgument("photoUrl") { type = NavType.StringType }),
        enterTransition = {
            fadeIn(
                animationSpec = tween(
                    300, easing = LinearEasing
                )
            ) + slideIntoContainer(
                animationSpec = tween(300, easing = EaseIn),
                towards = AnimatedContentTransitionScope.SlideDirection.Start
            )
        },
        exitTransition = {
            fadeOut(
                animationSpec = tween(
                    300, easing = LinearEasing
                )
            ) + slideOutOfContainer(
                animationSpec = tween(300, easing = EaseOut),
                towards = AnimatedContentTransitionScope.SlideDirection.End
            )
        }
    ) { backStackEntry ->
        ScreenDetails(
            // ...
        )
    }
}

অনেকগুলি বিভিন্ন ধরণের প্রবেশ এবং প্রস্থান ট্রানজিশন রয়েছে যা আগত এবং বহির্গামী সামগ্রীতে বিভিন্ন প্রভাব প্রয়োগ করে, আরও বেশি ডকুমেন্টেশন দেখুন।

একটি অ্যানিমেশন পুনরাবৃত্তি

একটি সবুজ পটভূমি যা দুটি রঙের মধ্যে অ্যানিমেট করে অসীমভাবে নীল পটভূমিতে রূপান্তরিত হয়।
চিত্র 13. দুটি মানের মধ্যে পটভূমি রঙ অ্যানিমেটিং, অসীমভাবে

অবিচ্ছিন্নভাবে আপনার অ্যানিমেশনটি পুনরাবৃত্তি করতে একটি infiniteRepeatable animationSpec সহ rememberInfiniteTransition ব্যবহার করুন। এটি কীভাবে পিছনে যেতে হবে তা নির্দিষ্ট করতে RepeatModes পরিবর্তন করুন।

একটি সেট সংখ্যার পুনরাবৃত্তি করতে finiteRepeatable ব্যবহার করুন।

val infiniteTransition = rememberInfiniteTransition(label = "infinite")
val color by infiniteTransition.animateColor(
    initialValue = Color.Green,
    targetValue = Color.Blue,
    animationSpec = infiniteRepeatable(
        animation = tween(1000, easing = LinearEasing),
        repeatMode = RepeatMode.Reverse
    ),
    label = "color"
)
Column(
    modifier = Modifier.drawBehind {
        drawRect(color)
    }
) {
    // your composable here
}

একটি কমপোজেবল চালু করার সময় একটি অ্যানিমেশন শুরু করুন

যখন কোনও কমপোজেবল রচনাটিতে প্রবেশ করে তখন LaunchedEffect চলে। এটি একটি কমপোজেবলের প্রবর্তনের সময় একটি অ্যানিমেশন শুরু করে, আপনি এটি অ্যানিমেশন রাষ্ট্র পরিবর্তন চালাতে ব্যবহার করতে পারেন। লঞ্চে অ্যানিমেশন শুরু করতে animateTo পদ্ধতির সাথে Animatable ব্যবহার করে:

val alphaAnimation = remember {
    Animatable(0f)
}
LaunchedEffect(Unit) {
    alphaAnimation.animateTo(1f)
}
Box(
    modifier = Modifier.graphicsLayer {
        alpha = alphaAnimation.value
    }
)

ক্রমিক অ্যানিমেশন তৈরি করুন

প্রত্যেকের মধ্যে সবুজ তীর সহ চারটি চেনাশোনা, একে অপরের পরে একে একে অ্যানিমেট করে।
চিত্র 14. ডায়াগ্রামটি নির্দেশ করে যে কীভাবে একটি ক্রমিক অ্যানিমেশনটি একের পর এক অগ্রসর হয়।

অনুক্রমিক বা সমবর্তী অ্যানিমেশনগুলি সম্পাদন করতে Animatable করুটাইন এপিআই ব্যবহার করুন। অন্যের পরে Animatable উপর animateTo কল করা প্রতিটি অ্যানিমেশনটি পূর্ববর্তী অ্যানিমেশনগুলি এগিয়ে যাওয়ার আগে শেষ হওয়ার জন্য অপেক্ষা করে। এটি কারণ এটি একটি স্থগিত ফাংশন।

val alphaAnimation = remember { Animatable(0f) }
val yAnimation = remember { Animatable(0f) }

LaunchedEffect("animationKey") {
    alphaAnimation.animateTo(1f)
    yAnimation.animateTo(100f)
    yAnimation.animateTo(500f, animationSpec = tween(100))
}

একযোগে অ্যানিমেশন তৈরি করুন

সবুজ তীর সহ তিনটি চেনাশোনা প্রত্যেককে অ্যানিমেটিং করে, একই সাথে সমস্ত একসাথে অ্যানিমেট করে।
চিত্র 15. ডায়াগ্রামটি নির্দেশ করে যে কীভাবে একযোগে অ্যানিমেশনগুলি একই সাথে অগ্রসর হয়।

একযোগে অ্যানিমেশনগুলি অর্জনের জন্য করুটাইন এপিআই ( Animatable#animateTo() বা animate ), বা Transition এপিআই ব্যবহার করুন। আপনি যদি কোনও করুটাইন প্রসঙ্গে একাধিক লঞ্চ ফাংশন ব্যবহার করেন তবে এটি একই সাথে অ্যানিমেশনগুলি চালু করে:

val alphaAnimation = remember { Animatable(0f) }
val yAnimation = remember { Animatable(0f) }

LaunchedEffect("animationKey") {
    launch {
        alphaAnimation.animateTo(1f)
    }
    launch {
        yAnimation.animateTo(100f)
    }
}

আপনি একই সময়ে অনেকগুলি বিভিন্ন সম্পত্তি অ্যানিমেশন চালানোর জন্য একই রাজ্যটি ব্যবহার করতে updateTransition এপিআই ব্যবহার করতে পারেন। নীচের উদাহরণটি রাষ্ট্রীয় পরিবর্তন, rect এবং borderWidth দ্বারা নিয়ন্ত্রিত দুটি বৈশিষ্ট্যকে অ্যানিমেট করে:

var currentState by remember { mutableStateOf(BoxState.Collapsed) }
val transition = updateTransition(currentState, label = "transition")

val rect by transition.animateRect(label = "rect") { state ->
    when (state) {
        BoxState.Collapsed -> Rect(0f, 0f, 100f, 100f)
        BoxState.Expanded -> Rect(100f, 100f, 300f, 300f)
    }
}
val borderWidth by transition.animateDp(label = "borderWidth") { state ->
    when (state) {
        BoxState.Collapsed -> 1.dp
        BoxState.Expanded -> 0.dp
    }
}

অ্যানিমেশন কর্মক্ষমতা অনুকূলিত করুন

কমপোজে অ্যানিমেশনগুলি পারফরম্যান্স সমস্যার কারণ হতে পারে। এটি অ্যানিমেশন কী তা প্রকৃতির কারণে: স্ক্রিনে পিক্সেলগুলি দ্রুত চলা বা পরিবর্তন করা, চলাচলের মায়া তৈরি করতে ফ্রেম বাই ফ্রেম।

রচনার বিভিন্ন পর্যায়গুলি বিবেচনা করুন: রচনা, বিন্যাস এবং অঙ্কন। যদি আপনার অ্যানিমেশনটি বিন্যাসের পর্যায়ে পরিবর্তন করে তবে এটির জন্য রিলেআউট এবং রেড্রাওর জন্য সমস্ত প্রভাবিত কমপোজেবলের প্রয়োজন। যদি আপনার অ্যানিমেশনটি ড্র পর্যায়ে ঘটে থাকে তবে আপনি যদি লেআউট পর্যায়ে অ্যানিমেশনটি চালাবেন তবে এটি ডিফল্টরূপে আরও বেশি পারফরম্যান্স হতে পারে, কারণ সামগ্রিকভাবে এটি করার মতো কাজ কম হবে।

অ্যানিমেট করার সময় আপনার অ্যাপ্লিকেশনটি যথাসম্ভব কম কাজ করে তা নিশ্চিত করার জন্য, যেখানে সম্ভব সেখানে কোনও Modifier ল্যাম্বদা সংস্করণ চয়ন করুন। এটি পুনরুদ্ধারটি এড়িয়ে যায় এবং রচনা পর্বের বাইরে অ্যানিমেশন সম্পাদন করে, অন্যথায় Modifier.graphicsLayer{ } ব্যবহার করুন, কারণ এই সংশোধকটি সর্বদা অঙ্কন পর্যায়ে চলে। এ সম্পর্কে আরও তথ্যের জন্য, পারফরম্যান্স ডকুমেন্টেশনে ডিফারিং রিডস বিভাগটি দেখুন।

অ্যানিমেশন সময় পরিবর্তন করুন

ডিফল্টরূপে রচনা বেশিরভাগ অ্যানিমেশনগুলির জন্য স্প্রিং অ্যানিমেশন ব্যবহার করে। স্প্রিংস, বা পদার্থবিজ্ঞান ভিত্তিক অ্যানিমেশনগুলি আরও প্রাকৃতিক বোধ করে। তারা নির্দিষ্ট সময়ের পরিবর্তে অবজেক্টের বর্তমান বেগকে বিবেচনায় নেওয়ার সাথে সাথে এগুলিও বাধাগ্রস্ত হয়। আপনি যদি ডিফল্টটি ওভাররাইড করতে চান তবে উপরে প্রদর্শিত সমস্ত অ্যানিমেশন এপিআইগুলির একটি অ্যানিমেশন কীভাবে চালিত হয় তা কাস্টমাইজ করার জন্য একটি animationSpec সেট করার ক্ষমতা রয়েছে, আপনি এটি একটি নির্দিষ্ট সময়কালের জন্য কার্যকর করতে চান বা আরও বাউন্সি হতে চান।

নীচে বিভিন্ন animationSpec বিকল্পগুলির সংক্ষিপ্তসার রয়েছে:

  • spring : পদার্থবিজ্ঞান ভিত্তিক অ্যানিমেশন, সমস্ত অ্যানিমেশনগুলির জন্য ডিফল্ট। আলাদা অ্যানিমেশন চেহারা এবং অনুভূতি অর্জন করতে আপনি কঠোরতা বা স্যাঁতসেঁতে বা স্যাঁতসেঁতে পরিবর্তন করতে পারেন।
  • tween ( এর মধ্যে সংক্ষিপ্ত): সময়কাল-ভিত্তিক অ্যানিমেশন, একটি Easing ফাংশন সহ দুটি মানের মধ্যে অ্যানিমেট করে।
  • keyframes : অ্যানিমেশনে নির্দিষ্ট কী পয়েন্টগুলিতে মান নির্দিষ্ট করার জন্য স্পেস।
  • repeatable : সময়কাল-ভিত্তিক স্পেক যা নির্দিষ্ট সংখ্যক বার চালায়, RepeatMode দ্বারা নির্দিষ্ট করা হয়।
  • infiniteRepeatable : সময়কাল ভিত্তিক স্পেক যা চিরকাল চলে।
  • snap : তাত্ক্ষণিকভাবে কোনও অ্যানিমেশন ছাড়াই শেষ মানটিতে স্ন্যাপ করে।
আপনার Alt পাঠ্য এখানে লিখুন
চিত্র 16. কোনও স্পেস সেট বনাম কাস্টম স্প্রিং স্পেস সেট

অ্যানিমেশনসপেকগুলি সম্পর্কে আরও তথ্যের জন্য সম্পূর্ণ ডকুমেন্টেশন পড়ুন।

অতিরিক্ত সম্পদ

রচনাটিতে মজাদার অ্যানিমেশনগুলির আরও উদাহরণের জন্য, নিম্নলিখিতটি একবার দেখুন: