אפשר להוסיף ממשק משתמש מבוסס-כתיבה לאפליקציה קיימת שמשתמשת בעיצוב מבוסס-תצוגה.
כדי ליצור מסך חדש שמבוסס כולו על 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!") }
הקוד הזה נראה בדיוק כמו הקוד שמופיע באפליקציה לכתיבה בלבד.
ViewCompositionStrategy
למשך ComposeView
ViewCompositionStrategy
מגדיר מתי צריך להשליך את היצירה. ברירת המחדל, ViewCompositionStrategy.Default
, מאפשרת לממשק Composition להימחק כשהרכיב הבסיסי ComposeView
מתנתק מהחלון, אלא אם הוא חלק מקונטיינר של מאגר, כמו RecyclerView
. באפליקציה עם Compose בלבד, התנהגות ברירת המחדל הזו היא מה שרוצים. עם זאת, אם מוסיפים את Compose בהדרגה לקוד, התנהגות כזו עלולה לגרום לאובדן מצב בתרחישים מסוימים.
כדי לשנות את ViewCompositionStrategy
, יש להפעיל את setViewCompositionStrategy()
ולספק אסטרטגיה אחרת.
בטבלה הבאה מפורט סיכום של התרחישים השונים שבהם אפשר להשתמש ב-ViewCompositionStrategy
:
ViewCompositionStrategy |
תיאור ותרחיש של יכולת פעולה הדדית |
---|---|
DisposeOnDetachedFromWindow |
ה-Composition יוסר כשה-ComposeView הבסיסי ינותק מהחלון. הגרסה הוחלפה מאז על ידי DisposeOnDetachedFromWindowOrReleasedFromPool .תרחיש של יכולת פעולה הדדית: * ComposeView , אם זה הרכיב היחיד בהיררכיית התצוגה, או בהקשר של מסך תצוגה/כתיבה מעורב (לא ב-Fragment). |
DisposeOnDetachedFromWindowOrReleasedFromPool (ברירת מחדל) |
בדומה ל-DisposeOnDetachedFromWindow , כשהיצירה לא נמצאת בקונטיינר למאגר, למשל RecyclerView . אם מאגר התגים כלול במאגר הנתונים שבמאגר, הוא יוסר כשהמאגר עצמו מתנתק מהחלון או כשהפריט נמחק (כלומר כשהמאגר מלא).תרחיש של יכולת פעולה הדדית: * ComposeView אם זה הרכיב היחיד בהיררכיית התצוגה, או בהקשר של מסך משולב של תצוגה/פיתוח (לא מקטע).* ComposeView כפריט בקונטיינר של מאגר, כמו RecyclerView . |
DisposeOnLifecycleDestroyed |
היצירה תימחק לאחר שה-Lifecycle שסופק יושמד.תרחיש של יכולת פעולה הדדית * ComposeView בתצוגה של מקטע. |
DisposeOnViewTreeLifecycleDestroyed |
הקומפוזיציה תימחק כשה-Lifecycle שבבעלות ה-LifecycleOwner שהוחזר על ידי ViewTreeLifecycleOwner.get של החלון הבא שאליו הממשק מחובר נהרס.תרחיש של יכולת פעולה הדדית: * ComposeView בממשק של קטע קוד.* ComposeView בתצוגה שבה מחזור החיים עדיין לא ידוע. |
ComposeView
במקטעים
אם רוצים לשלב את התוכן של ממשק המשתמש של 'כתיבה' במקטע או בתצוגה קיימת
פריסה, צריך להשתמש ב-ComposeView
וקוראים לו
setContent()
. ComposeView
הוא מכשיר Android View
.
אפשר להוסיף את 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()
כדי להשתמש ב-Compose.
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 } }
איור 1. כאן מוצג הפלט של הקוד שמוסיף רכיבי Compose בהיררכיה של ממשק המשתמש של View. ההודעה "שלום Android!" טקסט מוצג על ידי
הווידג'ט TextView
. ההודעה "Hello 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
. כך תוכלו לראות איך הרכיבים שלכם נראים בתצוגה מעורבת של תצוגות ורכיבי Compose.
נניח שאתם רוצים להציג את הרכיב הבא ב-Layout Editor. חשוב לזכור שרכיבים מורכבים עם הערה @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>
השלבים הבאים
עכשיו, אחרי שהכרתם את ממשקי ה-API ליכולת פעולה הדדית לשימוש ב-Compose בתצוגות, תוכלו לקרוא איך משתמשים בתצוגות ב-Compose.
אין המלצות כרגע.
אפשר לנסות להיכנס לחשבון Google.