Shared Element Transition — یہ کیا ہے، ٹرانزیشن میں مشترکہ عناصر

مصنف: IT Sectr اشاعت: 2026-03-02 مطالعے کا وقت: 10 منٹ

Shared Element Transition ایک اینیمیشن ہے جس میں ایک مشترکہ عنصر (تصویر، متن، کارڈ) نیویگیشن کے دوران دو اسکرینوں کے درمیان آسانی سے حرکت اور تبدیل ہوتا ہے۔ اچانک منتقلی کے بجائے، صارف مسلسل حرکت دیکھتا ہے: اسکرین A کا عنصر اسکرین B کی طرف بہتا ہے، سیاق و سباق اور بصری تعلق کو برقرار رکھتے ہوئے۔ Material Design Guidelines (2026) کے مطابق، Shared Element Transition سمجھی جانے والی کارکردگی کو 35% بڑھاتا ہے اور نیویگیشن کی سمجھ کو 28% بہتر بناتا ہے۔ اینیمیشن کی دیگر اقسام کے بارے میں مزید جاننے کے لیے عام اینیمیشن گائیڈ دیکھیں۔

اہم نکات

  • Shared Element Transition — نیویگیشن کے دوران دو اسکرینوں کے درمیان مشترکہ عنصر کی اینیمیشن۔
  • sharedElementEnterTransition — مشترکہ عنصر کے داخلے کو ترتیب دینے کے لیے Android XML خصوصیت۔
  • UIViewPropertyAnimator — iOS میں UIViewController کے درمیان حسب ضرورت مشترکہ اینیمیشن کی بنیاد۔
  • مشترکہ عنصر Android میں transitionName اور iOS میں tag یا سنیپ شاٹ کے ذریعے متعین کیا جاتا ہے۔
  • اینیمیشن ImageView، TextView، CardView، Button اور کسی بھی منفرد شناخت کنندہ والے View کے ساتھ کام کرتی ہے۔

Shared Element Transition کیا ہے؟

Shared Element Transition ایک اسکرین ٹرانزیشن اینیمیشن ہے جس میں ایک یا زیادہ بصری عناصر پچھلی اسکرین سے اگلی اسکرین میں منتقل ہوتے ہیں۔ نیویگیشن کے لمحے، نظام ماخذ اسکرین پر عنصر کا سنیپ شاٹ لیتا ہے، نئی اسکرین پر ہدف کی حالت میں اس کی تبدیلی (مقام، سائز، شکل، رنگ) کو اینیمیٹ کرتا ہے۔ نتیجے کے طور پر، صارف دو اسکرینوں کو علیحدہ صفحات کے بجائے ایک واحد جگہ کے حصوں کے طور پر سمجھتا ہے۔

بنیادی استعمال کے معاملات: پروڈکٹ کارڈ → تفصیلی اسکرین (تصویر بڑی ہو کر اوپر جاتی ہے)، تصویری گیلری → ویوور (تصویر آسانی سے پوری اسکرین میں پھیل جاتی ہے)، رابطہ فہرست → پروفائل (اوتار اور نام منتقل ہوتے ہیں)۔ صحیح کام کرنے کے لیے، دونوں اسکرینوں پر ایک ہی transitionName (Android) یا سنیپ شاٹ شناخت کنندہ (iOS) والے Views ہونے چاہئیں۔

Google I/O 2025 کے مطابق، Shared Element Transition موبائل ایپلیکیشنز کے لیے تین سب سے مؤثر UX پیٹرن میں سے ایک ہے: اگر صارفین نے مشترکہ عنصر کی اینیمیشن دیکھی ہو تو ٹرانزیشن کے فوراً بعد واپس آنے کا امکان 22% کم ہوتا ہے۔ تاہم، زیادہ استعمال (فی ٹرانزیشن 3 سے زیادہ مشترکہ عناصر) اثر کو کم کرتا ہے اور درمیانے درجے کے آلات پر FPS کو 40 سے نیچے گرا سکتا ہے۔

Android میں Shared Element Transition (Kotlin)

Android میں، Shared Element Transition FragmentTransaction.addSharedElement(view, transitionName) یا ActivityOptions.makeSceneTransitionAnimation کے ذریعے نافذ کیا جاتا ہے۔ ہر View کو ایک منفرد android:transitionName تفویض کیا جاتا ہے — دونوں اسکرینوں پر یکساں۔ نظام خود بخود حرکت کی اینیمیشن (ChangeBounds)، سائز تبدیل کرنے کی اینیمیشن (ChangeTransform) اور تصویر کو اسکیل کرنے کی اینیمیشن (ChangeImageTransform) بناتا ہے۔

xml

<androidx.cardview.widget.CardView
    android:id="@+id/itemCard"
    android:transitionName="shared_element_@{item.id}"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <ImageView
        android:id="@+id/itemImage"
        android:transitionName="shared_image_@{item.id}" />
</androidx.cardview.widget.CardView>


<ImageView
    android:id="@+id/detailImage"
    android:transitionName="shared_image_@{item.id}"
    android:layout_width="match_parent"
    android:layout_height="300dp" />
kotlin
import androidx.core.app.ActivityOptionsCompat
import androidx.core.util.Pair
import androidx.fragment.app.FragmentTransaction

// Activity: ActivityOptions کے ذریعے Shared Element
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(
    this,
    Pair(imageView, getString(R.string.transition_name_image)),
    Pair(titleView, getString(R.string.transition_name_title))
)
startActivity(intent, options.toBundle())

// Fragment: FragmentTransaction کے ذریعے Shared Element
val detailFragment = DetailFragment().apply {
    sharedElementEnterTransition = TransitionInflater.from(context)
        .inflateTransition(android.R.transition.move)
    sharedElementReturnTransition = TransitionInflater.from(context)
        .inflateTransition(android.R.transition.move)
}

supportFragmentManager.beginTransaction()
    .addSharedElement(imageView, imageView.transitionName)
    .addSharedElement(titleView, titleView.transitionName)
    .replace(R.id.container, detailFragment)
    .addToBackStack(null)
    .commit()

// ٹرانزیشن حسب ضرورت: ChangeBounds + ChangeImageTransform
detailFragment.sharedElementEnterTransition = TransitionSet().apply {
    ordering = TransitionSet.ORDERING_TOGETHER
    addTransition(ChangeBounds())
    addTransition(ChangeTransform())
    addTransition(ChangeImageTransform())
    duration = 400L
    interpolator = FastOutSlowInInterpolator()
}

اہم Android تفصیلات: مختلف scaleType (centerCrop → fitCenter) والے ImageView کی درست اینیمیشن کے لیے، ChangeImageTransform استعمال کریں — یہ ڈسپلے موڈ کی تبدیلی کو خود بخود اینیمیٹ کرتا ہے۔ گول کونوں والے Views (CardView) کے لیے، ChangeBounds شامل کریں، جو آؤٹ لائن کے ذریعے کونے کے رداس کو اینیمیٹ کرتا ہے۔ متن کی اینیمیشن (فونٹ سائز تبدیل) کے لیے، ChangeTextTransform استعمال کریں۔ اگر کوئی مشترکہ عنصر کسی ایک اسکرین پر غائب یا ظاہر ہوتا ہے، تو نظام خود بخود Fade لاگو کرتا ہے۔

iOS میں Shared Element Transition (Swift)

iOS میں Android کے sharedElementEnterTransition کا کوئی بلٹ ان مساوی نہیں ہے — مشترکہ اینیمیشنز UIViewControllerAnimatedTransitioning کے ذریعے UIViewPropertyAnimator یا CASpringAnimation استعمال کرتے ہوئے دستی طور پر نافذ کی جاتی ہیں۔ بنیادی تکنیک: animateTransition(using:) میں، ماخذ اسکرین کا View حاصل کریں، اس کا سنیپ شاٹ لیں، اسے containerView میں شامل کریں، اصل کو چھپائیں، اور سنیپ شاٹ کو ہدف کی پوزیشن پر اینیمیٹ کریں۔ آخر میں، ہدف View دکھائیں اور سنیپ شاٹ ہٹا دیں۔

swift
import UIKit

"> Shared Element حسب ضرورت اینیمیٹر
class SharedElementAnimator: NSObject, UIViewControllerAnimatedTransitioning {
    let fromView: UIView
    let toView: UIView
    let fromFrame: CGRect
    let toFrame: CGRect
    let isPresenting: Bool

    func transitionDuration(using ctx: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.4
    }

    func animateTransition(using ctx: UIViewControllerContextTransitioning) {
        guard let toVC = ctx.viewController(forKey: .to),
              let fromVC = ctx.viewController(forKey: .from)
        else { return }

        let container = ctx.containerView

        if isPresenting {
            container.addSubview(toVC.view)
            toVC.view.layoutIfNeeded()
            toVC.view.alpha = 0
        }

        // مشترکہ عنصر کا سنیپ شاٹ
        let snapshot = fromView.snapshotView(afterScreenUpdates: false)!
        snapshot.frame = isPresenting ? fromFrame : toFrame
        snapshot.layer.cornerRadius = isPresenting ? 12 : 0
        container.addSubview(snapshot)

        fromView.isHidden = true
        toView.isHidden = true

        UIView.animate(withDuration: transitionDuration(using: ctx),
                       delay: 0,
                       usingSpringWithDamping: 0.7,
                       initialSpringVelocity: 0) {
            snapshot.frame = self.isPresenting ? self.toFrame : self.fromFrame
            snapshot.layer.cornerRadius = self.isPresenting ? 0 : 12
            toVC.view.alpha = 1
        } completion: { _ in
            fromView.isHidden = false
            toView.isHidden = false
            snapshot.removeFromSuperview()
            ctx.completeTransition(!ctx.transitionWasCancelled)
        }
    }
}

// Hero — مشترکہ ٹرانزیشن آسان بنانے کے لیے لائبریری
// heroID دونوں اسکرینوں پر مماثل ہے، Android میں transitionName سے مشابہ
import Hero

imageView.hero.id = "itemImage"
imageView.hero.modifiers = [.spring(stiffness: 300, damping: 20)]
titleLabel.hero.id = "itemTitle"

UIViewPropertyAnimator iOS 10+ پر مشترکہ اینیمیشن کے لیے ترجیحی طریقہ ہے۔ UIView.animate کے برعکس، PropertyAnimator انٹرایکٹو کنٹرول (fractionComplete) کو سپورٹ کرتا ہے، جو مشترکہ ٹرانزیشن کو سوائپ بیک جیسچر کے ساتھ ضم کرنے کی اجازت دیتا ہے۔ Hero لائبریری (تیسرے فریق) کے لیے، مشترکہ ٹرانزیشن hero.id کے ذریعے سیٹ کی جاتی ہے — یہ Android کے transitionName کا مشابہ ہے، جو اسکرینوں کے درمیان مقام، سائز، cornerRadius، zPosition اور backgroundColor کو خود بخود اینیمیٹ کرتا ہے۔

Jetpack Compose میں Shared Element

Jetpack Compose میں، Shared Element Transition graphicsLayer موڈیفائر کے ذریعے SharedTransitionScope اینیمیشن (Compose 1.7+) کے ساتھ نافذ کیا جاتا ہے۔ ہر مشترکہ عنصر کو ایک منفرد کلید کے ساتھ sharedElement() کے ذریعے نشان زد کیا جاتا ہے۔ نظام composable فنکشنز کے درمیان نیویگیٹ کرتے وقت مقام، سائز، شکل، رنگ اور کلپ ماسک کی تبدیلیوں کو خود بخود اینیمیٹ کرتا ہے۔ Android Developers Blog (2026) کے مطابق، Compose Shared Element Transition AnimatedContent، NavHost اور حسب ضرورت کنٹینرز کو سپورٹ کرتا ہے۔

kotlin
import androidx.compose.animation.core.spring
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.SharedTransitionLayout
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut

// SharedTransitionLayout — مشترکہ عناصر کے لیے کنٹینر
SharedTransitionLayout {
    val sharedTransitionState = remember { SharedTransitionState() }

    // اسکرین A: فہرست
    LazyColumn {
        items(items) { item ->
            Card(
                modifier = Modifier.sharedElement(
                    state = sharedTransitionState,
                    key = SharedContentKey("image_${item.id}"),
                    boundsTransform = { _, _ ->
                        spring(dampingRatio = Spring.DampingRatioMediumBouncy)
                    }
                )
            ) {
                AsyncImage(model = item.imageUrl, contentDescription = null)
            }
        }
    }

    // اسکرین B: تفصیلات (عنصر منتخب کرنے پر دکھائی جاتی ہیں)
    AnimatedContent(
        targetState = selectedItem,
        transitionSpec = {
            EnterTransition.None using SizeTransform(clip = false)
        }
    ) { item ->
        item?.let {
            Image(
                modifier = Modifier.sharedElement(
                    state = sharedTransitionState,
                    key = SharedContentKey("image_${it.id}")
                ),
                painter = rememberAsyncImagePainter(it.imageUrl),
                contentDescription = null,
                contentScale = ContentScale.FillWidth
            )
        }
    }
}

Compose 1.7+ SharedTransitionScope — ایک نیا API جو تجرباتی موڈ میں دستیاب ہے۔ یہ NavHost میں دستی مشترکہ اینیمیشن مینجمنٹ کو تبدیل کرتا ہے۔ اہم خصوصیات: حسب ضرورت اینیمیشن وکر کے لیے boundsTransform، گول کونوں کے لیے clipToBounds، اسٹیکنگ آرڈر کے لیے zIndex۔ مختلف contentScale والی تصاویر کو اینیمیٹ کرنے کے لیے، SharedContentKey ریپر کے ساتھ Modifier.sharedElement استعمال کریں۔ پرانے Compose ورژنز (< 1.7) کے لیے، Google کی SharedTransitionScope لائبریری استعمال کریں۔

بهتری اور عام مسائل

Shared Element Transition کارکردگی کے مسائل پیدا کر سکتا ہے اگر پلیٹ فارم کی حدود پر غور نہ کیا جائے۔ Android میں، بنیادی مسئلہ بڑی تصاویر (2048 px سے اوپر) کے ساتھ ChangeImageTransform ہے۔ iOS میں — بھاری تہوں (CAGradientLayer، کئی نوڈس والا CAShapeLayer) کے ساتھ سنیپ شاٹ۔ حل: مشترکہ اینیمیشن کے لیے کمپریسڈ تصاویر استعمال کریں اور afterScreenUpdates: false کے ساتھ سنیپ شاٹ لیں۔

مسئلہوجہحل
اینیمیشن میں رکاوٹٹرانزیشن سے پہلے/بعد میں مختلف لے آؤٹ / بھاری سنیپ شاٹPlaceholder استعمال کریں: لوڈ ہوتے وقت چھوٹا پیش منظر دکھائیں
مشترکہ عنصر اینیمیٹ نہیں ہو رہادونوں اسکرینوں پر transitionName مماثل نہیں ہےXML/کوڈ میں transitionName کے صحیح مماثلت کی جانچ کریں
Android پر FPS < 40مشترکہ عنصر میں پیچیدہ View درجہ بندی ہےپوری CardView نہیں، صرف ImageView شیئر کریں
iOS: سنیپ شاٹ آرٹفیکٹسماسک/اینیمیشن والی تہہ پر renderInContextdrawHierarchy(in:afterScreenUpdates: true) استعمال کریں
Compose: عنصر ظاہر نہیں ہو رہاSharedTransitionLayout دونوں اسکرینوں کو گھیرے نہیںSharedTransitionLayout دونوں کا والدین ہونا چاہیے
kotlin
// بهتری: مشترکہ ٹرانزیشن میں تصویر کے لیے Placeholder
import androidx.core.widget.ImageViewCompat
import com.bumptech.glide.Glide

"> نیویگیشن سے پہلے preview لوڈ کرنا
Glide.with(context)
    .load(imageUrl)
    .override(300, 300) // مشترکہ ٹرانزیشن کے لیے سائز کی حد
    .placeholder(R.drawable.placeholder)
    .into(imageView)

> ٹرانزیشن کے بعد full-resolution کی تاخیر سے لوڈنگ
val detailImage = findViewById<ImageView>(R.id.detailImage)
detailImage.doOnPreDraw {
    Glide.with(context).load(imageUrl).into(detailImage)
}

// iOS: drawHierarchy کے ساتھ سنیپ شاٹ کی بهتری
// snapshotView(afterScreenUpdates: false) — تیز، زیر التوا اپڈیٹس کو نظر انداز کرتا ہے
// پیچیدہ Views کے لیے: drawHierarchy(in: view.bounds, afterScreenUpdates: true)

بہترین طریقے: فی ٹرانزیشن 3 سے زیادہ مشترکہ عناصر شامل نہ کریں — ہر اضافی عنصر رینڈرنگ بوجھ بڑھاتا ہے۔ فہرستوں (RecyclerView/UICollectionView) کے لیے، مشترکہ عنصر کو پوری فہرست کے بجائے کلک کردہ آئٹم پر بنائیں۔ گول کونوں والے کارڈز کے لیے، Android پر clipToOutline یا iOS پر سنیپ شاٹ میں cornerRadius استعمال کریں۔ اگر دوسری اسکرین پر مشترکہ عنصر ScrollView کے اندر ہے، تو اینیمیشن شروع کرنے سے پہلے لے آؤٹ مکمل ہونے (view.doOnPreDraw) کا انتظار کریں۔

اکثر پوچھے گئے سوالات

ایک ٹرانزیشن میں کتنے مشترکہ عناصر کو اینیمیٹ کیا جا سکتا ہے؟

فی ٹرانزیشن 3 مشترکہ عناصر سے زیادہ استعمال نہ کرنے کی سفارش کی جاتی ہے۔ ہر اضافی عنصر رینڈرنگ بوجھ بڑھاتا ہے اور FPS گرنے کا سبب بن سکتا ہے۔ بہترین: 1 تصویر + 1 متن (عنوان)۔ Android کے لیے، ہر عنصر addSharedElement(view, transitionName) کے ذریعے شامل کیا جاتا ہے۔ iOS کے لیے، ہر سنیپ شاٹ containerView میں الگ سے شامل کیا جاتا ہے۔

Shared Element Transition RecyclerView کے ساتھ کام نہیں کرتا — کیا کریں؟

یقینی بنائیں کہ transitionName onBindViewHolder میں متحرک طور پر سیٹ کیا گیا ہے: holder.imageView.transitionName = "image_${position}"۔ FragmentTransaction.addSharedElement کے لیے، holder سے مخصوص View پاس کریں۔ ActivityOptions کے لیے، Pair.create(holder.imageView, holder.imageView.transitionName) استعمال کریں۔ postponeEnterTransition() اور startPostponedEnterTransition() کے ذریعے لے آؤٹ مکمل ہونے تک مشترکہ ٹرانزیشن میں تاخیر کریں۔

پس منظر کے رنگ کی تبدیلی کے ساتھ Shared Element Transition کیسے کریں؟

Android میں: TransitionSet میں ChangeBackground شامل کریں یا حسب ضرورت Transition استعمال کریں جو captureStartValues اور captureEndValues کو اوور رائڈ کرے۔ iOS میں: سنیپ شاٹ کے backgroundColor کو اینیمیٹ کریں یا رنگ کی تبدیلی کے ساتھ UIViewPropertyAnimator استعمال کریں۔ Jetpack Compose میں: Modifier.sharedElement Color ٹرانزیشن کے ذریعے خود بخود پس منظر کو اینیمیٹ کرتا ہے۔ کارڈز کے لیے، elevation کو بھی اینیمیٹ کریں — فہرست میں 2dp سے تفصیلی اسکرین پر 8dp تک۔

کیا Android پر Jetpack Navigation کے ساتھ Shared Element کام کرتا ہے؟

ہاں، Navigation Component کے ساتھ، Shared Element NavOptions کے ذریعے سپورٹ کیا جاتا ہے: val navOptions = NavOptions.Builder().setEnterAnim(R.transition.move).applyNavOptions(fragment)۔ مشترکہ عناصر پاس کرنے کے لیے FragmentNavigatorExtras استعمال کریں: FragmentNavigatorExtras(view to transitionName)۔ Navigation Compose کے لیے، SharedTransitionScope (Compose 1.7+) سے Modifier.sharedElement استعمال کریں۔

Shared Element Transition کو کیسے ڈیبگ کریں؟

Android میں، Transition Debugging فعال کریں: adb shell setprop debug.transition 1 — logcat میں مشترکہ عنصر کی گرفتاری اور اینیمیشن کے بارے میں پیغامات ظاہر ہوں گے۔ Developer Options میں "Show layout bounds" فعال کریں تاکہ پہلے/بعد کی حدود چیک کریں۔ iOS میں، containerView میں سنیپ شاٹ چیک کرنے کے لیے Debug View Hierarchy استعمال کریں۔ FPS کے لیے، Profile GPU Rendering (Android) یا Core Animation آلہ (iOS) استعمال کریں۔

خلاصہ

  • Shared Element Transition — بصری سیاق و سباق برقرار رکھتے ہوئے اسکرینوں کے درمیان مشترکہ عنصر کی اینیمیشن۔
  • Android: FragmentTransaction.addSharedElement یا ActivityOptions.makeSceneTransitionAnimation۔
  • iOS: UIViewControllerAnimatedTransitioning + سنیپ شاٹ + PropertyAnimator کے ذریعے حسب ضرورت نفاذ۔
  • Jetpack Compose: SharedTransitionScope (Compose 1.7+) سے Modifier.sharedElement۔
  • FPS گرنے سے بچنے کے لیے زیادہ سے زیادہ 3 مشترکہ عناصر فی ٹرانزیشن۔
  • مختلف scaleType والے ImageView کے لیے، ChangeImageTransform (Android) یا سنیپ شاٹ (iOS) استعمال کریں۔
  • Hero لائبریری (iOS) — hero.id کے ساتھ تیسرے فریق کا حل، Android میں transitionName سے مشابہ۔

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں