animate*AsState
দিয়ে একটি একক মান অ্যানিমেট করুন
animate*AsState
ফাংশনগুলি একটি একক মান অ্যানিমেট করার জন্য রচনার সবচেয়ে সহজ অ্যানিমেশন API। আপনি শুধুমাত্র লক্ষ্য মান (বা শেষ মান) প্রদান করেন এবং API বর্তমান মান থেকে নির্দিষ্ট মান পর্যন্ত অ্যানিমেশন শুরু করে।
নিচে এই API ব্যবহার করে আলফা অ্যানিমেটিং করার একটি উদাহরণ দেওয়া হল। animateFloatAsState
এ টার্গেট মানটিকে কেবল মোড়ানোর মাধ্যমে, আলফা মান এখন প্রদত্ত মানগুলির মধ্যে একটি অ্যানিমেশন মান (এই ক্ষেত্রে 1f
বা 0.5f
)।
var enabled by remember { mutableStateOf(true) } val alpha: Float by animateFloatAsState(if (enabled) 1f else 0.5f, label = "alpha") Box( Modifier .fillMaxSize() .graphicsLayer(alpha = alpha) .background(Color.Red) )
মনে রাখবেন যে আপনাকে কোনো অ্যানিমেশন ক্লাসের একটি উদাহরণ তৈরি করতে হবে না, বা বাধা হ্যান্ডেল করতে হবে না। হুডের নিচে, একটি অ্যানিমেশন অবজেক্ট (যেমন, একটি Animatable
ইনস্ট্যান্স) তৈরি করা হবে এবং কল সাইটে মনে রাখা হবে, যার প্রাথমিক মান হিসাবে প্রথম লক্ষ্য মান। সেখান থেকে, যে কোনো সময় আপনি এই কম্পোজযোগ্য একটি ভিন্ন লক্ষ্য মান সরবরাহ করেন, একটি অ্যানিমেশন স্বয়ংক্রিয়ভাবে সেই মানটির দিকে শুরু হয়। যদি ফ্লাইটে ইতিমধ্যেই একটি অ্যানিমেশন থাকে, তবে অ্যানিমেশনটি তার বর্তমান মান (এবং বেগ) থেকে শুরু হয় এবং লক্ষ্য মানের দিকে অ্যানিমেট হয়। অ্যানিমেশনের সময়, এই কম্পোজেবলটি পুনর্গঠিত হয় এবং প্রতিটি ফ্রেমে একটি আপডেট অ্যানিমেশন মান প্রদান করে।
বাক্সের বাইরে, কম্পোজ Float
, Color
, Dp
, Size
, Offset
, Rect
, Int
, IntOffset
এবং IntSize
জন্য animate*AsState
ফাংশন প্রদান করে। আপনি সহজেই অন্যান্য ডেটা প্রকারের জন্য সমর্থন যোগ করতে পারেন একটি TwoWayConverter
প্রদান করে animateValueAsState
যা একটি জেনেরিক টাইপ নেয়।
আপনি একটি AnimationSpec
প্রদান করে অ্যানিমেশন স্পেসিফিকেশন কাস্টমাইজ করতে পারেন। আরও তথ্যের জন্য AnimationSpec দেখুন।
একটি ট্রানজিশনের সাথে একসাথে একাধিক বৈশিষ্ট্য অ্যানিমেট করুন
Transition
তার সন্তান হিসাবে এক বা একাধিক অ্যানিমেশন পরিচালনা করে এবং একাধিক রাজ্যের মধ্যে একযোগে চালায়।
রাজ্যগুলি যে কোনও ডেটা টাইপের হতে পারে। অনেক ক্ষেত্রে, আপনি টাইপ নিরাপত্তা নিশ্চিত করতে একটি কাস্টম enum
টাইপ ব্যবহার করতে পারেন, যেমন এই উদাহরণে:
enum class BoxState { Collapsed, Expanded }
updateTransition
Transition
একটি উদাহরণ তৈরি করে এবং মনে রাখে এবং এর অবস্থা আপডেট করে।
var currentState by remember { mutableStateOf(BoxState.Collapsed) } val transition = updateTransition(currentState, label = "box state")
তারপরে আপনি এই ট্রানজিশনে একটি চাইল্ড অ্যানিমেশন সংজ্ঞায়িত করতে animate*
এক্সটেনশন ফাংশনগুলির একটি ব্যবহার করতে পারেন। প্রতিটি রাজ্যের জন্য লক্ষ্য মান নির্দিষ্ট করুন। এই animate*
ফাংশনগুলি একটি অ্যানিমেশন মান প্রদান করে যা অ্যানিমেশন চলাকালীন প্রতিটি ফ্রেমে আপডেট করা হয় যখন ট্রানজিশন অবস্থা updateTransition
এর সাথে আপডেট করা হয়।
val rect by transition.animateRect(label = "rectangle") { state -> when (state) { BoxState.Collapsed -> Rect(0f, 0f, 100f, 100f) BoxState.Expanded -> Rect(100f, 100f, 300f, 300f) } } val borderWidth by transition.animateDp(label = "border width") { state -> when (state) { BoxState.Collapsed -> 1.dp BoxState.Expanded -> 0.dp } }
ঐচ্ছিকভাবে, ট্রানজিশন স্টেট পরিবর্তনের প্রতিটি সংমিশ্রণের জন্য একটি ভিন্ন AnimationSpec
নির্দিষ্ট করতে আপনি একটি transitionSpec
প্যারামিটার পাস করতে পারেন। আরও তথ্যের জন্য AnimationSpec দেখুন।
val color by transition.animateColor( transitionSpec = { when { BoxState.Expanded isTransitioningTo BoxState.Collapsed -> spring(stiffness = 50f) else -> tween(durationMillis = 500) } }, label = "color" ) { state -> when (state) { BoxState.Collapsed -> MaterialTheme.colorScheme.primary BoxState.Expanded -> MaterialTheme.colorScheme.background } }
একবার একটি ট্রানজিশন টার্গেট স্টেটে পৌঁছে গেলে, Transition.currentState
হবে Transition.targetState
এর মতো। এটি রূপান্তর শেষ হয়েছে কিনা তার জন্য একটি সংকেত হিসাবে ব্যবহার করা যেতে পারে।
আমরা কখনও কখনও প্রথম লক্ষ্য রাষ্ট্র থেকে ভিন্ন একটি প্রাথমিক অবস্থা চাই. আমরা এটি অর্জন করতে MutableTransitionState
এর সাথে updateTransition
ব্যবহার করতে পারি। উদাহরণস্বরূপ, কোডটি রচনায় প্রবেশ করার সাথে সাথে এটি আমাদের অ্যানিমেশন শুরু করতে দেয়।
// Start in collapsed state and immediately animate to expanded var currentState = remember { MutableTransitionState(BoxState.Collapsed) } currentState.targetState = BoxState.Expanded val transition = rememberTransition(currentState, label = "box state") // ……
একাধিক সংমিশ্রণযোগ্য ফাংশন জড়িত আরও জটিল রূপান্তরের জন্য, আপনি চাইল্ড ট্রানজিশন তৈরি করতে createChildTransition
ব্যবহার করতে পারেন। এই কৌশলটি একটি জটিল কম্পোজেবলের একাধিক সাবকম্পোনেন্টের মধ্যে উদ্বেগ আলাদা করার জন্য কার্যকর। অভিভাবক ট্রানজিশন চাইল্ড ট্রানজিশনের সমস্ত অ্যানিমেশন মান সম্পর্কে সচেতন থাকবেন।
enum class DialerState { DialerMinimized, NumberPad } @Composable fun DialerButton(isVisibleTransition: Transition<Boolean>) { // `isVisibleTransition` spares the need for the content to know // about other DialerStates. Instead, the content can focus on // animating the state change between visible and not visible. } @Composable fun NumberPad(isVisibleTransition: Transition<Boolean>) { // `isVisibleTransition` spares the need for the content to know // about other DialerStates. Instead, the content can focus on // animating the state change between visible and not visible. } @Composable fun Dialer(dialerState: DialerState) { val transition = updateTransition(dialerState, label = "dialer state") Box { // Creates separate child transitions of Boolean type for NumberPad // and DialerButton for any content animation between visible and // not visible NumberPad( transition.createChildTransition { it == DialerState.NumberPad } ) DialerButton( transition.createChildTransition { it == DialerState.DialerMinimized } ) } }
AnimatedVisibility
এবং AnimatedContent
সহ ট্রানজিশন ব্যবহার করুন
AnimatedVisibility
এবং AnimatedContent
Transition
এক্সটেনশন ফাংশন হিসাবে উপলব্ধ। Transition.AnimatedVisibility
এবং Transition.AnimatedContent
এর জন্য targetState
Transition
থেকে উদ্ভূত হয় এবং যখন Transition
targetState
পরিবর্তিত হয় তখন প্রয়োজন অনুযায়ী এন্টার/এক্সিট ট্রানজিশন ট্রিগার করে। এই এক্সটেনশন ফাংশনগুলি সমস্ত প্রবেশ/প্রস্থান/সাইজ ট্রান্সফর্ম অ্যানিমেশনগুলিকে অনুমতি দেয় যা অন্যথায় AnimatedVisibility
/ AnimatedContent
অভ্যন্তরীণ Transition
উত্তোলন করতে পারে৷ এই এক্সটেনশন ফাংশনগুলির সাথে, AnimatedVisibility
/ AnimatedContent
অবস্থার পরিবর্তন বাইরে থেকে লক্ষ্য করা যায়। একটি বুলিয়ান visible
প্যারামিটারের পরিবর্তে, AnimatedVisibility
এই সংস্করণটি একটি ল্যাম্বডা নেয় যা প্যারেন্ট ট্রানজিশনের টার্গেট স্টেটকে বুলিয়ানে রূপান্তর করে।
বিস্তারিত জানার জন্য অ্যানিমেটেড ভিজিবিলিটি এবং অ্যানিমেটেড কনটেন্ট দেখুন।
var selected by remember { mutableStateOf(false) } // Animates changes when `selected` is changed. val transition = updateTransition(selected, label = "selected state") val borderColor by transition.animateColor(label = "border color") { isSelected -> if (isSelected) Color.Magenta else Color.White } val elevation by transition.animateDp(label = "elevation") { isSelected -> if (isSelected) 10.dp else 2.dp } Surface( onClick = { selected = !selected }, shape = RoundedCornerShape(8.dp), border = BorderStroke(2.dp, borderColor), shadowElevation = elevation ) { Column( modifier = Modifier .fillMaxWidth() .padding(16.dp) ) { Text(text = "Hello, world!") // AnimatedVisibility as a part of the transition. transition.AnimatedVisibility( visible = { targetSelected -> targetSelected }, enter = expandVertically(), exit = shrinkVertically() ) { Text(text = "It is fine today.") } // AnimatedContent as a part of the transition. transition.AnimatedContent { targetState -> if (targetState) { Text(text = "Selected") } else { Icon(imageVector = Icons.Default.Phone, contentDescription = "Phone") } } } }
একটি ট্রানজিশন এনক্যাপসুলেট করুন এবং এটি পুনরায় ব্যবহারযোগ্য করুন
সাধারণ ব্যবহারের ক্ষেত্রে, আপনার UI-এর মতো একই কম্পোজেবলে ট্রানজিশন অ্যানিমেশন সংজ্ঞায়িত করা একটি সম্পূর্ণ বৈধ বিকল্প। আপনি যখন বেশ কয়েকটি অ্যানিমেটেড মান সহ একটি জটিল উপাদানে কাজ করছেন, তবে, আপনি কম্পোজযোগ্য UI থেকে অ্যানিমেশন বাস্তবায়নকে আলাদা করতে চাইতে পারেন।
আপনি একটি ক্লাস তৈরি করে এটি করতে পারেন যা সমস্ত অ্যানিমেশন মান ধারণ করে এবং একটি 'আপডেট' ফাংশন যা সেই ক্লাসের একটি উদাহরণ প্রদান করে। রূপান্তর বাস্তবায়ন নতুন পৃথক ফাংশন মধ্যে নিষ্কাশন করা যেতে পারে. যখন অ্যানিমেশন লজিককে কেন্দ্রীভূত করার প্রয়োজন হয় বা জটিল অ্যানিমেশনগুলিকে পুনরায় ব্যবহারযোগ্য করার প্রয়োজন হয় তখন এই প্যাটার্নটি কার্যকর।
enum class BoxState { Collapsed, Expanded } @Composable fun AnimatingBox(boxState: BoxState) { val transitionData = updateTransitionData(boxState) // UI tree Box( modifier = Modifier .background(transitionData.color) .size(transitionData.size) ) } // Holds the animation values. private class TransitionData( color: State<Color>, size: State<Dp> ) { val color by color val size by size } // Create a Transition and return its animation values. @Composable private fun updateTransitionData(boxState: BoxState): TransitionData { val transition = updateTransition(boxState, label = "box state") val color = transition.animateColor(label = "color") { state -> when (state) { BoxState.Collapsed -> Color.Gray BoxState.Expanded -> Color.Red } } val size = transition.animateDp(label = "size") { state -> when (state) { BoxState.Collapsed -> 64.dp BoxState.Expanded -> 128.dp } } return remember(transition) { TransitionData(color, size) } }
rememberInfiniteTransition
দিয়ে একটি অসীম পুনরাবৃত্তি অ্যানিমেশন তৈরি করুন
InfiniteTransition
এক বা একাধিক চাইল্ড অ্যানিমেশন যেমন Transition
ধারণ করে, কিন্তু অ্যানিমেশনগুলি রচনায় প্রবেশ করার সাথে সাথেই চলতে শুরু করে এবং অপসারণ না করা পর্যন্ত থামে না। আপনি rememberInfiniteTransition
দিয়ে InfiniteTransition
এর একটি উদাহরণ তৈরি করতে পারেন। চাইল্ড অ্যানিমেশন animateColor
, animatedFloat
বা animatedValue
দিয়ে যোগ করা যেতে পারে। অ্যানিমেশন স্পেসিফিকেশন নির্দিষ্ট করার জন্য আপনাকে একটি infiniteRepeatable নির্দিষ্ট করতে হবে।
val infiniteTransition = rememberInfiniteTransition(label = "infinite") val color by infiniteTransition.animateColor( initialValue = Color.Red, targetValue = Color.Green, animationSpec = infiniteRepeatable( animation = tween(1000, easing = LinearEasing), repeatMode = RepeatMode.Reverse ), label = "color" ) Box( Modifier .fillMaxSize() .background(color) )
নিম্ন-স্তরের অ্যানিমেশন API
পূর্ববর্তী বিভাগে উল্লিখিত সমস্ত উচ্চ-স্তরের অ্যানিমেশন APIগুলি নিম্ন-স্তরের অ্যানিমেশন APIগুলির ভিত্তির উপরে নির্মিত।
animate*AsState
ফাংশন হল সবচেয়ে সহজ এপিআই, যা একটি অ্যানিমেশন মান হিসাবে তাত্ক্ষণিক মান পরিবর্তন করে। এটি Animatable
দ্বারা সমর্থিত, যা একটি একক মান অ্যানিমেট করার জন্য একটি করুটিন-ভিত্তিক API। updateTransition
একটি ট্রানজিশন অবজেক্ট তৈরি করে যা একাধিক অ্যানিমেটিং মান পরিচালনা করতে পারে এবং একটি রাষ্ট্র পরিবর্তনের উপর ভিত্তি করে সেগুলি চালাতে পারে। rememberInfiniteTransition
অনুরূপ, কিন্তু এটি একটি অসীম রূপান্তর তৈরি করে যা একাধিক অ্যানিমেশন পরিচালনা করতে পারে যা অনির্দিষ্টকালের জন্য চলতে থাকে। Animatable
ব্যতীত এই সমস্ত APIগুলিই কম্পোজেবল, যার মানে এই অ্যানিমেশনগুলি রচনার বাইরে তৈরি করা যেতে পারে।
এই সমস্ত APIগুলি আরও মৌলিক Animation
API-এর উপর ভিত্তি করে তৈরি৷ যদিও বেশিরভাগ অ্যাপ Animation
সাথে সরাসরি ইন্টারঅ্যাক্ট করবে না, Animation
জন্য কিছু কাস্টমাইজেশন ক্ষমতা উচ্চ-স্তরের API-এর মাধ্যমে উপলব্ধ। AnimationVector
এবং AnimationSpec
সম্পর্কে আরও তথ্যের জন্য অ্যানিমেশন কাস্টমাইজ করুন দেখুন।
Animatable
: করুটিন-ভিত্তিক একক মান অ্যানিমেশন
Animatable
হল একটি মান ধারক যা animateTo
মাধ্যমে পরিবর্তিত হওয়ার সাথে সাথে মানটিকে অ্যানিমেট করতে পারে। এটি animate*AsState
বাস্তবায়নের জন্য এপিআই ব্যাক আপ করে। এটি সুসংগত ধারাবাহিকতা এবং পারস্পরিক একচেটিয়াতা নিশ্চিত করে, যার অর্থ মান পরিবর্তন সর্বদা অবিচ্ছিন্ন থাকে এবং যেকোন চলমান অ্যানিমেশন বাতিল করা হবে।
Animatable
অনেক বৈশিষ্ট্য, animateTo
সহ, সাসপেন্ড ফাংশন হিসাবে সরবরাহ করা হয়েছে। এর মানে হল যে তাদের একটি উপযুক্ত কোরোটিন সুযোগে আবৃত করা দরকার। উদাহরণস্বরূপ, আপনি শুধুমাত্র নির্দিষ্ট কী মানের সময়কালের জন্য একটি সুযোগ তৈরি করতে LaunchedEffect
কম্পোজেবল ব্যবহার করতে পারেন।
// Start out gray and animate to green/red based on `ok` val color = remember { Animatable(Color.Gray) } LaunchedEffect(ok) { color.animateTo(if (ok) Color.Green else Color.Red) } Box( Modifier .fillMaxSize() .background(color.value) )
উপরের উদাহরণে, আমরা Color.Gray
এর প্রারম্ভিক মানের সাথে Animatable
একটি উদাহরণ তৈরি এবং মনে রাখি। বুলিয়ান পতাকার মানের উপর নির্ভর করে ok
, রঙটি Color.Green
বা Color.Red
তে অ্যানিমেট হয়। বুলিয়ান মানের পরবর্তী যেকোনো পরিবর্তন অন্য রঙে অ্যানিমেশন শুরু করে। মান পরিবর্তন করার সময় যদি একটি চলমান অ্যানিমেশন থাকে, তবে অ্যানিমেশনটি বাতিল করা হয় এবং নতুন অ্যানিমেশন বর্তমান স্ন্যাপশট মান থেকে বর্তমান বেগের সাথে শুরু হয়।
এটি হল অ্যানিমেশন বাস্তবায়ন যা পূর্ববর্তী বিভাগে উল্লিখিত animate*AsState
API-কে ব্যাক আপ করে। animate*AsState
এর তুলনায়, Animatable
ব্যবহার করে সরাসরি বিভিন্ন বিষয়ে আমাদের সূক্ষ্ম নিয়ন্ত্রণ পাওয়া যায়। প্রথমত, Animatable
একটি প্রাথমিক মান তার প্রথম লক্ষ্য মানের থেকে আলাদা হতে পারে। উদাহরণস্বরূপ, উপরের কোড উদাহরণটি প্রথমে একটি ধূসর বাক্স দেখায়, যা অবিলম্বে সবুজ বা লালে অ্যানিমেটিং শুরু করে। দ্বিতীয়ত, Animatable
কন্টেন্ট মানের উপর আরও ক্রিয়াকলাপ প্রদান করে, যথা snapTo
এবং animateDecay
। snapTo
অবিলম্বে লক্ষ্য মানের বর্তমান মান সেট করে। এটি কার্যকর যখন অ্যানিমেশন নিজেই সত্যের একমাত্র উৎস নয় এবং অন্যান্য অবস্থার সাথে সিঙ্ক করতে হবে, যেমন স্পর্শ ইভেন্ট। animateDecay
একটি অ্যানিমেশন শুরু করে যা প্রদত্ত বেগ থেকে ধীর হয়ে যায়। এটি ফ্লিং আচরণ বাস্তবায়নের জন্য দরকারী। আরও তথ্যের জন্য অঙ্গভঙ্গি এবং অ্যানিমেশন দেখুন।
বাক্সের বাইরে, Animatable
Float
এবং Color
সমর্থন করে, তবে একটি TwoWayConverter
প্রদান করে যেকোনো ডেটা টাইপ ব্যবহার করা যেতে পারে। আরও তথ্যের জন্য AnimationVector দেখুন।
আপনি একটি AnimationSpec
প্রদান করে অ্যানিমেশন স্পেসিফিকেশন কাস্টমাইজ করতে পারেন। আরও তথ্যের জন্য AnimationSpec দেখুন।
Animation
: ম্যানুয়ালি নিয়ন্ত্রিত অ্যানিমেশন
Animation
হল সর্বনিম্ন-স্তরের অ্যানিমেশন API উপলব্ধ। আমরা এখন পর্যন্ত অ্যানিমেশনের উপরে তৈরি করা অনেক অ্যানিমেশন দেখেছি। দুটি Animation
সাবটাইপ আছে: TargetBasedAnimation
এবং DecayAnimation
।
Animation
শুধুমাত্র ম্যানুয়ালি অ্যানিমেশনের সময় নিয়ন্ত্রণ করতে ব্যবহার করা উচিত। Animation
রাষ্ট্রহীন, এবং এতে জীবনচক্রের কোনো ধারণা নেই। এটি একটি অ্যানিমেশন গণনা ইঞ্জিন হিসাবে কাজ করে যা উচ্চ-স্তরের API ব্যবহার করে।
TargetBasedAnimation
অন্যান্য API গুলি বেশিরভাগ ব্যবহারের ক্ষেত্রেই কভার করে, কিন্তু TargetBasedAnimation
ব্যবহার করলে আপনি নিজে নিজে অ্যানিমেশন খেলার সময় নিয়ন্ত্রণ করতে পারবেন। নীচের উদাহরণে, withFrameNanos
দ্বারা প্রদত্ত ফ্রেম সময়ের উপর ভিত্তি করে TargetAnimation
খেলার সময় ম্যানুয়ালি নিয়ন্ত্রিত হয়।
val anim = remember { TargetBasedAnimation( animationSpec = tween(200), typeConverter = Float.VectorConverter, initialValue = 200f, targetValue = 1000f ) } var playTime by remember { mutableLongStateOf(0L) } LaunchedEffect(anim) { val startTime = withFrameNanos { it } do { playTime = withFrameNanos { it } - startTime val animationValue = anim.getValueFromNanos(playTime) } while (someCustomCondition()) }
DecayAnimation
TargetBasedAnimation
বিপরীতে, DecayAnimation
এর জন্য একটি targetValue
প্রদানের প্রয়োজন হয় না। পরিবর্তে, এটি initialVelocity
এবং initialValue
এবং সরবরাহকৃত DecayAnimationSpec
দ্বারা সেট করা প্রারম্ভিক অবস্থার উপর ভিত্তি করে তার targetValue
গণনা করে।
ক্ষয় অ্যানিমেশনগুলি প্রায়শই ফ্লিং ইঙ্গিতের পরে উপাদানগুলিকে থামাতে মন্থর করতে ব্যবহৃত হয়। অ্যানিমেশন বেগ initialVelocityVector
দ্বারা সেট করা মান থেকে শুরু হয় এবং সময়ের সাথে সাথে ধীর হয়ে যায়।
আপনার জন্য প্রস্তাবিত
- দ্রষ্টব্য: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট প্রদর্শিত হয়
- অ্যানিমেশন কাস্টমাইজ করুন {:#customize-animations}
- রচনায় অ্যানিমেশন
- অ্যানিমেশন মডিফায়ার এবং কম্পোজেবল