لائحة التنقل

عنصر درج التنقل هو قائمة انزلاق تتيح للمستخدمين التنقّل إلى أقسام مختلفة من تطبيقك. ويمكن للمستخدمين تفعيله من خلال التمرير سريعًا من الجانب أو النقر على رمز قائمة.

راجِع حالات الاستخدام الثلاث التالية لتنفيذ "لوحة التنقّل":

  • تنظيم المحتوى: يمكنك السماح للمستخدمين بالتبديل بين فئات مختلفة، مثل التطبيقات الإخبارية أو تطبيقات التدوين.
  • إدارة الحساب: يجب توفير روابط سريعة إلى إعدادات الحساب وأقسام الملف الشخصي في التطبيقات التي تتضمّن حسابات مستخدمين.
  • اكتشاف الميزات: يمكنك تنظيم الميزات والإعدادات المتعددة في ملف شخصي واحد للتسهيل اكتشاف المستخدمين للميزات والوصول إليها في التطبيقات المعقدة.

في أسلوب Material Design، هناك نوعان من أدراج التنقّل:

  • عادي: مشاركة مساحة ضمن شاشة مع محتوى آخر
  • وضع النافذة المنبثقة: يظهر فوق المحتوى الآخر ضمن الشاشة.
الشكل 1. مثال على درج التنقّل

مثال

يمكنك استخدام العنصر القابل للتجميع ModalNavigationDrawer لتنفيذ لائحة تنقّل.

استخدِم خانة drawerContent لتقديم ModalDrawerSheet وتقديم محتويات الدرج، كما هو موضّح في المثال التالي:

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
        }
    }
) {
    // Screen content
}

تقبل ModalNavigationDrawer عددًا من مَعلمات الأدراج الإضافية. على سبيل المثال، يمكنك تفعيل أو إيقاف استجابة الدرج للسحب باستخدام المَعلمة gesturesEnabled كما هو موضّح في المثال التالي:

ModalNavigationDrawer(
    drawerContent = {
        ModalDrawerSheet {
            // Drawer contents
        }
    },
    gesturesEnabled = false
) {
    // Screen content
}

سلوك التحكّم

للتحكّم في كيفية فتح الدرج وإغلاقه، استخدِم DrawerState. يجب تمرير DrawerState إلى ModalNavigationDrawer باستخدام المَعلمة drawerState.

يوفر DrawerState إمكانية الوصول إلى وظيفتَي open وclose، بالإضافة إلى السمات ذات الصلة بحالة الدرج الحالية. تتطلّب دوال التعليق هذه CoroutineScope، ويمكنك إنشاء مثيل لها باستخدام rememberCoroutineScope. يمكنك أيضًا استدعاء دوال التعليق في استجابة لأحداث واجهة المستخدم.

val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope()
ModalNavigationDrawer(
    drawerState = drawerState,
    drawerContent = {
        ModalDrawerSheet { /* Drawer content */ }
    },
) {
    Scaffold(
        floatingActionButton = {
            ExtendedFloatingActionButton(
                text = { Text("Show drawer") },
                icon = { Icon(Icons.Filled.Add, contentDescription = "") },
                onClick = {
                    scope.launch {
                        drawerState.apply {
                            if (isClosed) open() else close()
                        }
                    }
                }
            )
        }
    ) { contentPadding ->
        // Screen content
    }
}

إنشاء مجموعات داخل درج التنقّل

يوضّح المقتطف التالي كيفية إنشاء درج تنقّل مفصّل يتضمّن أقسامًا ومقسمات:

@Composable
fun DetailedDrawerExample(
    content: @Composable (PaddingValues) -> Unit
) {
    val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
    val scope = rememberCoroutineScope()

    ModalNavigationDrawer(
        drawerContent = {
            ModalDrawerSheet {
                Column(
                    modifier = Modifier.padding(horizontal = 16.dp)
                        .verticalScroll(rememberScrollState())
                ) {
                    Spacer(Modifier.height(12.dp))
                    Text("Drawer Title", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleLarge)
                    HorizontalDivider()

                    Text("Section 1", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleMedium)
                    NavigationDrawerItem(
                        label = { Text("Item 1") },
                        selected = false,
                        onClick = { /* Handle click */ }
                    )
                    NavigationDrawerItem(
                        label = { Text("Item 2") },
                        selected = false,
                        onClick = { /* Handle click */ }
                    )

                    HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))

                    Text("Section 2", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleMedium)
                    NavigationDrawerItem(
                        label = { Text("Settings") },
                        selected = false,
                        icon = { Icon(Icons.Outlined.Settings, contentDescription = null) },
                        badge = { Text("20") }, // Placeholder
                        onClick = { /* Handle click */ }
                    )
                    NavigationDrawerItem(
                        label = { Text("Help and feedback") },
                        selected = false,
                        icon = { Icon(Icons.AutoMirrored.Outlined.Help, contentDescription = null) },
                        onClick = { /* Handle click */ },
                    )
                    Spacer(Modifier.height(12.dp))
                }
            }
        },
        drawerState = drawerState
    ) {
        Scaffold(
            topBar = {
                TopAppBar(
                    title = { Text("Navigation Drawer Example") },
                    navigationIcon = {
                        IconButton(onClick = {
                            scope.launch {
                                if (drawerState.isClosed) {
                                    drawerState.open()
                                } else {
                                    drawerState.close()
                                }
                            }
                        }) {
                            Icon(Icons.Default.Menu, contentDescription = "Menu")
                        }
                    }
                )
            }
        ) { innerPadding ->
            content(innerPadding)
        }
    }
}

النقاط الرئيسية حول الرمز

  • تعبئة drawerContent بعنصر Column يحتوي على أقسام ومقسمات وعناصر تنقّل
  • يوفّر ModalDrawerSheet تصميمًا بأسلوب Material Design للدرج.
  • يفصل الرمز HorizontalDivider الأقسام داخل الدرج.
  • ModalNavigationDrawer لإنشاء الدرج
  • drawerContent تحدّد محتوى الدرج.
  • داخل ModalDrawerSheet، يُرتِّب Column عناصر الدرج بشكل عمودي.
  • تمثّل العناصر القابلة للتجميع NavigationDrawerItem عناصر فردية في الدرج.
  • يقدّم Scaffold الهيكل الأساسي للشاشة، بما في ذلك TopAppBar.
  • يتحكم الرمز navigationIcon في TopAppBar في حالة فتح الدرج وإغلاقه.

النتيجة

توضِّح الصورة التالية كيفية ظهور الدرج عند فتحه، مع عرض الأقسام والعناصر:

درج تنقّل مفصّل يتضمّن قسمَين، يتضمّن كلّ منهما عناصر ورموزًا مُصنَّفة متعددة.
الشكل 2. لائحة تنقل مفتوحة تتضمّن مجموعتَين متداخلتَين

مصادر إضافية