TopAppBar یک کامپوننت Material Design است که پنل بالایی برنامه را با عنوان، دکمه ناوبری و اقدامات اضافی نمایش میدهد. در Jetpack Compose، TopAppBar از طریق تابع composable TopAppBar از کتابخانه Material پیادهسازی میشود. طبق مستندات رسمی Android Developers (2025)، TopAppBar از Material2 و Material3، از جمله ارتفاع تطبیقی، رنگها و انیمیشن پشتیبانی میکند. پنل به طور خودکار با نوار وضعیت سیستم تطبیق مییابد و با Insets به درستی کار میکند. TopAppBar به عنوان نقطه ورود اصلی برای ناوبری و اقدامات زمینهای در برنامههای اندروید استفاده میشود.
نکات کلیدی
TopAppBar یک تابع composable از کتابخانه Material Design برای Jetpack Compose است که پنل بالایی برنامه (App Bar) را پیادهسازی میکند. این کامپوننت عنوان صفحه فعلی، دکمه ناوبری در سمت چپ و اقدامات اضافی در سمت راست را نمایش میدهد.
برخلاف سیستم کلاسیک View، نسخه Compose TopAppBar کاملاً اعلانی است: پنل با تغییر وضعیت دوباره ترسیم میشود و از طریق findViewById مدیریت نمیشود. TopAppBar از مفهوم slot API استفاده میکند، جایی که title، navigationIcon و actions به عنوان لامبداهای 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("اصلی") },
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 است که از طریق آن ناوبری پیادهسازی میشود. سناریوهای معمول: باز کردن Navigation Drawer (آیکون Menu)، بازگشت به صفحه قبلی (آیکون ArrowBack) یا بستن صفحه فعلی (آیکون Close).
انتخاب آیکون به موقعیت صفحه در پشته ناوبری بستگی دارد. اگر صفحه ریشه است — آیکون Menu برای باز کردن Drawer نمایش داده میشود. اگر صفحه تو در تو است — آیکون ArrowBack برای بازگشت. در Compose این منطق از طریق NavController پیادهسازی میشود: ورودی فعلی پشته back stack تعیین میکند که کدام آیکون نمایش داده شود.
طبق توصیه Material Design (2025)، عرض منطقه ناوبری 48 dp است — هدف استاندارد برای تعامل لمسی. آیکون باید با بازخورد بصری (ripple) قابل کلیک باشد. در Compose این با بستهبندی در IconButton با callback onClick که ناوبری را راهاندازی میکند تضمین میشود.
هنگام استفاده از Scaffold، دکمه ناوبری ممکن است DrawerState را که به Scaffold منتقل میشود، تکرار کند، نه مستقیماً به TopAppBar. در این حالت navigationIcon از طریق rememberDrawerState به وضعیت Drawer اشاره میکند.
پارامتر actions در TopAppBar یک بلوک composable با زمینه RowScope میپذیرد که امکان قرار دادن چندین آیکون یا دکمه در سمت راست عنوان را فراهم میکند. هر اکشن باید یک عنصر آیکونوگرافیک قابل کلیک باشد: جستجو، اعلانها، تنظیمات، موارد دلخواه.
برای اکشنهای اضافی از منوی کشویی از طریق DropdownMenu استفاده میشود. اگر تعداد اکشنها از سه بیشتر باشد، اکشنهای اضافی در OverflowMenu با آیکون MoreVert قرار میگیرند. با کلیک، لیست اکشنهای مخفی باز میشود. DropdownMenu به طور خودکار نسبت به آیکون قرار میگیرد.
@Composable
fun TopBarWithOverflow() {
var menuExpanded by remember { mutableStateOf(false) }
TopAppBar(
title = { Text("پروفایل") },
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("تنظیمات") }, onClick = { /* navigate */ })
DropdownMenuItem(text = { Text("درباره") }, onClick = { /* navigate */ })
}
}
}
)
}
تنظیم contentDescription برای هر آیکون مهم است — این یک الزام دسترسیپذیری است. بدون توضیحات، TalkBack دکمه را اعلام نمیکند. برای عناصر صرفاً تزئینی از contentDescription = null استفاده کنید.
Material3 (M3) نسخه فعلی Material Design است که توسط Google برای پروژههای جدید توصیه میشود. TopAppBar در M3 از طریق TopAppBar، CenterAlignedTopAppBar و MediumTopAppBar پیادهسازی میشود. تفاوت کلیدی با Material2 — پشتیبانی داخلی از dynamic color، ارتفاع تطبیقی و scroll behavior.
Dynamic Color به طور خودکار رنگهای پنل را بر اساس والپیپر دستگاه انتخاب میکند (Android 12+). TopAppBar در M3 از surfaceColor برای پسزمینه و primary برای عنوان استفاده میکند. اگر dynamic color در دسترس نباشد، پالت fallback از MaterialTheme اعمال میشود. طبق Google Material Design (2025)، 63٪ کاربران Android 12+ از dynamic color در برنامهها استفاده میکنند.
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("کتابخانه") },
navigationIcon = {
IconButton(onClick = { }) {
Icon(Icons.Filled.Menu, contentDescription = "Menu")
}
},
scrollBehavior = scrollBehavior
)
}
) { padding ->
LazyColumn(contentPadding = padding) { /* content */ }
}
}
برای Material3 TopAppBar حتماً از @OptIn(ExperimentalMaterial3Api::class) استفاده کنید — این annotation نشان میدهد که API ممکن است در نسخههای آینده تغییر کند. تا سال 2025 TopAppBar در M3 experimental باقی میماند، اما Google استفاده تولیدی با تأیید مناسب را توصیه میکند.
ScrollBehavior مکانیزمی است که دید TopAppBar را هنگام اسکرول عمودی محتوا مدیریت میکند. در Jetpack Compose، scrollBehavior امکان مخفی یا کوچک کردن پنل را برای آزاد کردن فضا فراهم میکند که به ویژه در صفحههای با لیست بزرگ محتوا مفید است.
Material3 سه استراتژی ارائه میدهد: enterAlways (پنل هنگام اسکرول به بالا ظاهر میشود و هنگام اسکرول به پایین مخفی میشود)، exitUntilCollapsed (پنل فقط پس از جمع شدن کامل عنوان مخفی میشود) و سفارشی از طریق پیادهسازی رابط TopAppBarScrollBehavior. گزینه اول برای فیدهای محتوا مناسب است، دومی — برای صفحات با MediumTopAppBar.
ScrollBehavior نیاز به هماهنگی با LazyColumn یا LazyRow از طریق rememberLazyListState() دارد. وضعیت اسکرول از طریق پارامتر scrollBehavior به TopAppBar منتقل میشود. کامپوننت به طور خودکار رویدادهای اسکرول را دنبال میکند و دید پنل را انیمیشن میکند. طبق 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("محتوا") },
scrollBehavior = scrollBehavior
)
}
) { padding ->
LazyColumn(contentPadding = padding) { /* items */ }
}
ScrollBehavior فقط در Material3 در دسترس است. در Material2 TopAppBar پشتیبانی داخلی برای مخفی شدن هنگام اسکرول ندارد — برای رفتار مشابه نیاز به پیادهسازی دستی از طریق NestedScrollConnection است.
سؤالات متداول
TopAppBar پیادهسازی App Bar در Compose است که به صورت اعلانی از طریق توابع composable کار میکند. Toolbar یک کامپوننت View از طرح XML است. TopAppBar به طور خودکار با تم Compose تطبیق مییابد، از slot API پشتیبانی میکند و برخلاف Toolbar که از طریق کد Activity مدیریت میشود، به findViewById نیاز ندارد.
در Material3 سایه به طور پیشفرض وجود ندارد — TopAppBar به جای elevation از رنگ سطح (surface) استفاده میکند. در Material2 سایه با تنظیم پارامتر elevation = 0.dp حذف میشود. علاوه بر این میتوان Modifier.shadow(0.dp) را برای خاموش کردن کامل فراخوانی کرد.
یک بلوک composable با TextField در پارامتر title منتقل کنید. هنگام فعال شدن جستجو، navigationIcon و actions را از طریق رندر شرطی مخفی کنید. وضعیت را از طریق remember ذخیره کنید: var isSearching by remember { mutableStateOf(false) }. وقتی isSearching = true است، در title به جای Text، TextField رندر میشود.
بله، از طریق composable سفارشی در پارامتر title. به جای یک Text، یک Column با دو Text منتقل کنید: اولی — عنوان اصلی (semibold)، دومی — زیرعنوان (medium، اندازه کوچکتر). MediumTopAppBar دارای پشتیبانی داخلی از عنوان دوخطی با انیمیشن جمعشدن است.
TopAppBar به طور خودکار فاصلههای سیستم را در نظر نمیگیرد. باید Modifier.statusBarsPadding() را روی TopAppBar اعمال کنید یا از Scaffold استفاده کنید که WindowInsets را مدیریت میکند. در Material3 پارامتر windowInsets برای در نظر گرفتن خودکار فیلدهای سیستم اضافه شده است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید