نقل CoorditorLayout إلى أداة "Compose"

CoordinatorLayout هي ViewGroup تتيح استخدام تنسيقات معقّدة ومتراكبة ومتداخلة. ويتم استخدامها كحاوية لتفعيل تفاعلات معيّنة في التصميم المتعدد الأبعاد، مثل توسيع أشرطة الأدوات والأوراق السفلية أو تصغيرها، وذلك بالنسبة إلى طرق العرض المضمّنة فيها.

في Compose، أقرب عنصر مكافئ لـ CoordinatorLayout هو Scaffold. يوفّر Scaffold مساحات عرض للمحتوى من أجل دمج مكوّنات التصميم المتعدد الأبعاد في أنماط وتفاعلات شاشة شائعة. توضّح هذه الصفحة كيفية نقل عملية تنفيذ CoordinatorLayout لاستخدام Scaffold في Compose.

خطوات نقل البيانات

لنقل CoordinatorLayout إلى Scaffold، اتّبِع الخطوات التالية:

  1. في المقتطف أدناه، تحتوي CoordinatorLayout على AppBarLayout تتضمّن ToolBar وViewPager وFloatingActionButton. علِّق على CoordinatorLayout والعناصر التابعة لها من تسلسل واجهة المستخدم وأضِف ComposeView لاستبدالها.

    <!--  <androidx.coordinatorlayout.widget.CoordinatorLayout-->
    <!--      android:id="@+id/coordinator_layout"-->
    <!--      android:layout_width="match_parent"-->
    <!--      android:layout_height="match_parent"-->
    <!--      android:fitsSystemWindows="true">-->
    
    <!--    <androidx.compose.ui.platform.ComposeView-->
    <!--        android:id="@+id/compose_view"-->
    <!--        android:layout_width="match_parent"-->
    <!--        android:layout_height="match_parent"-->
    <!--        app:layout_behavior="@string/appbar_scrolling_view_behavior" />-->
    
    <!--    <com.google.android.material.appbar.AppBarLayout-->
    <!--        android:id="@+id/app_bar_layout"-->
    <!--        android:layout_width="match_parent"-->
    <!--        android:layout_height="wrap_content"-->
    <!--        android:fitsSystemWindows="true"-->
    <!--        android:theme="@style/Theme.Sunflower.AppBarOverlay">-->
    
        <!-- AppBarLayout contents here -->
    
    <!--    </com.google.android.material.appbar.AppBarLayout>-->
    
    <!--  </androidx.coordinatorlayout.widget.CoordinatorLayout>-->
    
    <androidx.compose.ui.platform.ComposeView
        android:id="@+id/compose_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    
  2. في Fragment أو Activity، احصل على مرجع إلى ComposeView الذي أضفته للتو واستدعِ طريقة setContent عليه. في نص الطريقة، اضبط Scaffold كمحتوى لها:

    composeView.setContent {
        Scaffold(Modifier.fillMaxSize()) { contentPadding ->
            // Scaffold contents
            // ...
        }
    }

  3. في محتوى Scaffold، أضِف المحتوى الأساسي لشاشتك بداخله. بما أنّ المحتوى الأساسي في XML أعلاه هو ViewPager2، سنستخدم HorizontalPager، وهو العنصر المكافئ له في Compose. تتلقّى أيضًا دالة lambda الخاصة بـ content في Scaffold مثيلاً من PaddingValues يجب تطبيقه على جذر المحتوى. يمكنك استخدام Modifier.padding لتطبيق PaddingValues نفسها على HorizontalPager.

    composeView.setContent {
        Scaffold(Modifier.fillMaxSize()) { contentPadding ->
            val pagerState = rememberPagerState {
                10
            }
            HorizontalPager(
                state = pagerState,
                modifier = Modifier.padding(contentPadding)
            ) { /* Page contents */ }
        }
    }

  4. استخدِم مساحات عرض المحتوى الأخرى التي يوفّرها Scaffold لإضافة المزيد من عناصر الشاشة ونقل طرق العرض المتبقية التابعة لها. يمكنك استخدام مساحة العرض topBar لإضافة TopAppBar، ومساحة العرض floatingActionButton لتوفير FloatingActionButton.

    composeView.setContent {
        Scaffold(
            Modifier.fillMaxSize(),
            topBar = {
                TopAppBar(
                    title = {
                        Text("My App")
                    }
                )
            },
            floatingActionButton = {
                FloatingActionButton(
                    onClick = { /* Handle click */ }
                ) {
                    Icon(
                        Icons.Filled.Add,
                        contentDescription = "Add Button"
                    )
                }
            }
        ) { contentPadding ->
            val pagerState = rememberPagerState {
                10
            }
            HorizontalPager(
                state = pagerState,
                modifier = Modifier.padding(contentPadding)
            ) { /* Page contents */ }
        }
    }

حالات الاستخدام الشائعة

تصغير أشرطة الأدوات وتوسيعها

في نظام View، لتصغير شريط الأدوات وتوسيعه باستخدام CoordinatorLayout، يمكنك استخدام AppBarLayout كحاوية لشريط الأدوات. يمكنك بعد ذلك تحديد a Behavior من خلال layout_behavior في XML على طريقة العرض القابلة للتمرير المرتبطة (مثل RecyclerView أو NestedScrollView) لتحديد كيفية تصغير شريط الأدوات أو توسيعه أثناء التمرير.

في Compose، يمكنك تحقيق تأثير مشابه من خلال a TopAppBarScrollBehavior. على سبيل المثال، لتنفيذ شريط أدوات يتم تصغيره وتوسيعه بحيث يظهر شريط الأدوات عند التمرير للأعلى، اتّبِع الخطوات التالية:

  1. استدعِ TopAppBarDefaults.enterAlwaysScrollBehavior() لإنشاء TopAppBarScrollBehavior.
  2. قدِّم TopAppBarScrollBehavior الذي تم إنشاؤه إلى TopAppBar.
  3. اربط NestedScrollConnection من خلال Modifier.nestedScroll على Scaffold حتى يتمكّن Scaffold من تلقّي أحداث التمرير المتداخلة أثناء تمرير المحتوى القابل للتمرير للأعلى أو للأسفل. بهذه الطريقة، يمكن أن يتم تصغير شريط التطبيق المضمّن أو توسيعه بشكل مناسب أثناء تمرير المحتوى.

    // 1. Create the TopAppBarScrollBehavior
    val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
    
    Scaffold(
        topBar = {
            TopAppBar(
                title = {
                    Text("My App")
                },
                // 2. Provide scrollBehavior to TopAppBar
                scrollBehavior = scrollBehavior
            )
        },
        // 3. Connect the scrollBehavior.nestedScrollConnection to the Scaffold
        modifier = Modifier
            .fillMaxSize()
            .nestedScroll(scrollBehavior.nestedScrollConnection)
    ) { contentPadding ->
        /* Contents */
        // ...
    }

تخصيص تأثير التمرير الذي يتم تصغيره وتوسيعه

يمكنك تقديم عدة مَعلمات لـ enterAlwaysScrollBehavior لـ تخصيص تأثير الرسوم المتحركة الذي يتم تصغيره وتوسيعه. TopAppBarDefaults أيضًا يوفّر TopAppBarScrollBehavior أخرى، مثل exitUntilCollapsedScrollBehavior، التي لا توسّع شريط التطبيق إلا عند تمرير المحتوى بالكامل للأسفل.

لإنشاء تأثير مخصّص بالكامل (على سبيل المثال، تأثير اختلاف المنظر)، يمكنك أيضًا إنشاء NestedScrollConnection الخاصة بك وإزاحة شريط الأدوات يدويًا أثناء تمرير المحتوى. يمكنك الاطّلاع على نموذج التمرير المتداخل على AOSP للحصول على مثال للرمز.

أدراج

باستخدام طرق العرض، يمكنك تنفيذ لائحة التنقل باستخدام DrawerLayout كطريقة العرض الجذر. في المقابل، تكون CoordinatorLayout طريقة عرض تابعة لـ DrawerLayout. يحتوي DrawerLayout أيضًا على طريقة عرض تابعة أخرى، مثل NavigationView، لعرض خيارات التنقّل في الدرج.

في Compose، يمكنك تنفيذ درج تنقّل باستخدام العنصر المركّب ModalNavigationDrawer. يوفّر ModalNavigationDrawer مساحة عرض drawerContent للدرج ومساحة عرض content لمحتوى الشاشة.

ModalNavigationDrawer(
    drawerContent = {
        ModalDrawerSheet {
            Text("Drawer title", modifier = Modifier.padding(16.dp))
            HorizontalDivider()
            NavigationDrawerItem(
                label = { Text(text = "Drawer Item") },
                selected = false,
                onClick = { /*TODO*/ }
            )
            // ...other drawer items
        }
    }
) {
    Scaffold(Modifier.fillMaxSize()) { contentPadding ->
        // Scaffold content
        // ...
    }
}

لمزيد من المعلومات، يمكنك الاطّلاع على مقالة أدراج.

أشرطة إعلام منبثقة

يوفر Scaffold مساحة عرض snackbarHost، يمكنها قبول عنصر SnackbarHost مركب لعرض Snackbar.

val scope = rememberCoroutineScope()
val snackbarHostState = remember { SnackbarHostState() }
Scaffold(
    snackbarHost = {
        SnackbarHost(hostState = snackbarHostState)
    },
    floatingActionButton = {
        ExtendedFloatingActionButton(
            text = { Text("Show snackbar") },
            icon = { Icon(Icons.Filled.Image, contentDescription = "") },
            onClick = {
                scope.launch {
                    snackbarHostState.showSnackbar("Snackbar")
                }
            }
        )
    }
) { contentPadding ->
    // Screen content
    // ...
}

لمزيد من المعلومات، يمكنك الاطّلاع على مقالة أشرطة إعلام منبثقة.

مزيد من المعلومات

لمزيد من المعلومات عن نقل CoordinatorLayout إلى Compose، يمكنك الاطّلاع على المَراجع التالية: