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

إنّ CoordinatorLayout هو عنصر ViewGroup يتيح التنسيقات المعقدة والمتداخلة والمدمجة. ويتم استخدامها كحاوية لتفعيل تفاعلات نظام Material Design، مثل توسيع/تصغير أشرطة الأدوات والأوراق السفلية، لطرق العرض الموجودة داخلها.

في 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. في المقتطف أو النشاط، احصل على إشارة إلى ComposeView الذي أضفته للتو واستخدِم طريقة setContent عليه. في نص الطريقة، اضبط Scaffold كمحتوى لها:

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

  3. أضِف المحتوى الأساسي على شاشتك في محتوى Scaffold. بما أنّ المحتوى الأساسي في ملف XML أعلاه هو ViewPager2، سنستخدم HorizontalPager، وهو مكافئ Compose له. تتلقّى دالة content lambda في 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 */ }
        }
    }

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

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

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

في ميزة "الإنشاء"، يمكنك تحقيق تأثير مشابه من خلال TopAppBarScrollBehavior. على سبيل المثال، لتنفيذ شريط أدوات للتصغير/التوسيع بحيث يظهر شريط الأدوات عند التمرير لأعلى، اتبع الخطوات التالية:

  1. يمكنك الاتصال بـ TopAppBarDefaults.enterAlwaysScrollBehavior() لإنشاء TopAppBarScrollBehavior.
  2. قدِّم TopAppBarScrollBehavior الذي تم إنشاؤه إلى TopAppBar.
  3. اربط NestedScrollConnection عبر Modifier.nestedScroll في 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، يُرجى الاطّلاع على المراجع التالية: