রচনার অনেকগুলি অন্তর্নির্মিত অ্যানিমেশন প্রক্রিয়া রয়েছে এবং কোনটি বেছে নেবেন তা জানা অপ্রতিরোধ্য হতে পারে৷ নীচে সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রের একটি তালিকা রয়েছে। আপনার কাছে উপলব্ধ বিভিন্ন 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
কাস্টমাইজ করা - কম্পোজে ইজিং ফাংশন সহজ করা
রচনার অনেকগুলি অন্তর্নির্মিত অ্যানিমেশন প্রক্রিয়া রয়েছে এবং কোনটি বেছে নেবেন তা জানা অপ্রতিরোধ্য হতে পারে৷ নীচে সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রের একটি তালিকা রয়েছে। আপনার কাছে উপলব্ধ বিভিন্ন 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
কাস্টমাইজ করা - কম্পোজে ইজিং ফাংশন সহজ করা
রচনার অনেকগুলি অন্তর্নির্মিত অ্যানিমেশন প্রক্রিয়া রয়েছে এবং কোনটি বেছে নেবেন তা জানা অপ্রতিরোধ্য হতে পারে৷ নীচে সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রের একটি তালিকা রয়েছে। আপনার কাছে উপলব্ধ বিভিন্ন 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{ }
ব্যবহার করুন, কারণ এই মডিফায়ারটি সবসময় ড্র পর্বে চলে। এই বিষয়ে আরও তথ্যের জন্য, কর্মক্ষমতা ডকুমেন্টেশনে ডিফারিং রিডস বিভাগটি দেখুন।
অ্যানিমেশনের সময় পরিবর্তন করুন
বেশিরভাগ অ্যানিমেশনের জন্য ডিফল্টভাবে কম্পোজ স্প্রিং অ্যানিমেশন ব্যবহার করে। স্প্রিংস, বা পদার্থবিদ্যা-ভিত্তিক অ্যানিমেশনগুলি আরও প্রাকৃতিক অনুভব করে। তারা একটি নির্দিষ্ট সময়ের পরিবর্তে বস্তুর বর্তমান বেগ বিবেচনায় নেওয়ায় বাধাযোগ্য। আপনি যদি ডিফল্টটি ওভাররাইড করতে চান তবে উপরে প্রদর্শিত সমস্ত অ্যানিমেশন এপিআইগুলির একটি অ্যানিমেশন কীভাবে চালিত হয় তা কাস্টমাইজ করার জন্য একটি animationSpec
সেট করার ক্ষমতা রয়েছে, আপনি এটি একটি নির্দিষ্ট সময়কালের জন্য কার্যকর করতে চান বা আরও বাউন্সি হতে চান।
নীচে বিভিন্ন animationSpec
বিকল্পগুলির সংক্ষিপ্তসার রয়েছে:
-
spring
: পদার্থবিজ্ঞান ভিত্তিক অ্যানিমেশন, সমস্ত অ্যানিমেশনগুলির জন্য ডিফল্ট। আলাদা অ্যানিমেশন চেহারা এবং অনুভূতি অর্জন করতে আপনি কঠোরতা বা স্যাঁতসেঁতে বা স্যাঁতসেঁতে পরিবর্তন করতে পারেন। -
tween
( এর মধ্যে সংক্ষিপ্ত): সময়কাল-ভিত্তিক অ্যানিমেশন, একটিEasing
ফাংশন সহ দুটি মানের মধ্যে অ্যানিমেট করে। -
keyframes
: অ্যানিমেশনে নির্দিষ্ট কী পয়েন্টগুলিতে মান নির্দিষ্ট করার জন্য স্পেস। -
repeatable
: সময়কাল-ভিত্তিক স্পেক যা নির্দিষ্ট সংখ্যক বার চালায়,RepeatMode
দ্বারা নির্দিষ্ট করা হয়। -
infiniteRepeatable
: সময়কাল ভিত্তিক স্পেক যা চিরকাল চলে। -
snap
: তাত্ক্ষণিকভাবে কোনও অ্যানিমেশন ছাড়াই শেষ মানটিতে স্ন্যাপ করে।
অ্যানিমেশনসপেকগুলি সম্পর্কে আরও তথ্যের জন্য সম্পূর্ণ ডকুমেন্টেশন পড়ুন।
অতিরিক্ত সম্পদ
রচনাটিতে মজাদার অ্যানিমেশনগুলির আরও উদাহরণের জন্য, নিম্নলিখিতটি একবার দেখুন:
- কমপোজে 5 দ্রুত অ্যানিমেশন
- কমপোজে জেলিফিশ মুভ করা
- কমপোজে
AnimatedContent
কাস্টমাইজ করা - কমপোজে ফাংশনগুলি স্বাচ্ছন্দ্য দেওয়া
রচনাটিতে অনেকগুলি অন্তর্নির্মিত অ্যানিমেশন প্রক্রিয়া রয়েছে এবং কোনটি বেছে নেওয়া উচিত তা জানতে পেরে এটি অপ্রতিরোধ্য হতে পারে। নীচে সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রে একটি তালিকা রয়েছে। আপনার কাছে উপলব্ধ বিভিন্ন এপিআই বিকল্পগুলির সম্পূর্ণ সেট সম্পর্কে আরও বিশদ তথ্যের জন্য, সম্পূর্ণ রচনা অ্যানিমেশন ডকুমেন্টেশন পড়ুন।
সাধারণ কমপোজেবল বৈশিষ্ট্যগুলি অ্যানিমেটেড
রচনাটি সুবিধাজনক এপিআই সরবরাহ করে যা আপনাকে অনেকগুলি সাধারণ অ্যানিমেশন ব্যবহারের ক্ষেত্রে সমাধান করতে দেয়। এই বিভাগটি দেখায় যে আপনি কীভাবে একটি কম্পোজেবলের সাধারণ বৈশিষ্ট্যগুলি সঞ্চার করতে পারেন।
অ্যানিমেট উপস্থিত / অদৃশ্য
একটি কমপোজেবল আড়াল বা প্রদর্শন করতে 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
অবশেষে আইটেমটি রচনা থেকে সরিয়ে দেয়।
অ্যানিমেট ব্যাকগ্রাউন্ড রঙ
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()
ব্যবহার করতে পারেন 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
ব্যবহার করতে পারেন।
কমপোজেবলের অ্যানিমেট অবস্থান
একটি কমপোজেবলের অবস্থান সঞ্চার করতে, 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) ) }
একটি কমপোজেবলের প্যাডিং অ্যানিমেট
একটি কমপোজেবলের প্যাডিং অ্যানিমেট করতে, 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{ }
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
কমপোজেবল ব্যবহার করুন এবং উচ্চতা সম্পত্তিটি প্রতি রাজ্যে বিভিন্ন মানগুলিতে সেট করুন।
অ্যানিমেট পাঠ্য স্কেল, অনুবাদ বা ঘূর্ণন
অ্যানিমেটিং স্কেল, অনুবাদ বা পাঠ্যের ঘূর্ণন করার সময়, 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) ) }
পাঠ্য রঙ অ্যানিমেট
পাঠ্য রঙ সঞ্চার করতে, 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
করুটাইন এপিআই ব্যবহার করুন। অন্যের পরে 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)) }
একযোগে অ্যানিমেশন তৈরি করুন
একযোগে অ্যানিমেশনগুলি অর্জনের জন্য করুটাইন এপিআই ( 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
: তাত্ক্ষণিকভাবে কোনও অ্যানিমেশন ছাড়াই শেষ মানটিতে স্ন্যাপ করে।
অ্যানিমেশনসপেকগুলি সম্পর্কে আরও তথ্যের জন্য সম্পূর্ণ ডকুমেন্টেশন পড়ুন।
অতিরিক্ত সম্পদ
রচনাটিতে মজাদার অ্যানিমেশনগুলির আরও উদাহরণের জন্য, নিম্নলিখিতটি একবার দেখুন:
- কমপোজে 5 দ্রুত অ্যানিমেশন
- কমপোজে জেলিফিশ মুভ করা
- কমপোজে
AnimatedContent
কাস্টমাইজ করা - কমপোজে ফাংশনগুলি স্বাচ্ছন্দ্য দেওয়া