व्यू में कंपोज़ की सुविधा इस्तेमाल करना

व्यू-आधारित डिज़ाइन का इस्तेमाल करने वाले किसी मौजूदा ऐप्लिकेशन में, Compose-आधारित यूज़र इंटरफ़ेस (यूआई) जोड़ा जा सकता है.

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. सिंगल-ऐक्टिविटी वाले Compose-ओनली ऐप्लिकेशन में, यह डिफ़ॉल्ट ऐक्शन और सेटिंग ही आपकी ज़रूरत के मुताबिक होती है. हालांकि, अगर अपने कोड बेस में Compose को धीरे-धीरे जोड़ा जा रहा है, तो कुछ मामलों में इस ऐक्शन और सेटिंग की वजह से स्टेट लॉस हो सकता है.

ViewCompositionStrategy को बदलने के लिए, setViewCompositionStrategy() तरीके को कॉल करें और कोई दूसरी रणनीति उपलब्ध कराएं.

यहां दी गई टेबल में, उन अलग-अलग स्थितियों के बारे में बताया गया है जिनमें ViewCompositionStrategy का इस्तेमाल किया जा सकता है:

ViewCompositionStrategy ब्यौरा और इंटरऑपरेबिलिटी का उदाहरण
DisposeOnDetachedFromWindow जब ComposeView को विंडो से अलग किया जाएगा, तब कंपोज़िशन को हटा दिया जाएगा. अब इसकी जगह DisposeOnDetachedFromWindowOrReleasedFromPool का इस्तेमाल किया जाता है.

इंटरऑपरेबिलिटी का उदाहरण:

* ComposeView चाहे यह व्यू हैरारकी में मौजूद एकमात्र एलिमेंट हो या मिक्स व्यू/Compose स्क्रीन के कॉन्टेक्स्ट में हो (फ़्रैगमेंट में नहीं).
DisposeOnDetachedFromWindowOrReleasedFromPool (डिफ़ॉल्ट) DisposeOnDetachedFromWindow की तरह, जब कंपोज़िशन किसी पूलिंग कंटेनर में न हो, जैसे कि RecyclerView. अगर यह पूलिंग कंटेनर में है, तो यह तब बंद हो जाएगा, जब पूलिंग कंटेनर खुद विंडो से अलग हो जाएगा या जब आइटम को खारिज कर दिया जाएगा (यानी कि जब पूल भर जाएगा).

इंटरऑप स्थिति:

* ComposeView चाहे यह व्यू हैरारकी में एकमात्र एलिमेंट हो या मिक्स व्यू/Compose स्क्रीन के संदर्भ में हो (फ़्रैगमेंट में नहीं).
* ComposeView को RecyclerView जैसे किसी पूलिंग कंटेनर में आइटम के तौर पर.
DisposeOnLifecycleDestroyed दिए गए Lifecycle के खत्म होने पर, कंपोज़िशन को हटा दिया जाएगा.

इंटरऑप सिनैरियो

* फ़्रैगमेंट के व्यू में ComposeView.
DisposeOnViewTreeLifecycleDestroyed कंपोज़िशन को तब हटाया जाएगा, जब उस विंडो का Lifecycle नष्ट हो जाएगा जिससे व्यू अटैच है. यह , LifecycleOwner के मालिकाना हक वाला होता है और इसे ViewTreeLifecycleOwner.get से वापस किया जाता है.

इंटरऑपरेबिलिटी का उदाहरण:

* फ़्रैगमेंट के व्यू में ComposeView.
* ComposeView को ऐसे व्यू में इस्तेमाल किया गया है जिसकी लाइफ़साइकल के बारे में अब तक जानकारी नहीं है.

ComposeView in Fragments (Transitionary Step)

अगर आपको किसी फ़्रैगमेंट या मौजूदा व्यू लेआउट में Compose यूज़र इंटरफ़ेस (यूआई) कॉन्टेंट शामिल करना है, तो ComposeView का इस्तेमाल करें और इसके setContent() तरीके को कॉल करें. ComposeView, Android View है.

ComposeView को अपने एक्सएमएल लेआउट में किसी अन्य View की तरह ही डाला जा सकता है:

<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 सोर्स कोड में, एक्सएमएल में तय किए गए लेआउट रिसॉर्स से लेआउट को इनफ़्लेट करें. इसके बाद, एक्सएमएल आईडी का इस्तेमाल करके 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
    }
}

इसके अलावा, व्यू बाइंडिंग का इस्तेमाल करके भी 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 एलिमेंट जोड़ता है. "Hello Android!" टेक्स्ट, TextView विजेट से दिखता है. "Hello Compose!" टेक्स्ट, Compose के टेक्स्ट एलिमेंट से दिखता है.

अगर आपकी फ़ुल स्क्रीन Compose की मदद से बनाई गई है, तो फ़्रैगमेंट में सीधे तौर पर ComposeView को भी शामिल किया जा सकता है. इससे आपको एक्सएमएल लेआउट फ़ाइल का इस्तेमाल करने की ज़रूरत नहीं पड़ती.

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 वाले एक्सएमएल लेआउट के लिए, लेआउट एडिटर में कंपोज़ेबल की झलक भी देखी जा सकती है. ऐसा करने पर, आपको यह देखने को मिलता है कि व्यू और Compose के मिले-जुले लेआउट में, आपके कंपोज़ेबल कैसे दिखते हैं.

मान लें कि आपको लेआउट एडिटर में, कंपोज़ेबल का यह फ़ंक्शन दिखाना है. ध्यान दें कि @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>

लेआउट एडिटर में दिखाया गया कंपोज़ेबल