ভাগ করা উপাদান স্থানান্তর কাস্টমাইজ করুন

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

অ্যানিমেশন স্পেক

আকার এবং অবস্থানের গতিবিধির জন্য ব্যবহৃত অ্যানিমেশন স্পেক পরিবর্তন করতে, আপনি Modifier.sharedElement() এ একটি ভিন্ন boundsTransform প্যারামিটার নির্দিষ্ট করতে পারেন। এটি প্রাথমিক Rect অবস্থান এবং লক্ষ্য Rect অবস্থান প্রদান করে।

উদাহরণস্বরূপ, পূর্ববর্তী উদাহরণের লেখাটিকে একটি আর্ক মোশনের সাথে সরানোর জন্য, একটি keyframes স্পেক ব্যবহার করার জন্য boundsTransform প্যারামিটারটি নির্দিষ্ট করুন:

val textBoundsTransform = BoundsTransform { initialBounds, targetBounds ->
    keyframes {
        durationMillis = boundsAnimationDurationMillis
        initialBounds at 0 using ArcMode.ArcBelow using FastOutSlowInEasing
        targetBounds at boundsAnimationDurationMillis
    }
}
Text(
    "Cupcake", fontSize = 28.sp,
    modifier = Modifier.sharedBounds(
        rememberSharedContentState(key = "title"),
        animatedVisibilityScope = animatedVisibilityScope,
        boundsTransform = textBoundsTransform
    )
)

আপনি যেকোনো AnimationSpec ব্যবহার করতে পারেন। এই উদাহরণে একটি keyframes spec ব্যবহার করা হয়েছে।

চিত্র ১. বিভিন্ন boundsTransform দেখানোর উদাহরণ পরামিতি রূপান্তর করুন

আকার পরিবর্তন মোড

দুটি ভাগ করা সীমানার মধ্যে অ্যানিমেট করার সময়, আপনি resizeMode প্যারামিটারটি RemeasureToBounds অথবা ScaleToBounds এ সেট করতে পারেন। এই প্যারামিটারটি নির্ধারণ করে যে দুটি অবস্থার মধ্যে ভাগ করা উপাদান কীভাবে রূপান্তরিত হয়। ScaleToBounds প্রথমে লুকহেড (অথবা লক্ষ্য) সীমাবদ্ধতা দিয়ে চাইল্ড লেআউট পরিমাপ করে। তারপর, সন্তানের স্থিতিশীল লেআউটটি ভাগ করা সীমানার সাথে মানানসই করে স্কেল করা হয়। ScaleToBounds স্টেটগুলির মধ্যে একটি "গ্রাফিক্যাল স্কেল" হিসাবে ভাবা যেতে পারে।

বিপরীতে, RemeasureToBounds লক্ষ্য আকারের উপর ভিত্তি করে অ্যানিমেটেড স্থির সীমাবদ্ধতা সহ sharedBounds এর চাইল্ড লেআউটকে পুনরায় পরিমাপ এবং পুনরায় লেআউট করে। পুনঃপরিমাপটি সীমার আকার পরিবর্তনের মাধ্যমে ট্রিগার করা হয়, যা সম্ভাব্যভাবে প্রতিটি ফ্রেমের জন্য হতে পারে।

Text কম্পোজেবলের জন্য, ScaleToBounds সুপারিশ করা হয়, কারণ এটি বিভিন্ন লাইনে টেক্সটের রিলেআউট এবং রিফ্লোয়িং এড়ায়। RemeasureToBounds সুপারিশ করা হয় বিভিন্ন আকৃতির অনুপাতের সীমানার জন্য, এবং যদি আপনি দুটি ভাগ করা উপাদানের মধ্যে তরল ধারাবাহিকতা চান।

দুটি আকার পরিবর্তন মোডের মধ্যে পার্থক্য নিম্নলিখিত উদাহরণগুলিতে দেখা যাবে:

ScaleToBounds

RemeasureToBounds

চূড়ান্ত লেআউটে যান

ডিফল্টরূপে, দুটি লেআউটের মধ্যে স্থানান্তরের সময়, লেআউটের আকার তার শুরু এবং চূড়ান্ত অবস্থার মধ্যে অ্যানিমেট করে। টেক্সটের মতো কন্টেন্ট অ্যানিমেট করার সময় এটি অবাঞ্ছিত আচরণ হতে পারে।

নিচের উদাহরণে "Lorem Ipsum" বর্ণনামূলক টেক্সটটি দুটি ভিন্ন উপায়ে স্ক্রিনে প্রবেশ করছে তা দেখানো হয়েছে। প্রথম উদাহরণে, কন্টেইনারটি আকারে বৃদ্ধি পাওয়ার সাথে সাথে টেক্সটটি প্রবেশের সাথে সাথে রিফ্লো হয়। দ্বিতীয় উদাহরণে টেক্সটটি বৃদ্ধি পাওয়ার সাথে সাথে রিফ্লো হয় না। Modifier.skipToLookaheadSize() যোগ করলে রিফ্লো বৃদ্ধির সাথে সাথে বাধা পায়।

কোন Modifier.skipToLookahead() নেই - লক্ষ্য করুন "লোরেম ইপসাম" পাঠ্য প্রবাহিত হচ্ছে

Modifier.skipToLookahead() - লক্ষ্য করুন যে "Lorem Ipsum" লেখাটি অ্যানিমেশনের শুরুতে তার চূড়ান্ত অবস্থা ধরে রেখেছে।

ক্লিপ এবং ওভারলে

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

এটি অন্যান্য নন-শেয়ার্ড UI এলিমেন্টের উপরে রেন্ডার করবে। ট্রানজিশন শেষ হয়ে গেলে, এলিমেন্টটি ওভারলে থেকে তার নিজস্ব DrawScope এ চলে যাবে।

একটি শেয়ার করা এলিমেন্টকে শেইপে ক্লিপ করতে, স্ট্যান্ডার্ড Modifier.clip() ফাংশনটি ব্যবহার করুন। এটিকে sharedElement() পরে রাখুন:

Image(
    painter = painterResource(id = R.drawable.cupcake),
    contentDescription = "Cupcake",
    modifier = Modifier
        .size(100.dp)
        .sharedElement(
            rememberSharedContentState(key = "image"),
            animatedVisibilityScope = this@AnimatedContent
        )
        .clip(RoundedCornerShape(16.dp)),
    contentScale = ContentScale.Crop
)

যদি আপনার নিশ্চিত করতে হয় যে কোনও শেয়ার্ড এলিমেন্ট কখনও প্যারেন্ট কন্টেইনারের বাইরে রেন্ডার না হয়, তাহলে আপনি sharedElement()clipInOverlayDuringTransition সেট করতে পারেন। ডিফল্টরূপে, নেস্টেড শেয়ার্ড বাউন্ডের জন্য, clipInOverlayDuringTransition প্যারেন্ট sharedBounds() থেকে ক্লিপ পাথ ব্যবহার করে।

শেয়ার্ড এলিমেন্ট ট্রানজিশনের সময় নির্দিষ্ট UI এলিমেন্ট, যেমন বটম বার বা ফ্লোটিং অ্যাকশন বোতাম, সবসময় উপরে রাখার জন্য, Modifier.renderInSharedTransitionScopeOverlay() ব্যবহার করুন। ডিফল্টরূপে, শেয়ার্ড ট্রানজিশন সক্রিয় থাকাকালীন এই মডিফায়ার কন্টেন্টকে ওভারলেতে রাখে।

উদাহরণস্বরূপ, Jetsnack-এ, BottomAppBar টি শেয়ার্ড এলিমেন্টের উপরে রাখতে হবে যতক্ষণ না স্ক্রিনটি দৃশ্যমান হয়। কম্পোজেবলে মডিফায়ার যোগ করলে এটি উঁচুতে থাকে।

Modifier.renderInSharedTransitionScopeOverlay() ছাড়া

Modifier.renderInSharedTransitionScopeOverlay() সহ

আপনি হয়তো চাইবেন যে আপনার নন-শেয়ার্ড কম্পোজেবলটি অ্যানিমেট হয়ে যাক এবং ট্রানজিশনের আগে অন্যান্য কম্পোজেবলের উপরে থাকুক। এই ধরনের ক্ষেত্রে, শেয়ার্ড এলিমেন্ট ট্রানজিশন চলাকালীন কম্পোজেবলটিকে অ্যানিমেট করতে renderInSharedTransitionScopeOverlay().animateEnterExit() ব্যবহার করুন:

JetsnackBottomBar(
    modifier = Modifier
        .renderInSharedTransitionScopeOverlay(
            zIndexInOverlay = 1f,
        )
        .animateEnterExit(
            enter = fadeIn() + slideInVertically {
                it
            },
            exit = fadeOut() + slideOutVertically {
                it
            }
        )
)

চিত্র ২। অ্যানিমেশন ট্রানজিশনের সাথে সাথে নিচের অ্যাপ বারটি ভেতরে এবং বাইরে স্লাইড করছে।

বিরল ক্ষেত্রে যখন আপনি চান যে আপনার শেয়ার্ড এলিমেন্টটি ওভারলেতে রেন্ডার না হোক, তখন আপনি sharedElement()renderInOverlayDuringTransition false এ সেট করতে পারেন।

শেয়ার করা এলিমেন্টের আকারে পরিবর্তনের বিষয়ে ভাইবোন লেআউটগুলিকে অবহিত করুন

ডিফল্টরূপে, sharedBounds() এবং sharedElement() লেআউট ট্রানজিশনের সময় কোনও আকারের পরিবর্তনের বিষয়ে প্যারেন্ট কন্টেইনারকে অবহিত করে না।

প্যারেন্ট কন্টেইনারে ট্রানজিশনের সময় আকার পরিবর্তনের জন্য, placeHolderSize প্যারামিটারটি PlaceHolderSize.animatedSize এ পরিবর্তন করুন। এটি করার ফলে আইটেমটি বৃদ্ধি বা সঙ্কুচিত হয়। লেআউটের অন্যান্য সমস্ত আইটেম পরিবর্তনের সাথে সাড়া দেয়।

PlaceholderSize.contentSize (ডিফল্ট)

PlaceholderSize.animatedSize

(লক্ষ্য করুন যে তালিকার অন্যান্য আইটেমগুলি কীভাবে একটি আইটেমের বৃদ্ধির প্রতিক্রিয়ায় নীচের দিকে নেমে যায়)