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

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

অ্যানিমেশন বৈশিষ্ট্য

আকার এবং অবস্থান আন্দোলনের জন্য ব্যবহৃত অ্যানিমেশন স্পেক পরিবর্তন করতে, আপনি 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 স্পেক ব্যবহার করে.

চিত্র 1. বিভিন্ন boundsTransform প্যারামিটার দেখানোর উদাহরণ

রিসাইজ মোড

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

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

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

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

ScaleToBounds

RemeasureToBounds

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

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

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

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

Modifier.skipToLookahead() - লক্ষ্য করুন "লোরেম ইপসাম" টেক্সটটি অ্যানিমেশনের শুরুতে তার চূড়ান্ত অবস্থা বজায় রাখে

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

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

এটি অন্যান্য অ-ভাগ করা 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
            }
        )
)

চিত্র 2. অ্যানিমেশন ট্রানজিশন হিসাবে নীচের অ্যাপ বার ভিতরে এবং বাইরে স্লাইডিং

বিরল ক্ষেত্রে যে আপনি চান যে আপনার ভাগ করা উপাদানটি ওভারলেতে রেন্ডার না হোক, আপনি sharedElement() -এ renderInOverlayDuringTransition কে মিথ্যাতে সেট করতে পারেন।

ভাগ করা উপাদান আকারে পরিবর্তনের ভাইবোন লেআউটগুলিকে অবহিত করুন৷

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

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

PlaceholderSize.contentSize (ডিফল্ট)

PlaceholderSize.animatedSize

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