Views-এ Compose ব্যবহার করা

আপনি আগে থেকে আছে এমন অ্যাপে Compose-ভিত্তিক UI যোগ করতে পারবেন যা View-ভিত্তিক ডিজাইন ব্যবহার করে।

সম্পূর্ণ Compose-ভিত্তিক নতুন স্ক্রিন তৈরি করতে, আপনার অ্যাক্টিভিটি থেকে setContent() মেথড কল করুন এবং আপনার পছন্দমতো কম্পোজেবল ফাংশন পাস করুন।

class ExampleActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent { // In here, we can call composables!
            MaterialTheme {
                Greeting(name = "compose")
            }
        }
    }
}

@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}

এই কোডটি দেখতে ঠিক এমন যা আপনি শুধুমাত্র Compose-এর জন্য তৈরি অ্যাপে পাবেন।

ComposeView-এর জন্য ViewCompositionStrategy

ViewCompositionStrategy কম্পোজিশন কখন ডিসপোজ করা উচিত তা নির্ধারণ করে। ডিফল্ট, ViewCompositionStrategy.Default, কম্পোজিশন ডিসপোজ করে যখন অন্তর্নিহিত ComposeView উইন্ডো থেকে ডিটাচ হয়, যদি না এটি পুলিং কন্টেনারের অংশ হয় যেমন RecyclerView। সিঙ্গেল-অ্যাক্টিভিটি কম্পোজ-অনলি অ্যাপে, এই ডিফল্ট অ্যাকশন আপনি চাইবেন, তবে, আপনি যদি নিজের কোডবেসে ইনক্রিমেন্টালভাবে কম্পোজ যোগ করেন, তাহলে এই অ্যাকশন কিছু পরিস্থিতিতে স্টেট লসের কারণ হতে পারে।

ViewCompositionStrategy পরিবর্তন করতে, setViewCompositionStrategy() মেথড কল করুন এবং অন্য একটি স্ট্র্যাটেজি প্রদান করুন।

নিচের সারণীতে বিভিন্ন পরিস্থিতি সংক্ষেপে উল্লেখ করা হয়েছে যেখানে আপনি ViewCompositionStrategy ব্যবহার করতে পারবেন:

ViewCompositionStrategy বিবরণ ও ইন্টার-অপারেবিলিটি সংক্রান্ত পরিস্থিতি
DisposeOnDetachedFromWindow উইন্ডো থেকে অন্তর্নিহিত ComposeView বিচ্ছিন্ন করা হলে কম্পোজিশনটি নিষ্পত্তি করা হবে। DisposeOnDetachedFromWindowOrReleasedFromPool-এর মাধ্যমে স্থান অধিকার করা হয়েছে।

ইন্টারঅপারেবিলিটি পরিস্থিতি:

* ComposeView এটি ভিউ হায়ারার্কির একমাত্র এলিমেন্ট কিনা অথবা মিক্সড ভিউ/কম্পোজ স্ক্রিনের (ফ্র্যাগমেন্টে নয়) প্রসঙ্গে।
DisposeOnDetachedFromWindowOrReleasedFromPool (ডিফল্ট) DisposeOnDetachedFromWindow-এর মতো, যখন কম্পোজিশন কোনও পুলিং কন্টেনারে থাকে না, যেমন RecyclerView। এটি যদি পুলিং কন্টেনারে থাকে, তাহলে পুলিং কন্টেনারটি নিজেই উইন্ডো থেকে বিচ্ছিন্ন হয়ে গেলে বা আইটেমটি বাতিল হয়ে গেলে (অর্থাৎ, পুলটি পূর্ণ হয়ে গেলে) এটি ডিসপোজ হয়ে যাবে।

ইন্টারঅপারেবিলিটি সিনারিও:

* ComposeView এটি ভিউ হায়ারার্কির একমাত্র এলিমেন্ট কিনা, অথবা একটি মিক্সড ভিউ/কম্পোজ স্ক্রিনের (ফ্র্যাগমেন্টে নয়) প্রসঙ্গে।
* ComposeView, RecyclerView-এর মতো পুলিং কন্টেনারে আইটেম হিসেবে।
DisposeOnLifecycleDestroyed প্রদান করা Lifecycle নষ্ট হয়ে গেলে কম্পোজিশন ডিসপোজ করা হবে।

ইন্টারঅপারেবিলিটি সিনারিও

* ফ্র্যাগমেন্টের ভিউতে ComposeView।
DisposeOnViewTreeLifecycleDestroyed পরবর্তী উইন্ডোর ViewTreeLifecycleOwner.get-এর মাধ্যমে ফেরত পাঠানো LifecycleOwner-এর মালিকানাধীন Lifecycle, যেটির সাথে View অ্যাটাচ করা আছে, সেটি নষ্ট হয়ে গেলে Composition ডিসপোজ করা হবে।

ইন্টারঅপারেবিলিটি সংক্রান্ত পরিস্থিতি:

* ফ্র্যাগমেন্টের View-তে ComposeView।
* ComposeView এমন একটি ভিউতে যার লাইফসাইকেল এখনও জানা যায়নি।

ComposeView ফ্র্যাগমেন্টে (ট্রানজিশনারি ধাপ)

আপনি যদি কোনও ফ্র্যাগমেন্ট বা আগে থেকে থাকা ভিউ লেআউটে Compose UI কন্টেন্ট যোগ করতে চান, তাহলে ComposeView ব্যবহার করুন এবং এর setContent() মেথড কল করুন। ComposeView হল একটি Android View।

আপনি অন্য যেকোনও View-এর মতো আপনার XML লেআউটে ComposeView রাখতে পারেন:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <TextView
      android:id="@+id/text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content" />

  <androidx.compose.ui.platform.ComposeView
      android:id="@+id/compose_view"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />
</LinearLayout>

Kotlin সোর্স কোডে, XML-এ সংজ্ঞায়িত লেআউট রিসোর্স থেকে লেআউট ইনফ্লেট করুন। তারপর XML আইডি ব্যবহার করে ComposeView পান, হোস্ট View-এর জন্য সবচেয়ে ভাল কাজ করে এমন কম্পোজিশন স্ট্র্যাটেজি সেট করুন এবং Compose ব্যবহার করতে setContent() কল করুন।

class ExampleFragmentXml : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        val view = inflater.inflate(R.layout.fragment_example, container, false)
        val composeView = view.findViewById<ComposeView>(R.id.compose_view)
        composeView.apply {
            // Dispose of the Composition when the view's LifecycleOwner
            // is destroyed
            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
            setContent {
                // In Compose world
                MaterialTheme {
                    Text("Hello Compose!")
                }
            }
        }
        return view
    }
}

এছাড়াও, আপনার XML লেআউট ফাইলের জন্য জেনারেট করা বাইন্ডিং ক্লাস রেফারেন্স করে ComposeView-এর রেফারেন্স পেতে আপনি ভিউ বাইন্ডিং ব্যবহার করতে পারেন:

class ExampleFragment : Fragment() {

    private var _binding: FragmentExampleBinding? = null

    // This property is only valid between onCreateView and onDestroyView.
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentExampleBinding.inflate(inflater, container, false)
        val view = binding.root
        binding.composeView.apply {
            // Dispose of the Composition when the view's LifecycleOwner
            // is destroyed
            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
            setContent {
                // In Compose world
                MaterialTheme {
                    Text("Hello Compose!")
                }
            }
        }
        return view
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
}

দুটি সামান্য আলাদা টেক্সট এলিমেন্ট, একটি আরেকটির উপরে রয়েছে

ছবি ১. এটি কোডের আউটপুট দেখায় যা Compose এলিমেন্টকে View UI হায়ারার্কিতে যোগ করে। "হ্যালো Android!" টেক্সটটি একটি TextView উইজেট দ্বারা দেখানো হয়। "Hello Compose!" টেক্সটটি একটি Compose টেক্সট এলিমেন্ট দ্বারা দেখানো হয়।

এছাড়াও, আপনার ফুল স্ক্রিন Compose দিয়ে তৈরি হলে, আপনি সরাসরি ফ্র্যাগমেন্টে ComposeView যোগ করতে পারবেন, যার ফলে আপনাকে XML লেআউট ফাইল সম্পূর্ণভাবে এড়িয়ে যেতে পারবেন।

class ExampleFragmentNoXml : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return ComposeView(requireContext()).apply {
            // Dispose of the Composition when the view's LifecycleOwner
            // is destroyed
            setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
            setContent {
                MaterialTheme {
                    // In Compose world
                    Text("Hello Compose!")
                }
            }
        }
    }
}

একই লেআউটে একাধিক ComposeView ইনস্ট্যান্স

একই লেআউটে একাধিক ComposeView এলিমেন্ট থাকলে, savedInstanceState কাজ করার জন্য প্রতিটির একটি অনন্য আইডি থাকতে হবে।

class ExampleFragmentMultipleComposeView : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View = LinearLayout(requireContext()).apply {
        addView(
            ComposeView(requireContext()).apply {
                setViewCompositionStrategy(
                    ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
                )
                id = R.id.compose_view_x
                // ...
            }
        )
        addView(TextView(requireContext()))
        addView(
            ComposeView(requireContext()).apply {
                setViewCompositionStrategy(
                    ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
                )
                id = R.id.compose_view_y
                // ...
            }
        )
    }
}

ComposeView আইডিগুলি res/values/ids.xml ফাইলে সংজ্ঞায়িত করা হয়েছে:

<resources>
  <item name="compose_view_x" type="id" />
  <item name="compose_view_y" type="id" />
</resources>

লেআউট এডিটরে কম্পোজেবল প্রিভিউ করা

এছাড়াও, আপনি ComposeView সহ XML লেআউটের জন্য লেআউট এডিটরের মধ্যে কম্পোজেবল প্রিভিউ করতে পারবেন। এটি করলে, আপনি মিক্সড ভিউ এবং কম্পোজ লেআউটের মধ্যে আপনার কম্পোজেবল কেমন দেখায় তা দেখতে পাবেন।

ধরুন, আপনি লেআউট এডিটরে নিম্নলিখিত কম্পোজেবল দেখাতে চান। মনে রাখবেন যে @Preview দিয়ে অ্যানোটেট করা কম্পোজেবল লেআউট এডিটরে প্রিভিউ করার জন্য উপযুক্ত।

@Preview
@Composable
fun GreetingPreview() {
    Greeting(name = "Android")
}

এই কম্পোজেবল দেখাতে, tools:composableName টুল অ্যাট্রিবিউট ব্যবহার করুন এবং লেআউটে প্রিভিউ করার জন্য কম্পোজেবলের সম্পূর্ণ নাম অনুযায়ী এর ভ্যালু সেট করুন।

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <androidx.compose.ui.platform.ComposeView
      android:id="@+id/my_compose_view"
      tools:composableName="com.example.compose.snippets.interop.InteroperabilityAPIsSnippetsKt.GreetingPreview"
      android:layout_height="match_parent"
      android:layout_width="match_parent"/>

</LinearLayout>

লেআউট এডিটরের মধ্যে কম্পোজেবল দেখানো হয়েছে