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

সাধারণ অ্যানিমেশন ব্যবহারের জন্য Compose-এ বিল্ট-ইন কম্পোজেবল এবং মডিফায়ার রয়েছে।

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

Compose-এ এমন বেশ কিছু কম্পোজেবল রয়েছে যা কন্টেন্টের আবির্ভাব, অদৃশ্য হওয়া এবং লেআউটের পরিবর্তনকে অ্যানিমেট করে।

সজীব আবির্ভাব ও অন্তর্ধান

সবুজ রচনাযোগ্য নিজেকে প্রকাশ ও গোপন করছে
চিত্র ১. একটি কলামে কোনো আইটেমের আবির্ভাব ও অদৃশ্য হওয়ার অ্যানিমেশন।

AnimatedVisibility কম্পোজেবলটি এর বিষয়বস্তুর আবির্ভাব ও অন্তর্ধানকে অ্যানিমেট করে।

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
    // ...
}

ডিফল্টরূপে, কন্টেন্টটি ধীরে ধীরে ভেসে ওঠে ও প্রসারিত হয় এবং ধীরে ধীরে মিলিয়ে গিয়ে ও সংকুচিত হয়ে অদৃশ্য হয়। EnterTransition এবং ExitTransition অবজেক্ট নির্দিষ্ট করে এই ট্রানজিশনটি কাস্টমাইজ করুন।

var visible by remember { mutableStateOf(true) }
val density = LocalDensity.current
AnimatedVisibility(
    visible = visible,
    enter = slideInVertically {
        // Slide in from 40 dp from the top.
        with(density) { -40.dp.roundToPx() }
    } + expandVertically(
        // Expand from the top.
        expandFrom = Alignment.Top
    ) + fadeIn(
        // Fade in with the initial alpha of 0.3f.
        initialAlpha = 0.3f
    ),
    exit = slideOutVertically() + shrinkVertically() + fadeOut()
) {
    Text(
        "Hello",
        Modifier
            .fillMaxWidth()
            .height(200.dp)
    )
}

পূর্ববর্তী উদাহরণে যেমন দেখানো হয়েছে, আপনি একটি + অপারেটর ব্যবহার করে একাধিক EnterTransition বা ExitTransition অবজেক্ট একত্রিত করতে পারেন, এবং প্রতিটি তার আচরণ কাস্টমাইজ করার জন্য ঐচ্ছিক প্যারামিটার গ্রহণ করে। আরও তথ্যের জন্য রেফারেন্স পৃষ্ঠাগুলি দেখুন।

প্রবেশ এবং প্রস্থান ট্রানজিশনের উদাহরণ

এন্টারট্রানজিশন প্রস্থান রূপান্তর
fadeIn
একটি UI উপাদান ধীরে ধীরে দৃশ্যমান হয়।
fadeOut
একটি UI উপাদান ধীরে ধীরে দৃষ্টির বাইরে চলে যায়।
slideIn
স্ক্রিনের বাইরে থেকে একটি UI উপাদান স্লাইড করে দৃশ্যমান হয়।
slideOut
একটি UI উপাদান স্ক্রিনের বাইরে চলে যায়।
slideInHorizontally
একটি UI উপাদান আনুভূমিকভাবে স্লাইড করে দৃশ্যমান হয়।
slideOutHorizontally
একটি UI উপাদান আনুভূমিকভাবে সরে গিয়ে দৃষ্টির বাইরে চলে যায়।
slideInVertically
একটি UI উপাদান উল্লম্বভাবে স্লাইড করে দৃশ্যমান হয়।
slideOutVertically
একটি UI উপাদান উল্লম্বভাবে সরে গিয়ে দৃষ্টির বাইরে চলে যায়।
scaleIn
একটি UI এলিমেন্ট বড় হয়ে দৃশ্যমান হয়।
scaleOut
একটি UI এলিমেন্ট ছোট হয়ে দৃষ্টির বাইরে চলে যায়।
expandIn
একটি UI উপাদান কেন্দ্রীয় বিন্দু থেকে প্রসারিত হয়ে দৃশ্যমান হয়।
shrinkOut
একটি UI উপাদান সংকুচিত হয়ে একটি কেন্দ্রীয় বিন্দুতে মিলিয়ে যায়।
expandHorizontally
একটি UI উপাদান আনুভূমিকভাবে প্রসারিত হয়ে দৃশ্যমান হয়।
shrinkHorizontally
একটি UI এলিমেন্ট আনুভূমিকভাবে সংকুচিত হয়ে দৃষ্টির বাইরে চলে যায়।
expandVertically
একটি UI উপাদান উল্লম্বভাবে প্রসারিত হয়ে দৃশ্যমান হয়।
shrinkVertically
একটি UI এলিমেন্ট উল্লম্বভাবে সংকুচিত হয়ে দৃষ্টির বাইরে চলে যায়।

AnimatedVisibility একটি বিকল্পও রয়েছে যা একটি MutableTransitionState আর্গুমেন্ট গ্রহণ করে। এটি আপনাকে কম্পোজিশন ট্রি-তে AnimatedVisibility কম্পোজেবলটি যুক্ত হওয়ার সাথে সাথেই একটি অ্যানিমেশন ট্রিগার করতে দেয়। এটি অ্যানিমেশনের অবস্থা পর্যবেক্ষণ করার জন্যও উপযোগী।

// Create a MutableTransitionState<Boolean> for the AnimatedVisibility.
val state = remember {
    MutableTransitionState(false).apply {
        // Start the animation immediately.
        targetState = true
    }
}
Column {
    AnimatedVisibility(visibleState = state) {
        Text(text = "Hello, world!")
    }

    // Use the MutableTransitionState to know the current animation state
    // of the AnimatedVisibility.
    Text(
        text = when {
            state.isIdle && state.currentState -> "Visible"
            !state.isIdle && state.currentState -> "Disappearing"
            state.isIdle && !state.currentState -> "Invisible"
            else -> "Appearing"
        }
    )
}

শিশুদের জন্য প্রবেশ এবং প্রস্থানের অ্যানিমেশন তৈরি করুন

AnimatedVisibility এর অন্তর্ভুক্ত কন্টেন্ট (সরাসরি বা পরোক্ষ চাইল্ড) তাদের প্রত্যেকের জন্য ভিন্ন ভিন্ন অ্যানিমেশন আচরণ নির্দিষ্ট করতে animateEnterExit মডিফায়ারটি ব্যবহার করতে পারে। এই চাইল্ডগুলোর প্রতিটির ভিজ্যুয়াল ইফেক্ট হলো AnimatedVisibility কম্পোজেবলে নির্দিষ্ট করা অ্যানিমেশনগুলো এবং চাইল্ডটির নিজস্ব এন্টার ও এক্সিট অ্যানিমেশনের একটি সংমিশ্রণ।

var visible by remember { mutableStateOf(true) }

AnimatedVisibility(
    visible = visible,
    enter = fadeIn(),
    exit = fadeOut()
) {
    // Fade in/out the background and the foreground.
    Box(
        Modifier
            .fillMaxSize()
            .background(Color.DarkGray)
    ) {
        Box(
            Modifier
                .align(Alignment.Center)
                .animateEnterExit(
                    // Slide in/out the inner box.
                    enter = slideInVertically(),
                    exit = slideOutVertically()
                )
                .sizeIn(minWidth = 256.dp, minHeight = 64.dp)
                .background(Color.Red)
        ) {
            // Content of the notification…
        }
    }
}

কিছু ক্ষেত্রে, আপনি চাইতে পারেন যে AnimatedVisibility যেন কোনো অ্যানিমেশনই প্রয়োগ না করে, যাতে animateEnterExit এর মাধ্যমে প্রতিটি চাইল্ড তাদের নিজস্ব স্বতন্ত্র অ্যানিমেশন পেতে পারে। এটি করার জন্য, AnimatedVisibility কম্পোজেবলে EnterTransition.None এবং ExitTransition.None উল্লেখ করুন।

কাস্টম অ্যানিমেশন যোগ করুন

যদি আপনি বিল্ট-ইন এন্টার এবং এক্সিট অ্যানিমেশনের বাইরে কাস্টম অ্যানিমেশন এফেক্ট যোগ করতে চান, তাহলে AnimatedVisibility এর জন্য কন্টেন্ট ল্যাম্বডার ভিতরে transition প্রপার্টি ব্যবহার করে অন্তর্নিহিত Transition ইনস্ট্যান্সটি অ্যাক্সেস করুন। Transition ইনস্ট্যান্সে যোগ করা যেকোনো অ্যানিমেশন স্টেট AnimatedVisibility এর এন্টার এবং এক্সিট অ্যানিমেশনের সাথে একই সময়ে চলবে। Transition এর সমস্ত অ্যানিমেশন শেষ না হওয়া পর্যন্ত AnimatedVisibility তার কন্টেন্ট রিমুভ করে না। Transition থেকে স্বাধীনভাবে তৈরি করা এক্সিট অ্যানিমেশনের ক্ষেত্রে (যেমন animate*AsState ব্যবহার করে), AnimatedVisibility সেগুলোকে বিবেচনা করতে পারবে না, এবং তাই সেগুলো শেষ হওয়ার আগেই কন্টেন্ট কম্পোজেবলটি রিমুভ করে দিতে পারে।

var visible by remember { mutableStateOf(true) }

AnimatedVisibility(
    visible = visible,
    enter = fadeIn(),
    exit = fadeOut()
) { // this: AnimatedVisibilityScope
    // Use AnimatedVisibilityScope#transition to add a custom animation
    // to the AnimatedVisibility.
    val background by transition.animateColor(label = "color") { state ->
        if (state == EnterExitState.Visible) Color.Blue else Color.Gray
    }
    Box(
        modifier = Modifier
            .size(128.dp)
            .background(background)
    )
}

Transition ব্যবহার করে অ্যানিমেশন পরিচালনা করার বিষয়ে আরও জানতে, “Animate multiple properties simultaneous with a transition” দেখুন।

লক্ষ্য অবস্থার উপর ভিত্তি করে অ্যানিমেট করুন

AnimatedContent কম্পোজেবলটি একটি টার্গেট স্টেটের উপর ভিত্তি করে এর কন্টেন্টকে পরিবর্তনের সাথে সাথে অ্যানিমেট করে।

Row {
    var count by remember { mutableIntStateOf(0) }
    Button(onClick = { count++ }) {
        Text("Add")
    }
    AnimatedContent(
        targetState = count,
        label = "animated content"
    ) { targetCount ->
        // Make sure to use `targetCount`, not `count`.
        Text(text = "Count: $targetCount")
    }
}

ডিফল্টরূপে, প্রাথমিক কন্টেন্টটি ধীরে ধীরে অদৃশ্য হয়ে যায় এবং তারপরে টার্গেট কন্টেন্টটি ধীরে ধীরে দৃশ্যমান হয় (এই আচরণটিকে ফেড থ্রু বলা হয়)। আপনি transitionSpec প্যারামিটারে একটি ContentTransform অবজেক্ট নির্দিষ্ট করে এই অ্যানিমেশন আচরণটি কাস্টমাইজ করতে পারেন। আপনি with ইনফিক্স ফাংশন ব্যবহার করে একটি EnterTransition অবজেক্টের সাথে একটি ExitTransition অবজেক্ট যুক্ত করে ContentTransform এর একটি ইনস্ট্যান্স তৈরি করতে পারেন। আপনি using ইনফিক্স ফাংশন দিয়ে ContentTransform অবজেক্টটি সংযুক্ত করে এতে SizeTransform প্রয়োগ করতে পারেন।

AnimatedContent(
    targetState = count,
    transitionSpec = {
        // Compare the incoming number with the previous number.
        if (targetState > initialState) {
            // If the target number is larger, it slides up and fades in
            // while the initial (smaller) number slides up and fades out.
            slideInVertically { height -> height } + fadeIn() togetherWith
                slideOutVertically { height -> -height } + fadeOut()
        } else {
            // If the target number is smaller, it slides down and fades in
            // while the initial number slides down and fades out.
            slideInVertically { height -> -height } + fadeIn() togetherWith
                slideOutVertically { height -> height } + fadeOut()
        }.using(
            // Disable clipping since the faded slide-in/out should
            // be displayed out of bounds.
            SizeTransform(clip = false)
        )
    }, label = "animated content"
) { targetCount ->
    Text(text = "$targetCount")
}

EnterTransition নির্ধারণ করে যে টার্গেট কন্টেন্টটি কীভাবে প্রদর্শিত হবে, এবং ExitTransition নির্ধারণ করে যে প্রাথমিক কন্টেন্টটি কীভাবে অদৃশ্য হবে। AnimatedVisibility জন্য উপলব্ধ সমস্ত EnterTransition এবং ExitTransition ফাংশন ছাড়াও, AnimatedContent slideIntoContainer এবং slideOutOfContainer রয়েছে। এগুলি হলো slideInHorizontally/Vertically এবং slideOutHorizontally/Vertically এর সুবিধাজনক বিকল্প, যা AnimatedContent কন্টেন্টের প্রাথমিক এবং টার্গেট কন্টেন্টের আকারের উপর ভিত্তি করে স্লাইড দূরত্ব গণনা করে।

SizeTransform নির্ধারণ করে যে প্রাথমিক এবং লক্ষ্য কন্টেন্টের মধ্যে আকারটি কীভাবে অ্যানিমেট হবে। অ্যানিমেশন তৈরি করার সময় আপনি প্রাথমিক আকার এবং লক্ষ্য আকার উভয়ই ব্যবহার করতে পারেন। অ্যানিমেশনের সময় কন্টেন্টটি কম্পোনেন্টের আকারে ক্লিপ করা হবে কিনা, তাও SizeTransform নিয়ন্ত্রণ করে।

var expanded by remember { mutableStateOf(false) }
Surface(
    color = MaterialTheme.colorScheme.primary,
    onClick = { expanded = !expanded }
) {
    AnimatedContent(
        targetState = expanded,
        transitionSpec = {
            fadeIn(animationSpec = tween(150, 150)) togetherWith
                fadeOut(animationSpec = tween(150)) using
                SizeTransform { initialSize, targetSize ->
                    if (targetState) {
                        keyframes {
                            // Expand horizontally first.
                            IntSize(targetSize.width, initialSize.height) at 150
                            durationMillis = 300
                        }
                    } else {
                        keyframes {
                            // Shrink vertically first.
                            IntSize(initialSize.width, targetSize.height) at 150
                            durationMillis = 300
                        }
                    }
                }
        }, label = "size transform"
    ) { targetExpanded ->
        if (targetExpanded) {
            Expanded()
        } else {
            ContentIcon()
        }
    }
}

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

AnimatedVisibility মতোই, animateEnterExit মডিফায়ারটি AnimatedContent এর content ল্যাম্বডার ভিতরে পাওয়া যায়। প্রতিটি প্রত্যক্ষ বা পরোক্ষ চাইল্ডে আলাদাভাবে EnterAnimation এবং ExitAnimation প্রয়োগ করতে এটি ব্যবহার করুন।

কাস্টম অ্যানিমেশন যোগ করুন

AnimatedVisibility মতোই, transition ফিল্ডটি AnimatedContent এর content lambda-র ভিতরে পাওয়া যায়। AnimatedContent ট্রানজিশনের সাথে একযোগে চলে এমন একটি কাস্টম অ্যানিমেশন ইফেক্ট তৈরি করতে এটি ব্যবহার করুন। বিস্তারিত জানতে updateTransition দেখুন।

দুটি লেআউটের মধ্যে অ্যানিমেট করুন

Crossfade অ্যানিমেশনের মাধ্যমে দুটি লেআউটের মধ্যে পরিবর্তন ঘটায়। current প্যারামিটারে দেওয়া মান টগল করার মাধ্যমে ক্রসফেড অ্যানিমেশনের সাহায্যে কন্টেন্ট পরিবর্তন করা হয়।

var currentPage by remember { mutableStateOf("A") }
Crossfade(targetState = currentPage, label = "cross fade") { screen ->
    when (screen) {
        "A" -> Text("Page A")
        "B" -> Text("Page B")
    }
}

অন্তর্নির্মিত অ্যানিমেশন মডিফায়ার

কম্পোজ সরাসরি কম্পোজেবলগুলোর ওপর নির্দিষ্ট পরিবর্তন অ্যানিমেট করার জন্য মডিফায়ার প্রদান করে।

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

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

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
        }

) {
}

তালিকার আইটেম অ্যানিমেশন

আপনি যদি কোনো লেজি লিস্ট বা গ্রিডের ভেতরে আইটেমের পুনর্বিন্যাস অ্যানিমেট করতে চান, তাহলে লেজি লেআউট আইটেম অ্যানিমেশন ডকুমেন্টেশনটি দেখে নিন।

{% হুবহু %} {% endverbatim %} {% হুবহু %} {% endverbatim %}