Sheet — то је UI компонента која се појављује у доњем делу екрана изнад главног садржаја и пружа додатне радње или информације. Bottom Sheet — најраспрострањенији тип, дефинисан у смерницама Material Design 3 (Google, 2024). За разлику од дијалошких прозора, Sheet не блокира у потпуности интеракцију са позадином и подржава стања collapsed и expanded. Разумевање типова и понашања Sheet-а неопходно је за изградњу удобне навигације у мобилним апликацијама.
Главно
Sheet — то је површински UI компонент који излази са дна екрана и приказује додатни садржај или радње, не одводећи корисника са тренутног екрана. За разлику од прелаза преко целог екрана, Sheet чува контекст: корисник види позадински екран и разуме одакле се појавио Sheet.
Архитектура Sheet-а заснована је на контејнеру са променљивом висином. У минималном стању (collapsed) видљив је само део садржаја — обично наслов или мала панела. Корисник може да повуче Sheet нагоре да би га проширио (expanded), или да превуче надоле да би га затворио. Такво понашање подсећа на физички лист папира који се извлачи испод гомиле — одатле и назив.
Google у смерницама Material Design 3 (2024) истиче два кључна сценарија употребе Sheet-а: приказ додатних радњи које нису стале на главној панели алата, и приказивање форми или детаљних информација без преласка на посебан екран. На iOS-у Apple је додала системску подршку за Sheet почевши од iOS 15 кроз UISheetPresentationController, што потврђује универзалност обрасца.
Material Design дефинише три типа Bottom Sheet-а, сваки са својим понашањем и облашћу примене. Избор правог типа директно утиче на корисничко искуство и усклађеност са смерницама платформе.
Стандардни Bottom Sheet — немодални компонент: корисник може да интерагује са позадинским екраном, не затварајући Sheet. На пример, листајући списак производа у позадинском прозору, корисник види филтере у Bottom Sheet-у и може их мењати без затварања панела. Sheet подешава своју висину према садржају — од 30% до 90% екрана.
Стандардни Bottom Sheet не блокира позадину и омогућава интеракцију са главним садржајем. Ово је кључна разлика од модалног Sheet-а, који захтева обавезну радњу за наставак рада. Користите стандардни Sheet када додатна информација није критична за главни сценарио.
Модални Bottom Sheet блокира интеракцију са позадинским екраном док корисник не изврши радњу унутар Sheet-а. Такав Sheet се увек приказује у expanded стању и захтева експлицитно затварање — преко дугмета, радње или превлачења надоле. Material Design препоручује модални Sheet за форме пријаве, потврде и критична подешавања.
На Android-у модални Bottom Sheet се имплементира кроз BottomSheetDialogFragment, који аутоматски блокира позадину. На iOS-у аналогно понашање обезбеђује модални вариан UISheetPresentationController-а са параметром .mediumDetent. Модални Sheet треба користити само када контекст захтева пажњу корисника.
Проширени Bottom Sheet комбинује својства стандардног и модалног: почиње као немодални у collapsed стању, али при превлачењу нагоре постаје модалан. У пракси то значи да корисник може прво летимично да погледа садржај, а затим да донесе одлуку — да прошири Sheet ради детаљног прегледа или да га затвори.
Овај образац је посебно популаран у мапама и навигаторима, где доња панела приказује кратке информације о тачки руте, а при превлачењу нагоре открива се са детаљима. Google Maps користи управо такав проширени Sheet за приказ информација о местима и рутама.
| Тип Sheet-а | Блокада позадине | Почетно стање | Пример |
|---|---|---|---|
| Стандардни | Не | Collapsed | Филтери у каталогу |
| Модални | Да | Expanded | Форма пријаве |
| Проширени | Делимично | Collapsed | Картица места |
Android SDK пружа неколико API-ја за имплементацију Bottom Sheet-а, почевши од класичног View приступа па до савременог Jetpack Compose-а. Material Components Library за Android укључује готове имплементације BottomSheetDialogFragment и BottomSheetBehavior.
BottomSheetBehavior — то је класа из Material Components-а која се прикачи за било коју View и управља њеном позицијом на екрану. Програмер задаје три стања: STATE_COLLAPSED (савијено), STATE_EXPANDED (проширено) и STATE_HIDDEN (скривено). Behavior аутоматски обрађује гестове превлачења и анимацију.
val sheet = findViewById<View>(R.id.bottom_sheet)
val behavior = BottomSheetBehavior.from(sheet)
behavior.state = BottomSheetBehavior.STATE_COLLAPSED
behavior.peekHeight = 200
Jetpack Compose пружа декларативнији API кроз компоненту ModalBottomSheet из Material 3. За разлику од View приступа, у Compose-у Bottom Sheet је composable функција која прима стање и садржај. Sheet аутоматски анимира појављивање, скривање и промену висине при превлачењу.
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun FilterSheet(onDismiss: () -> Unit) {
ModalBottomSheet(onDismissRequest = onDismiss) {
Text("Филтери")
Button(onClick = onDismiss) { Text("Примени") }
}
}
BottomSheetDialogFragment — то је специјализовани DialogFragment који се приказује као Bottom Sheet. Он аутоматски обрађује модалност, животни циклус и конфигурационе промене. Програмер треба само да прегази onCreateView и врати layout Sheet-а. Према документацији Google-а (Android Developers, 2024), BottomSheetDialogFragment је препоручени начин за модалне Bottom Sheet-ове у класичном Android-у.
Apple је увела системску подршку за Sheet почевши од iOS 15 кроз UISheetPresentationController. До тада су програмери имплементирали Bottom Sheet ручно кроз custom transition или библиотеке трећих страна. Нативни Sheet од Apple-а подржава detents — предефинисане нивое отварања.
UISheetPresentationController — то је уграђени контролер презентације који приказује View Controller као Sheet. Програмер задаје низ detents — вредности висине на којима Sheet може да се заустави. iOS 16 је додао custom detents са произвољном висином. Apple препоручује коришћење medium (.medium) и large (.large) detents-а као основних.
let viewController = MySheetViewController()
if let sheet = viewController.sheetPresentationController {
sheet.detents = [.medium, .large]
sheet.prefersGrabberVisible = true
sheet.preferredCornerRadius = 16
}
present(viewController, animated: true)
SwiftUI пружа модификатор .sheet, који везује приказ Sheet-а за стање. Када published променљива постане true, SwiftUI аутоматски приказује Sheet. SwiftUI такође подржава detents кроз модификатор .presentationDetents, додат у iOS 16.
struct ContentView: View {
@State private var showSheet = false
var body: some View {
Button("Прикажи Sheet") { showSheet = true }
.sheet(isPresented: $showSheet) {
FilterView()
.presentationDetents([.medium, .large])
}
}
}
Вишеплатформски фрејмворци такође подржавају Bottom Sheet, прилагођавајући понашање циљној платформи. Flutter и React Native пружају уграђене и прилагођене имплементације са различитим степеном флексибилности.
Flutter SDK садржи два метода за приказ Bottom Sheet-а: showBottomSheet (стандардни) и showModalBottomSheet (модални). Material Design у Flutter-у следи исте принципе као и у Android-у — Sheet се појављује при дну, подржава превлачење и подесиву висину. За проширено понашање са детектима користи се DraggableScrollableSheet.
Scaffold.of(context).showBottomSheet((context) {
return Container(
padding: EdgeInsets.all(16),
child: Column(
children: [
Text("Садржај Sheet-а"),
ElevatedButton(
onPressed: () => Navigator.of(context).pop(),
child: Text("Затвори")
)
]
)
);
})
React Native нема уграђени Bottom Sheet компонент у језгру, па програмери користе библиотеке трећих страна. Најпопуларнија је @gorhom/bottom-sheet (више од 7 хиљада звездица на GitHub-у, 2024). Она пружа gesture-driven Bottom Sheet са подршком за snap points, анимације и закачене наслове. Библиотека је написана на Reanimated 2 и Gesture Handler-у за перформансе од 60 FPS.
Правилна употреба Bottom Sheet-а захтева поштовање смерница платформе и разумевање сценарија у којима је Sheet прикладан. Размотримо кључне препоруке и уобичајене грешке при пројектовању Sheet-а.
Bottom Sheet је оптималан за радње које су додатне у односу на главни садржај на екрану. Филтери, сортирање, избор опција, кратке информације о елементу — типични сценарији. Material Design препоручује коришћење Bottom Sheet-а за алатке које не треба да заузимају цео екран, али захтевају више простора од Action Sheet-а или Popup менија.
Не користите Bottom Sheet за критична упозорења или грешке — за то су погодни дијалошки прозори. Избегавајте Sheet са великим бројем поља за унос која захтевају скроловање: корисник тешко долази до тастатуре и губи контекст. Ако Sheet садржи више од седам елемената радњи, размотрите посебан екран уместо Sheet-а.
Типична грешка — постављање peekHeight (висина у савијеном стању) на више од 40% екрана. Корисник не разуме да ли види Sheet у целини или се може проширити. Material Design препоручује peekHeight у границама 15-30% висине екрана, да би значајан део садржаја остао скривен и мотивисао на превлачење.
На iOS-у корисници очекују да Sheet може да се затвори превлачењем надоле из било ког положаја. Ако искључите овај гест (кроз UISheetPresentationController.prefersEdgeAttachedInCompactHeight), корисник доживљава фрустрацију покушавајући да затвори Sheet на уобичајени начин. Apple Human Interface Guidelines (2024) наглашавају да је превлачење за затварање — основно очекивање корисника iOS-а.
Често постављана питања
Bottom Sheet не блокира позадину у потпуности и подржава превлачење, док је дијалошки прозор модалан и захтева обавезну радњу. Bottom Sheet је бољи за додатне опције, дијалог — за критичне потврде.
Да, али је потребно подешавање adjustResize или adjustPan у манифесту Android-а. На iOS-у тастатура аутоматски подиже Sheet. Flutter и React Native захтевају ручну обраду кроз MediaQuery за коректно позиционирање.
Препоручује се не више од 5-7 елемената у стандардном Sheet-у. Ако има више садржаја — користите скрол или поделу на категорије. Material Design саветује да не прелазите 90% висине екрана у expanded стању.
За модални Sheet поставите setCancelable(true) на Android-у или isModalInPresentation = false на iOS-у. У Jetpack Compose-у onDismissRequest аутоматски обрађује тап по позадини. У SwiftUI-ју превлачење надоле је стандардно понашање.
Да, све нативне имплементације подржавају VoiceOver и TalkBack. Уверите се да FocusManager коректно помера фокус у Sheet при његовом отварању и враћа га назад при затварању. Прилагођене имплементације захтевају ручно подешавање accessibility.
Резиме
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође