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

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

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

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

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

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

    ```xml

    <!-- AppBarLayout contents here -->
    

    ```

  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 لإضافة المزيد من عناصر الشاشة ونقل عناصر View الثانوية المتبقية. يمكنك استخدام الخانة 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 في العرض القابل للتمرير المرتبط (مثل RecyclerView أو NestedScrollView) لتحديد طريقة تصغير/توسيع شريط الأدوات أثناء التمرير.

في Compose، يمكنك تحقيق تأثير مشابه من خلال 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، يُرجى الاطّلاع على المراجع التالية: