انتقال CoordinatorLayout به Compose

‫CoordinatorLayout یک ViewGroup است که چیدمان‌های پیچیده، هم‌پوشانی‌شده، و تودرتو را فعال می‌کند. از آن به‌عنوان محتوی برای فعال کردن تعاملات خاص «طراحی Material» مثل ازهم بازکردن/جمع کردن نوارابزارها و برگه‌های پایین برای «نماهای» موجود در آن استفاده می‌شود.

در «نوشتن»، نزدیک‌ترین معادل CoordinatorLayout،‏ Scaffold است. Scaffold جایگاه‌های محتوا را برای ترکیب کردن «عناصر Material» در الگوها و تعاملات صفحه مشترک فراهم می‌کند. این صفحه توضیح می‌دهد که چگونه می‌توانید پیاده‌سازی 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 استفاده خواهیم کرد که معادل آن در «نوشتن» است. 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 */ }
        }
    }

موارد استفاده رایج

جمع کردن و ازهم بازکردن نوارابزارها

در سیستم «نما»، برای جمع کردن و ازهم بازکردن نوارابزار با CoordinatorLayout، از AppBarLayout به‌عنوان ظرف نوارابزار استفاده می‌کنید. سپس می‌توانید ازطریق layout_behavior در XML در BehaviorRecyclerViewNestedScrollView مشخص کنید که نوارابزار هم‌زمان با پیمایش چگونه جمع/ازهم باز شود.

در «نوشتن»، می‌توانید ازطریق TopAppBarScrollBehavior به جلوه‌ای مشابه دست یابید. برای مثال، برای پیاده‌سازی نوارابزار جمع‌شونده/ازهم بازشونده به‌طوری که نوارابزار هنگام پیمایش به بالا ظاهر شود، این مراحل را دنبال کنید:

  1. برای ایجاد TopAppBarScrollBehavior، با TopAppBarDefaults.enterAlwaysScrollBehavior() تماس بگیرید.
  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، برای نمایش گزینه‌های پیمایش در کشو است.

در «نگارش»، می‌توانید بااستفاده از عنصر ترکیبی 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، منابع زیر را ببینید: