استفاده از «نوشتن» در «نماها»

می‌توانید «میانای کاربر» مبتنی بر Compose را به برنامه موجودی که از طراحی مبتنی بر View استفاده می‌کند اضافه کنید.

برای ایجاد صفحه‌ای جدید که کاملاً مبتنی بر «نگارش» باشد، فعالیتتان باید متد 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 پیدا می‌کنید.

ViewCompositionStrategy برای ComposeView

ViewCompositionStrategy تعیین می‌کند که «ترکیب» چه زمانی باید دور انداخته شود. پیش‌فرض، ViewCompositionStrategy.Default، وقتی ComposeView از پنجره جدا می‌شود «ترکیب» را دور می‌اندازد، مگر اینکه بخشی از یک محفظه استخرسازی مثل RecyclerView باشد. در برنامه تک‌فعالیتی فقط «ترکیب‌کننده»، این رفتار پیش‌فرض همان چیزی است که می‌خواهید، اما اگر به‌تدریج «ترکیب‌کننده» را به پایگاه کد خود اضافه می‌کنید، این رفتار ممکن است در برخی‌از سناریوها باعث ازدست رفتن وضعیت شود.

برای تغییر ViewCompositionStrategy، با روش setViewCompositionStrategy() تماس بگیرید و استراتژی دیگری ارائه دهید.

جدول زیر سناریوهای مختلفی را که می‌توانید از ViewCompositionStrategy در آن‌ها استفاده کنید خلاصه می‌کند:

ViewCompositionStrategy شرح و سناریو قابلیت تعامل‌پذیری
DisposeOnDetachedFromWindow وقتی ComposeView زیرین از پنجره جدا شود، «ترکیب» دور انداخته خواهد شد. از آن زمان با DisposeOnDetachedFromWindowOrReleasedFromPool جایگزین شده است.

سناریو قابلیت تعامل:

* ComposeView چه تنها عنصر در سلسله‌مراتب «نما» باشد، چه در بافت صفحه «نما/ترکیب» مختلط (نه در «تکه»).
DisposeOnDetachedFromWindowOrReleasedFromPool (پیش‌فرض) مشابه DisposeOnDetachedFromWindow، وقتی «ترکیب» در محتوی استخر نیست، مثل RecyclerView. اگر در یک محفظه استخر باشد، زمانی که محفظه استخر از پنجره جدا شود یا زمانی که مورد دور انداخته شود (یعنی زمانی که استخر پر باشد) ازبین می‌رود.

سناریو تعامل‌پذیری:

* ComposeView اینکه آیا تنها عنصر در سلسله‌مراتب «نما» است یا در زمینه صفحه «نما/ترکیب» مختلط (نه در «تکه»).
* ‫ComposeView به‌عنوان موردی در محتوی تجمیعی مثل RecyclerView.
DisposeOnLifecycleDestroyed وقتی Lifecycle ارائه‌شده ازبین برود، «ترکیب» دور انداخته خواهد شد.

سناریو تعامل‌پذیری

* ComposeView در «نمای» «تکه‌برنامه».
DisposeOnViewTreeLifecycleDestroyed وقتی Lifecycle متعلق به LifecycleOwner برگشت‌داده‌شده توسط ViewTreeLifecycleOwner.get از پنجره بعدی که «نما» به آن پیوست شده است ازبین برود، «ترکیب» دور انداخته خواهد شد.

سناریو تعامل‌پذیری:

* ComposeView در «نمای» «تکه».
* ‫ComposeView در «نمایی» که «چرخه عمر» هنوز مشخص نیست.

‫ComposeView در «تکه‌نوشته‌ها» (مرحله انتقالی)

اگر می‌خواهید محتوای «واسط کاربر Compose» را در بخش یا چیدمان View موجود بگنجانید، از ComposeView استفاده کنید و متد setContent() آن را فراخوانی کنید. ‫ComposeView یک View Android است.

می‌توانید ComposeView را در چیدمان XML خود درست مثل هر 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، چیدمان را از منبع چیدمان تعریف‌شده در XML باد کنید. سپس ComposeView را بااستفاده از شناسه XML دریافت کنید، استراتژی «ترکیب» را که برای میزبان View بهترین عملکرد را دارد تنظیم کنید، و 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 با ارجاع دادن به کلاس اتصال تولیدشده برای فایل چیدمان XML استفاده کنید:

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» اضافه می‌کند. نوشتار «Hello Android!» توسط ابزارک TextView نمایش داده می‌شود. نوشتار «سلام نوشتن!» توسط عنصر نوشتن نوشتار نمایش داده می‌شود.

اگر صفحه کامل شما با 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>

پیش‌نمایش عناصر ترکیبی در «ویرایشگر چیدمان»

همچنین می‌توانید عناصر ترکیبی را در «ویرایشگر چیدمان» برای چیدمان XML حاوی ComposeView پیش‌دید کنید. با انجام این کار می‌توانید ببینید عناصر ترکیبی شما در چیدمان ترکیبی «نماها» و «ترکیب» چگونه به‌نظر می‌رسند.

فرض کنید می‌خواهید عنصر ترکیبی زیر را در «ویرایشگر چیدمان» نمایش دهید. توجه داشته باشید که عناصر ترکیبی حاشیه‌نویسی‌شده با @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>

«ترکیب‌پذیر» در ویرایشگر چیدمان نمایش داده می‌شود