برای نوشتن، CoordinatorLayout را مهاجرت کنید

CoordinatorLayout یک ViewGroup است که امکان ایجاد طرح‌بندی‌های پیچیده، همپوشانی و تو در تو را فراهم می‌کند. این طرح‌بندی به عنوان یک ظرف برای فعال کردن تعاملات خاص طراحی متریال، مانند باز/بسته کردن نوار ابزارها و صفحات پایینی، برای Viewهای موجود در آن استفاده می‌شود.

در 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 مربوط به 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 به عنوان ظرفی برای نوار ابزار استفاده می‌کنید. سپس می‌توانید از طریق layout_behavior در XML، یک Behavior روی View اسکرول‌شونده مرتبط (مانند RecyclerView یا NestedScrollView ) مشخص کنید تا نحوه جمع شدن/باز شدن نوار ابزار هنگام اسکرول کردن را مشخص کنید.

در Compose، می‌توانید از طریق 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 مراجعه کنید.

کشوها

با استفاده از Views، شما با استفاده از 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، به منابع زیر مراجعه کنید:

{% کلمه به کلمه %} {% فعل کمکی %} {% کلمه به کلمه %} {% فعل کمکی %}