TopAppBar هو مكون من Material Design يعرض الشريط العلوي للتطبيق مع عنوان وزر تنقل وإجراءات إضافية. في Jetpack Compose، يتم تنفيذ TopAppBar من خلال دالة composable TopAppBar من مكتبة Material. وفقًا لوثائق Android Developers الرسمية (2025)، يدعم TopAppBar Material2 و Material3، بما في ذلك الارتفاع التكيفي والألوان والرسوم المتحركة. يتكيف الشريط تلقائيًا مع شريط حالة النظام ويعمل بشكل صحيح مع Insets. يُستخدم TopAppBar كنقطة دخول رئيسية للتنقل والإجراءات السياقية في تطبيقات Android.
النقاط الرئيسية
TopAppBar هي دالة composable من مكتبة Material Design لـ Jetpack Compose تنفذ الشريط العلوي للتطبيق. يعرض المكون عنوان الشاشة الحالية وزر تنقل على اليسار وإجراءات إضافية على اليمين.
على عكس نظام View التقليدي، فإن إصدار Compose من TopAppBar تصريحي بالكامل: يُعاد رسم الشريط عند تغيير الحالة، بدلاً من إدارته من خلال findViewById. يستخدم TopAppBar مفهوم slot API، حيث يتم تمرير title و navigationIcon و actions كلambdas composable. وهذا يسمح بتخصيص أي عنصر من الشريط دون وراثة.
وفقًا لـ Google Material Design (2025)، يأتي TopAppBar في Compose بثلاثة أنواع: CenterAlignedTopAppBar (عنوان مركزي)، و SmallTopAppBar (قياسي)، و MediumTopAppBar (ممتد). يحدد كل نوع ارتفاع الشريط وحجم خط العنوان وسلوك التمرير. يُستخدم النوع المركزي بشكل أكثر في الشاشات الرئيسية، بينما يُستخدم MediumTopAppBar للصفحات ذات المحتوى حيث يتقلص العنوان بسلاسة عند التمرير.
لتشغيل TopAppBar بشكل صحيح، يجب مراعاة هوامش النظام: Insets من WindowInsetsCompat. وفقًا لتوصية Android Developers (2025)، فإن استدعاء Modifier.statusBarsPadding() أو windowInsetsPadding(WindowInsets.systemBars) يمنع تداخل الشريط مع شريط الحالة.
يقبل مكون TopAppBar عدة معلمات إلزامية واختيارية. المعلمة الرئيسية هي title، حيث يتم تمرير كتلة composable مع نص العنوان. نظرًا لأن title هي لامدا @Composable، يمكن إدراج ليس فقط نصًا ولكن أيضًا أيقونة مع نص، أو إنشاء حقل بحث، أو عرض تقدم.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppTopBar() {
TopAppBar(
title = { Text("Main") },
navigationIcon = {
IconButton(onClick = { /* open drawer */ }) {
Icon(
Icons.Filled.Menu,
contentDescription = "Menu"
)
}
},
actions = {
IconButton(onClick = { /* search */ }) {
Icon(Icons.Filled.Search, contentDescription = "Search")
}
}
)
}
تسمح معلمة Modifier بتعيين الحشو والحجم والمحاذاة للشريط بأكمله. من خلال Modifier.heightIn يمكن تحديد الحد الأدنى والحد الأقصى للارتفاع. تقبل معلمة colors كائن TopAppBarColors لتجاوز ألوان الخلفية والعنوان والأيقونات.
افتراضيًا، يستخدم TopAppBar نظام الألوان من MaterialTheme الحالي. إذا كانت هناك حاجة للوحة ألوان مخصصة، استخدم TopAppBarDefaults.smallTopAppBarColors(). في Material3، يتكيف لون الخلفية تلقائيًا مع surfaceColor في السمة الفاتحة والداكنة، مما يلغي الحاجة إلى التكوين اليدوي.
| المعلمة | النوع | الوصف |
|---|---|---|
| title | @Composable () -> Unit | كتلة عنوان الشريط |
| navigationIcon | @Composable () -> Unit | أيقونة التنقل (هامبورغر/سهم) |
| actions | @Composable RowScope.() -> Unit | كتلة الإجراءات على اليمين |
| scrollBehavior | TopAppBarScrollBehavior? | سلوك التمرير |
| colors | TopAppBarColors | نظام ألوان الشريط |
NavigationIcon هو كتلة composable في الجزء الأيسر من TopAppBar يتم من خلالها تنفيذ التنقل. السيناريوهات النموذجية: فتح Drawer التنقل (أيقونة القائمة)، العودة إلى الشاشة السابقة (أيقونة السهم الخلفي)، أو إغلاق الشاشة الحالية (أيقونة الإغلاق).
يعتمد اختيار الأيقونة على موضع الشاشة في مكدس التنقل. إذا كانت الشاشة جذرية، يتم عرض أيقونة القائمة لفتح Drawer. إذا كانت الشاشة متداخلة، يتم عرض أيقونة السهم الخلفي للعودة. في Compose، يتم تنفيذ هذا المنطق من خلال NavController: يحدد إدخال back stack الحالي الأيقونة التي سيتم عرضها.
وفقًا لتوصيات Material Design (2025)، يبلغ عرض منطقة التنقل 48 dp — وهو الهدف القياسي للتفاعل باللمس. يجب أن تكون الأيقونة قابلة للنقر مع ردود فعل بصرية (ripple). في Compose، يتم ضمان ذلك من خلال تغليفها في IconButton مع رد اتصال onClick يؤدي إلى التنقل.
عند استخدام Scaffold، قد يكرر زر التنقل DrawerState، الذي يتم تمريره إلى Scaffold وليس مباشرة إلى TopAppBar. في هذه الحالة، يشير navigationIcon إلى حالة Drawer من خلال rememberDrawerState.
تقبل معلمة actions في TopAppBar كتلة composable مع سياق RowScope، مما يسمح بوضع أيقونات أو أزرار متعددة على يمين العنوان. يجب أن يكون كل إجراء عنصرًا أيقونيًا قابلاً للنقر: بحث، إشعارات، إعدادات، مفضلة.
للإجراءات الزائدة، يتم استخدام قائمة منسدلة من خلال DropdownMenu. إذا تجاوز عدد الإجراءات ثلاثة، يتم وضع الإجراءات الإضافية في OverflowMenu مع أيقونة MoreVert. عند النقر، تفتح قائمة بالإجراءات المخفية. يتم وضع DropdownMenu تلقائيًا بالنسبة للأيقونة.
@Composable
fun TopBarWithOverflow() {
var menuExpanded by remember { mutableStateOf(false) }
TopAppBar(
title = { Text("Profile") },
actions = {
IconButton(onClick = { /* share */ }) {
Icon(Icons.Filled.Share, contentDescription = "Share")
}
Box {
IconButton(onClick = { menuExpanded = true }) {
Icon(Icons.Filled.MoreVert, contentDescription = "More")
}
DropdownMenu(
expanded = menuExpanded,
onDismissRequest = { menuExpanded = false }
) {
DropdownMenuItem(text = { Text("Settings") }, onClick = { /* navigate */ })
DropdownMenuItem(text = { Text("About") }, onClick = { /* navigate */ })
}
}
}
)
}
من المهم تعيين contentDescription لكل أيقونة — وهذا مطلب إمكانية الوصول. بدون وصف، لن يعلن TalkBack عن الزر. للعناصر الزخرفية البحتة، استخدم contentDescription = null.
Material3 (M3) هو الإصدار الحالي من Material Design، الموصى به من قبل Google للمشاريع الجديدة. يتم تنفيذ TopAppBar في M3 من خلال TopAppBar و CenterAlignedTopAppBar و MediumTopAppBar. الفرق الرئيسي عن Material2 هو الدعم المدمج للون الديناميكي والارتفاع التكيفي وسلوك التمرير.
يختار اللون الديناميكي ألوان الشريط تلقائيًا بناءً على خلفية الجهاز (Android 12+). يستخدم TopAppBar في M3 surfaceColor للخلفية و primary للعنوان. إذا كان اللون الديناميكي غير متوفر، يتم تطبيق لوحة ألوان احتياطية من MaterialTheme. وفقًا لـ Google Material Design (2025)، يستخدم 63% من مستخدمي Android 12+ اللون الديناميكي في التطبيقات.
MediumTopAppBar هو إصدار ممتد بعنوان كبير (32 sp)، يتقلص بسلاسة إلى 20 sp عند التمرير، ليتحول إلى SmallTopAppBar. يتم تنفيذ هذا التأثير من خلال TopAppBarDefaults.mediumTopAppBarColors() ومعلمة scrollBehavior. يتم التحكم في حركة الانتقال من خلال TopAppBarState، الذي يتتبع تقلص العنوان.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MediumTopBarExample() {
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior()
Scaffold(
topBar = {
MediumTopAppBar(
title = { Text("Library") },
navigationIcon = {
IconButton(onClick = { }) {
Icon(Icons.Filled.Menu, contentDescription = "Menu")
}
},
scrollBehavior = scrollBehavior
)
}
) { padding ->
LazyColumn(contentPadding = padding) { /* content */ }
}
}
بالنسبة لـ TopAppBar في Material3، يجب استخدام @OptIn(ExperimentalMaterial3Api::class) — يشير التعليق التوضيحي إلى أن API قد يتغير في الإصدارات المستقبلية. اعتبارًا من 2025، لا يزال TopAppBar في M3 تجريبيًا، لكن Google توصي به للإنتاج مع الاختبار المناسب.
ScrollBehavior هي آلية تتحكم في رؤية TopAppBar أثناء التمرير الرأسي للمحتوى. في Jetpack Compose، يسمح scrollBehavior بإخفاء أو تقليص الشريط لتحرير المساحة، وهو مفيد بشكل خاص على الشاشات ذات قوائم المحتوى الكبيرة.
يوفر Material3 ثلاث استراتيجيات: enterAlways (يظهر الشريط عند التمرير للأعلى ويختفي عند التمرير للأسفل)، و exitUntilCollapsed (يختفي الشريط فقط بعد تقلص العنوان بالكامل)، ومخصصة من خلال تنفيذ واجهة TopAppBarScrollBehavior. الخيار الأول مناسب لخلاصات المحتوى، والثاني للشاشات مع MediumTopAppBar.
يتطلب ScrollBehavior التنسيق مع LazyColumn أو LazyRow من خلال rememberLazyListState(). يتم تمرير حالة التمرير إلى TopAppBar عبر معلمة scrollBehavior. يشترك المكون تلقائيًا في أحداث التمرير ويحرك رؤية الشريط. وفقًا لـ Android Developers (2025)، فإن enterAlwaysScrollBehavior هي الاستراتيجية الأكثر شيوعًا، المستخدمة في 75% من التطبيقات ذات TopAppBar القابل للتمرير.
لإنشاء سلوك مخصص، قم بتوسيع TopAppBarScrollBehavior وتجاوز طريقتي onScroll و onDrag. السلوك المخصص مفيد عندما لا تغطي السيناريوهات القياسية متطلبات التصميم — على سبيل المثال، عندما يجب إخفاء الشريط فقط بعد تجاوز حد تمرير معين.
افتراضيًا، لا يضيف scrollBehavior حشوًا للمحتوى — يجب تعيين paddingTop يدويًا عبر contentPadding في Scaffold أو عبر Modifier.padding في LazyColumn. في MediumTopAppBar، يتم حساب الهوامش تلقائيًا من خلال TopAppBarState.collapsedFraction.
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
topBar = {
MediumTopAppBar(
title = { Text("Content") },
scrollBehavior = scrollBehavior
)
}
) { padding ->
LazyColumn(contentPadding = padding) { /* items */ }
}
ScrollBehavior متاح فقط في Material3. لا يحتوي TopAppBar في Material2 على دعم مدمج للإخفاء عند التمرير — للحصول على سلوك مماثل، يلزم تنفيذ يدوي من خلال NestedScrollConnection.
الأسئلة الشائعة
TopAppBar هو تطبيق App Bar في Compose، يعمل بشكل تصريحي من خلال دوال composable. Toolbar هو مكون View من تخطيطات XML. يتكيف TopAppBar تلقائيًا مع سمة Compose، ويدعم slot API ولا يتطلب findViewById، على عكس Toolbar الذي يتم إدارته من خلال كود Activity.
في Material3، الظل غائب افتراضيًا — يستخدم TopAppBar لون السطح بدلاً من elevation. في Material2، تتم إزالة الظل بتعيين المعلمة elevation = 0.dp. بالإضافة إلى ذلك، يمكن استدعاء Modifier.shadow(0.dp) للإزالة الكاملة.
قم بتمرير كتلة composable مع TextField إلى معلمة title. عند تنشيط البحث، قم بإخفاء navigationIcon و actions من خلال العرض الشرطي. قم بتخزين الحالة عبر remember: var isSearching by remember { mutableStateOf(false) }. عندما isSearching = true، اعرض TextField في title بدلاً من Text.
نعم، من خلال composable مخصص في معلمة title. بدلاً من Text واحد، قم بتمرير Column مع عنصري Text: الأول هو العنوان الرئيسي (semibold)، والثاني هو العنوان الفرعي (medium، حجم أصغر). MediumTopAppBar لديه دعم مدمج للعناوين ذات السطرين مع حركة تقلص.
لا يأخذ TopAppBar في الاعتبار هوامش النظام تلقائيًا. من الضروري تطبيق Modifier.statusBarsPadding() على TopAppBar أو استخدام Scaffold الذي يعالج WindowInsets. في Material3، تمت إضافة معلمة windowInsets للمعالجة التلقائية لهوامش النظام.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا