রচনার অনেকগুলি অন্তর্নির্মিত অ্যানিমেশন প্রক্রিয়া রয়েছে এবং কোনটি বেছে নেবেন তা জানা অপ্রতিরোধ্য হতে পারে৷ নীচে সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রের একটি তালিকা রয়েছে। আপনার কাছে উপলব্ধ বিভিন্ন API বিকল্পগুলির সম্পূর্ণ সেট সম্পর্কে আরও বিশদ তথ্যের জন্য, সম্পূর্ণ রচনা অ্যানিমেশন ডকুমেন্টেশন পড়ুন।
অ্যানিমেট সাধারণ কম্পোজেবল বৈশিষ্ট্য
কম্পোজ সুবিধাজনক API প্রদান করে যা আপনাকে অনেক সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রে সমাধান করতে দেয়। এই বিভাগটি দেখায় কিভাবে আপনি একটি কম্পোজেবলের সাধারণ বৈশিষ্ট্যগুলিকে অ্যানিমেট করতে পারেন।
অ্যানিমেট উপস্থিত / অদৃশ্য হয়ে যাওয়া
কম্পোজেবল লুকাতে বা দেখানোর জন্য 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
শেষ পর্যন্ত কম্পোজিশন থেকে আইটেমটিকে সরিয়ে দেয়।
অ্যানিমেট পটভূমির রঙ
val animatedColor by animateColorAsState( if (animateBackgroundColor) colorGreen else colorBlue, label = "color" ) Column( modifier = Modifier.drawBehind { drawRect(animatedColor) } ) { // your composable here }
এই বিকল্পটি Modifier.background()
ব্যবহার করার চেয়ে বেশি কার্যকরী। Modifier.background()
একটি এক-শট রঙের সেটিং এর জন্য গ্রহণযোগ্য, কিন্তু সময়ের সাথে সাথে একটি রঙ অ্যানিমেট করার সময়, এটি প্রয়োজনের চেয়ে বেশি পুনর্গঠনের কারণ হতে পারে।
পটভূমির রঙ অসীমভাবে অ্যানিমেট করার জন্য, একটি অ্যানিমেশন বিভাগের পুনরাবৃত্তি দেখুন।
একটি কম্পোজেবল আকার অ্যানিমেট
রচনা আপনাকে কয়েকটি ভিন্ন উপায়ে কম্পোজেবলের আকার অ্যানিমেট করতে দেয়। কম্পোজযোগ্য আকার পরিবর্তনের মধ্যে অ্যানিমেশনের জন্য 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
ব্যবহার করতে পারেন।
কম্পোজেবলের অ্যানিমেট অবস্থান
কম্পোজেবলের অবস্থান অ্যানিমেট করতে, 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) ) }
একটি রচনাযোগ্য প্যাডিং অ্যানিমেট
একটি কম্পোজেবলের প্যাডিং অ্যানিমেট করতে, 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 } )
একটি কম্পোজেবল এর অ্যানিমেট উচ্চতা
একটি কম্পোজেবলের উচ্চতা অ্যানিমেট করতে, 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
কম্পোজেবল ব্যবহার করুন, এবং উচ্চতা সম্পত্তি প্রতি রাজ্যে বিভিন্ন মান সেট করুন।
অ্যানিমেট টেক্সট স্কেল, অনুবাদ বা ঘূর্ণন
স্কেল, অনুবাদ বা পাঠ্যের ঘূর্ণন অ্যানিমেটিং করার সময়, TextStyle
এ textMotion
প্যারামিটার সেট করুন। 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) ) }
অ্যানিমেট টেক্সট রঙ
টেক্সট কালার অ্যানিমেট করতে, 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 }, // ... )
বিভিন্ন ধরনের সামগ্রীর মধ্যে স্যুইচ করুন
বিভিন্ন কম্পোজেবলের মধ্যে অ্যানিমেট করতে 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
এ এই ব্লগ পোস্ট পড়ুন।
বিভিন্ন গন্তব্যে নেভিগেট করার সময় অ্যানিমেট করুন
নেভিগেশন-কম্পোজ আর্টিফ্যাক্ট ব্যবহার করার সময় কম্পোজেবলের মধ্যে ট্রানজিশন অ্যানিমেট করতে, একটি কম্পোজেবলের 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( // ... ) } }
বিভিন্ন ধরণের এন্টার এবং এক্সিট ট্রানজিশন রয়েছে যা ইনকামিং এবং আউটগোয়িং কন্টেন্টে বিভিন্ন প্রভাব প্রয়োগ করে, আরও তথ্যের জন্য ডকুমেন্টেশন দেখুন।
একটি অ্যানিমেশন পুনরাবৃত্তি করুন
আপনার অ্যানিমেশন ক্রমাগত পুনরাবৃত্তি করতে একটি 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 } )
ক্রমিক অ্যানিমেশন তৈরি করুন
অনুক্রমিক বা সমসাময়িক অ্যানিমেশনগুলি সম্পাদন করতে 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)) }
সমসাময়িক অ্যানিমেশন তৈরি করুন
সমসাময়িক অ্যানিমেশনগুলি অর্জন করতে 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
: কোনো অ্যানিমেশন ছাড়াই তাত্ক্ষণিকভাবে শেষ মান পর্যন্ত স্ন্যাপ করে।
অ্যানিমেশনস্পেকস সম্পর্কে আরও তথ্যের জন্য সম্পূর্ণ ডকুমেন্টেশন পড়ুন।
অতিরিক্ত সম্পদ
রচনায় মজাদার অ্যানিমেশনের আরও উদাহরণের জন্য, নিম্নলিখিতগুলি দেখুন:
- রচনায় 5টি দ্রুত অ্যানিমেশন
- কম্পোজে জেলিফিশ সরানো হচ্ছে
- রচনায়
AnimatedContent
কাস্টমাইজ করা - কম্পোজে ইজিং ফাংশন সহজ করা