تقدّم Jetpack Compose طلبًا لتنفيذ التصميم المتعدد الأبعاد، وهو نظام تصميم شامل لإنشاء الواجهات الرقمية. تتوفر المكونات الأساسية (الأزرار والبطاقات ومفاتيح التبديل، وما إلى ذلك) والتنسيقات مثل Scaffold
كدوال قابلة للإنشاء.
المكوّنات الأساسية هي عناصر أساسية تفاعلية لإنشاء واجهة مستخدم. يقدّم Compose عددًا من هذه المكوّنات المبتكرة. لمعرفة الإصدارات المتوفّرة، يمكنك الاطّلاع على مرجع Material Material API.
تستخدم "مكوّنات المواد" القيم التي توفّرها MaterialTheme
في تطبيقك:
@Composable fun MyApp() { MaterialTheme { // Material Components like Button, Card, Switch, etc. } }
لمعرفة المزيد من المعلومات حول هذه المواضيع، يمكنك الاطّلاع على أنظمة التصميم في أدلة الإنشاء.
خانات المحتوى
مكوّنات المواد الأساسية التي تتيح المحتوى الداخلي (التصنيفات النصية والرموز وما إلى ذلك) تميل إلى تقديم "خانات إعلانية"، وهي دالة lambda عامة تقبل المحتوى القابل للإنشاء، بالإضافة إلى الثوابت العامة، مثل الحجم والبطانة، لإتاحة وضع محتوى داخلي مطابق لمواصفات المواد.
من الأمثلة على ذلك Button
:
Button( onClick = { /* ... */ }, // Uses ButtonDefaults.ContentPadding by default contentPadding = PaddingValues( start = 20.dp, top = 12.dp, end = 20.dp, bottom = 12.dp ) ) { // Inner content including an icon and a text label Icon( Icons.Filled.Favorite, contentDescription = "Favorite", modifier = Modifier.size(ButtonDefaults.IconSize) ) Spacer(Modifier.size(ButtonDefaults.IconSpacing)) Text("Like") }
الشكل 1. Button
باستخدام الفتحة content
وال المساحة المتروكة التلقائية (يسارًا) وButton
باستخدام الخانة content
التي توفّر contentPadding
مخصّص (على اليمين).
تحتوي السمة Button
على فتحة content
lambda لاحقة عامة، تستخدِم RowScope
لتنسيق المحتوى القابل للإنشاء على التوالي. تتضمن المَعلمة أيضًا معلَمة contentPadding
لتطبيق
المساحة المتروكة على المحتوى الداخلي. يمكنك استخدام الثوابت التي تم تقديمها من خلال
ButtonDefaults
أو قيم مخصّصة.
مثال آخر: ExtendedFloatingActionButton
:
ExtendedFloatingActionButton( onClick = { /* ... */ }, icon = { Icon( Icons.Filled.Favorite, contentDescription = "Favorite" ) }, text = { Text("Like") } )
الشكل 2: ExtendedFloatingActionButton
باستخدام الخانات icon
وtext
.
بدلاً من دالة content
lambda العامة، يحتوي ExtendedFloatingActionButton
على خانتَين للتصنيف icon
وtext
. على الرغم من أنّ كل خانة تتوافق مع محتوى عام قابل للإنشاء، يتم رأي المكوِّن حول كيفية تصميم هذه الأجزاء من المحتوى الداخلي. يتعامل مع المساحة المتروكة والمحاذاة والحجم داخليًا.
سقالة
توفّر ميزة "الإنشاء" تنسيقات مناسبة لدمج المكونات الأساسية في أنماط الشاشة الشائعة. توفّر العناصر القابلة للإنشاء، مثل Scaffold
، خاناتًا لمختلف المكوّنات وعناصر الشاشة الأخرى.
محتوى الشاشة
يحتوي Scaffold
على فتحة lambda عامة واحدة (content
). تتلقّى دالة lambda مثيلاً من الرمز PaddingValues
الذي يجب تطبيقه على جذر المحتوى، مثلاً من خلال Modifier.padding
، وذلك لتعويض الشريطَين العلوي والسفلي، في حال توفّرهما.
Scaffold(/* ... */) { contentPadding -> // Screen content Box(modifier = Modifier.padding(contentPadding)) { /* ... */ } }
أشرطة التطبيقات
يوفر Scaffold
خانات لشريط التطبيق العلوي أو شريط التطبيق السفلي. يتم التعامل مع موضع
العارضات القابلة للإنشاء داخليًا.
يمكنك استخدام الخانة topBar
وTopAppBar
:
Scaffold( topBar = { TopAppBar(title = { Text("My App") }) } ) { contentPadding -> // Screen content }
يمكنك استخدام الخانة bottomBar
وBottomAppBar
:
Scaffold( bottomBar = { BottomAppBar { /* Bottom app bar content */ } } ) { contentPadding -> // Screen content }
ويمكن استخدام هذه الخانات لمكوّنات المادة الأخرى، مثل BottomNavigation
.
يمكنك أيضًا استخدام تركيبات مخصّصة، مثل إلقاء نظرة على شاشة الإعداد من نموذج البومة.
أزرار الإجراءات العائمة
توفّر ميزة Scaffold
خانة زر الإجراء العائم.
يمكنك استخدام الخانة floatingActionButton
وFloatingActionButton
:
Scaffold( floatingActionButton = { FloatingActionButton(onClick = { /* ... */ }) { /* FAB content */ } } ) { contentPadding -> // Screen content }
تتم معالجة موضع الإعلان السفلي لوحدة تحكّم الإجراء الرئيسي تلقائيًا. يمكنك استخدام
المعلَمة floatingActionButtonPosition
لضبط الموضع الأفقي:
Scaffold( floatingActionButton = { FloatingActionButton(onClick = { /* ... */ }) { /* FAB content */ } }, floatingActionButtonPosition = FabPosition.Center ) { contentPadding -> // Screen content }
أشرطة ملونة
توفّر السمة Scaffold
وسيلة لعرض أشرطة الإعلام.
يتم توفير ذلك من خلال SnackbarHost
،
الذي يتضمّن سمة SnackbarHostState
. توفّر السمة SnackbarHostState
إمكانية الوصول إلى دالة
showSnackbar
. تتطلب وظيفة التعليق هذه CoroutineScope
، على سبيل المثال، استخدام rememberCoroutineScope
، ويمكن طلبها استجابةً لأحداث واجهة المستخدم لعرض Snackbar
ضمن Scaffold
.
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 }
يمكنك توفير إجراء اختياري وتعديل مدة Snackbar
.
تقبل الدالة snackbarHostState.showSnackbar
المعلّمتَين الإضافيتَين actionLabel
وduration
، وتعرض SnackbarResult
.
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 { val result = snackbarHostState .showSnackbar( message = "Snackbar", actionLabel = "Action", // Defaults to SnackbarDuration.Short duration = SnackbarDuration.Indefinite ) when (result) { SnackbarResult.ActionPerformed -> { /* Handle snackbar action performed */ } SnackbarResult.Dismissed -> { /* Handle snackbar dismissed */ } } } } ) } ) { contentPadding -> // Screen content }
يمكنك توفير Snackbar
مخصّص باستخدام المعلَمة snackbarHost
. اطّلِع على
SnackbarHost API reference docs
للحصول على
مزيد من المعلومات.
الأدراج
ModalNavigationDrawer
هو درج التنقل الخاص بالتصميم المتعدد الأبعاد.
يمكنك استخدام الخانة drawerContent
لتوفير ModalDrawerSheet
وتوفير محتوى اللائحة:
ModalNavigationDrawer( drawerContent = { ModalDrawerSheet { Text("Drawer title", modifier = Modifier.padding(16.dp)) Divider() 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 } }
البطاقات السفلية
إذا كنت تريد تنفيذ ورقة سفلية، يمكنك
استخدام ModalBottomSheet
الإنشاء.
يمكنك استخدام الخانة content
التي تستخدم ColumnScope
لتنسيق محتوى جدول بيانات قابل للإنشاء في عمود:
ModalBottomSheet(onDismissRequest = { /* Executed when the sheet is dismissed */ }) { // Sheet content }
يتم توسيع جدول البيانات وتصغيره آليًا من خلال
SheetState
. يمكنك استخدام
rememberSheetState
لإنشاء مثيل SheetState
يجب تمريره إلى
ModalBottomSheet
باستخدام المَعلمة sheetState
. SheetState
توفّر إمكانية الوصول إلى الدالتَين show
وcollapse
،
بالإضافة إلى المواقع ذات الصلة بحالة الورقة الحالية. تتطلب هذه الدوال المعلّقة CoroutineScope
، على سبيل المثال، استخدام rememberCoroutineScope
، ويمكن طلبها استجابةً لأحداث واجهة المستخدم. احرص على إزالة
ModalBottomSheet
من المقطوعة الموسيقية عند إخفاء البطاقة السفلية.
val sheetState = rememberModalBottomSheetState() val scope = rememberCoroutineScope() var showBottomSheet by remember { mutableStateOf(false) } Scaffold( floatingActionButton = { ExtendedFloatingActionButton( text = { Text("Show bottom sheet") }, icon = { Icon(Icons.Filled.Add, contentDescription = "") }, onClick = { showBottomSheet = true } ) } ) { contentPadding -> // Screen content if (showBottomSheet) { ModalBottomSheet( onDismissRequest = { showBottomSheet = false }, sheetState = sheetState ) { // Sheet content Button(onClick = { scope.launch { sheetState.hide() }.invokeOnCompletion { if (!sheetState.isVisible) { showBottomSheet = false } } }) { Text("Hide bottom sheet") } } } }