ফ্র্যাগমেন্ট ট্রানজ্যাকশন

রানটাইমে, ব্যবহারকারীর ইন্টার‍্যাকশনের উত্তরে, FragmentManager ফ্র্যাগমেন্ট যোগ, সরিয়ে দেওয়া, পরিবর্তন এবং অন্যান্য অ্যাকশন পারফর্ম করতে পারে। আপনি ফ্র্যাগমেন্টে যে পরিবর্তন করেন তার প্রতিটি সেটকে ট্রানজ্যাকশন বলা হয় এবং FragmentTransaction ক্লাসের মাধ্যমে প্রদান করা API ব্যবহার করে ট্রানজ্যাকশনের মধ্যে কী করতে হবে তা আপনি নির্দিষ্ট করতে পারবেন। আপনি একাধিক অ্যাকশনকে একটি ট্রানজ্যাকশনে গ্রুপ করতে পারেন—যেমন, একটি ট্রানজ্যাকশন একাধিক ফ্র্যাগমেন্ট যোগ বা পরিবর্তন করতে পারে। এই গ্রুপিং তখন উপযোগী হতে পারে যখন আপনার কাছে একই স্ক্রিনে একাধিক সিবলিং ফ্র্যাগমেন্ট দেখানো হয়, যেমন স্প্লিট ভিউতে।

আপনি প্রতিটি ট্রানজ্যাকশন FragmentManager দ্বারা ম্যানেজ করা ব্যাক স্ট্যাকে সেভ করতে পারবেন, যা ব্যবহারকারীকে ফ্র্যাগমেন্ট পরিবর্তনের মাধ্যমে পিছনে নেভিগেট করার অনুমতি দেয়—অ্যাক্টিভিটির মাধ্যমে পিছনে নেভিগেট করার মতোই।

আপনি FragmentManager থেকে FragmentTransaction-এর ইনস্ট্যান্স পেতে পারেন beginTransaction()-এ কল করে, যেমন নিম্নলিখিত উদাহরণে দেখানো হয়েছে:

Kotlin

val fragmentManager = ...
val fragmentTransaction = fragmentManager.beginTransaction()

জাভা

FragmentManager fragmentManager = ...
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

প্রতিটি FragmentTransaction-এর জন্য করা ফাইনাল কলে ট্রানজ্যাকশন সম্পূর্ণ করতে হবে। commit() কল FragmentManager-কে সিগন্যাল দেয় যে সব অপারেশন ট্রানজ্যাকশনে যোগ করা হয়েছে।

Kotlin

val fragmentManager = ...
// The fragment-ktx module provides a commit block that automatically
// calls beginTransaction and commit for you.
fragmentManager.commit {
    // Add operations here
}

জাভা

FragmentManager fragmentManager = ...
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

// Add operations here

fragmentTransaction.commit();

ফ্র্যাগমেন্ট স্টেট পরিবর্তনের ক্রম আবার সাজানোর অনুমতি দিন

প্রতিটি FragmentTransaction-এর setReorderingAllowed(true) ব্যবহার করা উচিত:

Kotlin

supportFragmentManager.commit {
    ...
    setReorderingAllowed(true)
}

জাভা

FragmentManager fragmentManager = ...
fragmentManager.beginTransaction()
    ...
    .setReorderingAllowed(true)
    .commit();

আচরণগত সামঞ্জস্যের জন্য, ডিফল্ট হিসেবে রিঅর্ডারিং ফ্ল্যাগ চালু করা হয় না। তবে, FragmentManager-কে আপনার FragmentTransaction সঠিকভাবে এক্সিকিউট করার অনুমতি দিতে এটি প্রয়োজন, বিশেষ করে যখন এটি ব্যাক স্ট্যাকে কাজ করে এবং অ্যানিমেশন ও ট্রানজিশন রান করে। ফ্ল্যাগ চালু করলে এটি নিশ্চিত করা যায় যে একাধিক ট্রানজ্যাকশন একসাথে করা হলে, কোনও ইন্টারমিডিয়েট ফ্র্যাগমেন্ট (অর্থাৎ, যেগুলি যোগ করা হয়েছে এবং তারপরেই সাথে সাথে পরিবর্তন করা হয়েছে) লাইফসাইকেল পরিবর্তনের মধ্যে দিয়ে যায় না অথবা সেগুলির অ্যানিমেশন বা ট্রানজিশন এক্সিকিউট করা হয় না। মনে রাখবেন যে এই ফ্ল্যাগ ট্রানজ্যাকশনের প্রাথমিক এক্সিকিউশন এবং popBackStack()-এর মাধ্যমে ট্রানজ্যাকশন রিভার্স করা, দুটির উপরেই প্রভাব ফেলে।

ফ্র্যাগমেন্ট যোগ করা এবং সরানো

FragmentManager-এ ফ্র্যাগমেন্ট যোগ করতে, ট্রানজ্যাকশনে add() কল করুন। এই পদ্ধতি ফ্র্যাগমেন্টের জন্য কন্টেনারের আইডি এবং আপনি যে ফ্র্যাগমেন্ট যোগ করতে চান সেটির ক্লাস নাম রিসিভ করে। যোগ করা ফ্র্যাগমেন্ট RESUMED স্টেটে সরানো হয়েছে। কন্টেনারটি যেন একটি FragmentContainerView হয় যা ভিউ হায়ারার্কির অংশ, সেটি বিশেষভাবে সাজেস্ট করা হয়।

হোস্ট থেকে ফ্র্যাগমেন্ট সরাতে, remove() কল করুন, findFragmentById() বা findFragmentByTag()-এর মাধ্যমে ফ্র্যাগমেন্ট ম্যানেজার থেকে পাওয়া ফ্র্যাগমেন্ট ইনস্ট্যান্স পাস করুন। ফ্র্যাগমেন্টের ভিউ আগে কোনও কন্টেনারে যোগ করা হয়ে থাকলে, এই পর্যায়ে কন্টেনার থেকে ভিউটি সরিয়ে দেওয়া হয়। সরানো ফ্র্যাগমেন্ট DESTROYED স্টেটে সরানো হয়েছে।

আপনার দেওয়া নতুন ফ্র্যাগমেন্ট ক্লাসের ইনস্ট্যান্স দিয়ে কন্টেনারে আগে থেকে থাকা ফ্র্যাগমেন্ট রিপ্লেস করতে replace() ব্যবহার করুন। replace() কল করার অর্থ হল কন্টেনারে ফ্র্যাগমেন্ট সহ remove() কল করা এবং একই কন্টেনারে নতুন ফ্র্যাগমেন্ট যোগ করা।

নিম্নলিখিত কোড স্নিপেট থেকে আপনি জানতে পারবেন যে কীভাবে একটি ফ্র্যাগমেন্টের পরিবর্তে অন্য একটি ফ্র্যাগমেন্ট ব্যবহার করতে হয়:

Kotlin

// Create new fragment
val fragmentManager = // ...

// Create and commit a new transaction
fragmentManager.commit {
    setReorderingAllowed(true)
    // Replace whatever is in the fragment_container view with this fragment
    replace<ExampleFragment>(R.id.fragment_container)
}

জাভা

// Create new fragment and transaction
FragmentManager fragmentManager = ...
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setReorderingAllowed(true);

// Replace whatever is in the fragment_container view with this fragment
transaction.replace(R.id.fragment_container, ExampleFragment.class, null);

// Commit the transaction
transaction.commit();

এই উদাহরণে, ExampleFragment-এর নতুন ইনস্ট্যান্স ফ্র্যাগমেন্টকে প্রতিস্থাপন করে, যদি কিছু থাকে, যা বর্তমানে R.id.fragment_container দ্বারা চিহ্নিত লেআউট কন্টেনারে রয়েছে।

ডিফল্ট হিসেবে, FragmentTransaction-এ করা পরিবর্তন ব্যাক স্ট্যাকে যোগ করা হয় না। এইসব পরিবর্তন সেভ করতে, আপনি FragmentTransaction-এ addToBackStack() নম্বরে কল করতে পারেন। আরও তথ্যের জন্য, ফ্র্যাগমেন্ট ম্যানেজার দেখুন।

কমিট অ্যাসিঙ্ক্রোনাস

commit() কল করলে সাথে সাথে ট্রানজ্যাকশন হয় না। বরং, ট্রানজ্যাকশনটি যত তাড়াতাড়ি সম্ভব মূল UI থ্রেডে চালানোর জন্য শিডিউল করা হয়। তবে, প্রয়োজন হলে, আপনার UI থ্রেডে ফ্র্যাগমেন্ট ট্রানজ্যাকশন অবিলম্বে চালানোর জন্য আপনি commitNow() কল করতে পারেন।

মনে রাখবেন যে commitNow, addToBackStack-এর সাথে কাজ করে না। বিকল্প হিসেবে, আপনি commit() -এর জমা দেওয়া সব বাকি থাকা FragmentTransactions এক্সিকিউট করতে পারবেন যেসব কল এখনও রান করেনি সেগুলি executePendingTransactions()-এ কল করে রান করতে পারবেন। এই পদ্ধতি addToBackStack-এর সাথে মানানসই।

বেশিরভাগ ক্ষেত্রে, commit() ব্যবহার করলেই আপনার কাজ হয়ে যাবে।

অপারেশনের ক্রম গুরুত্বপূর্ণ

FragmentTransaction-এর মধ্যে আপনি যে ক্রমে অপারেশনগুলি করেন তা গুরুত্বপূর্ণ, বিশেষ করে setCustomAnimations() ব্যবহার করার সময়। এই পদ্ধতিটি প্রদত্ত অ্যানিমেশনগুলিকে সমস্ত ফ্র্যাগমেন্ট অপারেশনে প্রয়োগ করে যা এটি অনুসরণ করে।

Kotlin

supportFragmentManager.commit {
    setCustomAnimations(enter1, exit1, popEnter1, popExit1)
    add<ExampleFragment>(R.id.container) // gets the first animations
    setCustomAnimations(enter2, exit2, popEnter2, popExit2)
    add<ExampleFragment>(R.id.container) // gets the second animations
}

জাভা

getSupportFragmentManager().beginTransaction()
        .setCustomAnimations(enter1, exit1, popEnter1, popExit1)
        .add(R.id.container, ExampleFragment.class, null) // gets the first animations
        .setCustomAnimations(enter2, exit2, popEnter2, popExit2)
        .add(R.id.container, ExampleFragment.class, null) // gets the second animations
        .commit()

ফ্র্যাগমেন্টের লাইফসাইকেল সীমিত করা

FragmentTransactions ট্রানজ্যাকশনের স্কোপের মধ্যে যোগ করা আলাদা আলাদা ফ্র্যাগমেন্টের লাইফসাইকেল স্টেটকে প্রভাবিত করতে পারে। FragmentTransaction তৈরি করার সময়, setMaxLifecycle() প্রদত্ত ফ্র্যাগমেন্টের জন্য সর্বাধিক স্টেট সেট করে। যেমন, ViewPager2 setMaxLifecycle() ব্যবহার করে অফ-স্ক্রিন ফ্র্যাগমেন্টকে STARTED স্টেটে সীমাবদ্ধ করে।

ফ্র্যাগমেন্টের ভিউ দেখানো এবং লুকানো

কন্টেনারে যোগ করা ফ্র্যাগমেন্টের ভিউ দেখাতে ও লুকাতে FragmentTransaction পদ্ধতি show() এবং hide() ব্যবহার করুন। এই পদ্ধতিগুলি ফ্র্যাগমেন্টের লাইফসাইকেলকে প্রভাবিত না করেই ফ্র্যাগমেন্টের ভিউয়ের দৃশ্যমানতা সেট করে।

ফ্র্যাগমেন্টের মধ্যে ভিউয়ের দৃশ্যমানতা টগল করার জন্য ফ্র্যাগমেন্ট ট্রানজ্যাকশন ব্যবহার করার প্রয়োজন না হলেও, এইসব পদ্ধতি সেইসব ক্ষেত্রে উপযোগী যেখানে আপনি চান যে দৃশ্যমানতার স্ট্যাটাসে পরিবর্তন ব্যাক স্ট্যাকে ট্রানজ্যাকশনের সাথে যুক্ত হোক।

ফ্র্যাগমেন্ট অ্যাটাচ ও ডিটাচ করা

FragmentTransaction পদ্ধতি detach() UI থেকে ফ্র্যাগমেন্ট আলাদা করে দেয়, এর ভিউ হায়ারার্কি নষ্ট করে দেয়। ফ্র্যাগমেন্টটি ব্যাক স্ট্যাকে রাখার সময় যে অবস্থায় ছিল সেই একই অবস্থায় (STOPPED) থাকে। এর অর্থ হল, ফ্র্যাগমেন্টটি UI থেকে সরানো হয়েছে কিন্তু এখনও ফ্র্যাগমেন্ট ম্যানেজার দ্বারা ম্যানেজ করা হয়।

attach() পদ্ধতিটি একটি ফ্র্যাগমেন্টকে আবার অ্যাটাচ করে যেখান থেকে এটি আগে ডিটাচ করা হয়েছিল। এর ফলে, এর ভিউ হায়ারার্কি আবার তৈরি হয়, UI-এর সাথে অ্যাটাচ করা হয় এবং দেখানো হয়।

যেহেতু FragmentTransaction-কে একটি একক অ্যাটমিক সেট অফ অপারেশন হিসেবে বিবেচনা করা হয়, তাই একই ট্রানজ্যাকশনে একই ফ্র্যাগমেন্ট ইনস্ট্যান্সে detach এবং attach-কে কল করলে কার্যত একে অপরকে বাতিল করে দেয়, যার ফলে ফ্র্যাগমেন্টের UI-এর ধ্বংস এবং অবিলম্বে রিক্রিয়েশন এড়ানো যায়। আপনি যদি কোনও ফ্র্যাগমেন্ট ডিটাচ করে সাথে সাথে আবার অ্যাটাচ করতে চান, তাহলে আলাদা আলাদা ট্রানজ্যাকশন ব্যবহার করুন, commit() ব্যবহার করলে executePendingOperations() দিয়ে আলাদা করুন।