Компонента ScrollView у React Native — контејнер са могућношћу скроловања садржаја који превазилази димензије екрана. За разлику од FlatList, ScrollView рендерује сав садржај одједном, што је оптимално за мале количине података, форме и екране са познатом висином. Према React Native Docs, 2024, ScrollView подржава вертикално и хоризонтално скроловање, догађај onScroll, програмско управљање позицијом и гестове зумирања. Компонента се рендерује у нативни UIScrollView на iOS-у и ScrollView на Android-у.
Главно
ScrollView — компонента React Native која обавија свој садржај у скролујући контејнер. Ако садржај излази изван граница екрана, корисник може да га помера вертикално или хоризонтално. ScrollView рендерује све поткомпоненте при монтирању, без обзира на то да ли су видљиве на екрану или не.
За разлику од FlatList, који рендерује само видљиве елементе (lazy rendering), ScrollView креира све нативне приказе одједном. То чини ScrollView погодним за форме, странице подешавања, картице производа на једном екрану — свуда где је број поткомпоненти мали (до 20-30) или њихов тачан број унапред није познат.
Према React Native Using ScrollView, 2024, ScrollView подржава угњeждено скроловање (нпр. ScrollView унутар ScrollView), bounce ефекат при досезању ивице, индикаторе скроловања, закључавање позиције (snap) и обраду гестова. На iOS-у ScrollView аутоматски додаје размак испод SafeArea путем contentInsetAdjustmentBehavior.
ScrollView пружа богат скуп својстава за управљање понашањем скроловања, изгледом и интерактивношћу. Размотримо кључне групе: управљање скроловањем, визуелна подешавања, догађаји и платформске карактеристике.
horizontal — пребацује правац скроловања са вертикалног (подразумевано) на хоризонтално. scrollEnabled — искључује скроловање по потреби. showsVerticalScrollIndicator и showsHorizontalScrollIndicator управљају приказом индикатора скроловања. bounces (iOS) укључује/искључује bounce ефекат при досезању ивице садржаја.
Главни догађај — onScroll, који се позива при сваком скроловању и прослеђује објекат са nativeEvent, који садржи contentOffset (тренутна позиција), contentSize (величина садржаја), layoutMeasurement (величина видљивог подручја). onMomentumScrollEnd се позива након завршетка инерционог скроловања. onScrollEndDrag — када корисник пусти екран. Ови догађаји се користе за имплементацију бесконачног скроловања, паралаксе и лењог учитавања.
ScrollView пружа методе за програмско управљање путем референце: scrollTo({x, y, animated}) скролује до наведених координата, scrollToEnd({animated}) — до краја садржаја, flashScrollIndicators() — привремено приказује индикаторе скроловања.
const scrollRef = useRef(null);
// Скролуј на почетак
scrollRef.current.scrollTo({ x: 0, y: 0, animated: true });
// Скролуј на крај
scrollRef.current.scrollToEnd({ animated: true });
Програмско управљање скроловањем се често користи у четовима (аутоматско скроловање до последње поруке), формама (скроловање до поља са грешком) и каруселима (програмско листање).
Избор између ScrollView и FlatList — једна од кључних архитектонских одлука у React Native. Обе компоненте обезбеђују скроловање, али користе суштински различите стратегије рендеровања. ScrollView рендерује све одједном, FlatList — само видљиве елементе.
| Карактеристика | ScrollView | FlatList |
|---|---|---|
| Рендеровање | Сви елементи одједном | Само видљиви + бафер |
| Перформансе | Опадају при 30+ елемената | Стабилне при било ком броју |
| Садржај | Било које компоненте (форме, картице) | Истоврсни елементи из низа |
| Величина података | Мала и средња (до 30 елемената) | Велика и неограничена |
| Хоризонтални скрол | Да (својство horizontal) | Да (horizontal) |
| Секције | Не (рендерује како јесте) | SectionList за секције |
Правило избора: ScrollView — за екране где је број поткомпоненти познат и не прелази 20-30 (профил корисника, форма подешавања, страница производа). FlatList — за листе са потенцијaлно великим бројем елемената (феед вести, каталог производа, поруке ћаскања). Ако је садржај разноврстан (наслов, форма, картица, подножје) — ScrollView је пожељнији, јер FlatList очекује истоврсне елементе.
ScrollView подржава хоризонтално скроловање путем својства horizontal, што га чини идеалним за каруселе, галерије слика, картице и хоризонталне листе. У комбинацији са својством pagingEnabled (iOS) или snapToInterval, ScrollView се претвара у компоненту за пагинирану навигацију.
Својство horizontal пребацује правац скроловања. pagingEnabled (iOS) укључује пагинирано скроловање, где се скрол зауставља само на границама елемената. snapToInterval поставља корак причвршћивања у пикселима за обе платформе.
const ImageCarousel = ({ images }) => (
<ScrollView
horizontal
pagingEnabled
showsHorizontalScrollIndicator={false}
onMomentumScrollEnd={handlePageChange}
>
{images.map((img, index) => (
<Image
key={index}
source={{ uri: img }}
style={{ width: SCREEN_WIDTH, height: 250 }}
/>
))}
</ScrollView>
);
У овом каруселу pagingEnabled аутоматски причвршћује скрол на границе сваке слике. onMomentumScrollEnd омогућава ажурирање индикатора тренутне странице. Такав карусел ради нативно и подржава инерционо скроловање.
За нестандардне кораке причвршћивања користи се snapToInterval (величина корака у пикселима) и snapToAlignment (start, center, end). Помоћу snapToOffsets се може поставити низ конкретних позиција за причвршћивање. Ово је корисно за хоризонталне листе са картицама различитих величина.
Размотримо два типична сценарија: екран са формом (вертикални скрол) и хоризонтална листа категорија. Оба користе ScrollView са различитим својствима за оптимално понашање.
Страница за уређивање профила садржи разноврсне елементе: аватар, неколико поља за унос, прекидаче и дугме за чување. ScrollView омогућава скроловање целе странице у целини, а не сваког блока појединачно.
const ProfileScreen = () => (
<ScrollView
contentContainerStyle={styles.container}
keyboardShouldPersistTaps="handled"
showsVerticalScrollIndicator={false}
>
<AvatarPicker />
<TextInput placeholder="Name" />
<TextInput placeholder="Email" />
<TextInput placeholder="About me" multiline />
<SwitchRow label="Notifications" />
<Button title="Save" />
</ScrollView>
);
Својство keyboardShouldPersistTaps: 'handled' омогућава скроловање и интеракцију са формом док је тастатура отворена. contentContainerStyle примењује размаке на сав садржај. Овај образац се користи у свим екранима са формама у React Native.
За навигацију по категоријама (четови, филтери, картице) користи се хоризонтални ScrollView са чиповима. Оваква компонента се често среће у апликацијама маркетплејса и друштвених мрежа.
const CategoryChips = ({ categories, selected, onSelect }) => (
<ScrollView
horizontal
showsHorizontalScrollIndicator={false}
contentContainerStyle={styles.chipContainer}
>
{categories.map((cat) => (
<Chip
key={cat.id}
label={cat.name}
isSelected={selected === cat.id}
onPress={() => onSelect(cat.id)}
/>
))}
</ScrollView>
);
Хоризонтални ScrollView са искљученим индикатором — стандард за траку категорија. Сваки чип је посебна компонента са стањем избора. Својство showsHorizontalScrollIndicator: false уклања траку скроловања, што одговара очекивањима корисника мобилних апликација.
Често постављана питања
ScrollView је погодан за мале количине података (до 20-30 елемената) и разноврстан садржај (форме, профили, екрани подешавања). FlatList бирајте за дугачке истоврсне листе — феед вести, каталог производа, поруке.
Користите догађај onScroll са onScrollEndDrag или onMomentumScrollEnd. У nativeEvent.contentOffset.y се налази тренутна вертикална позиција. За перформансе користите ScrollEventThrottle (iOS) за подешавање учесталости позивања onScroll.
ScrollView рендерује све елементе при монтирању, стварајући нативне приказе за сваки. При 50+ елемената на екрану, оптерећење меморије и JS нити расте, изазивајући пад фрејмова. За такве случајеве користите FlatList са лењим рендеровањем.
Поставите bounces={false}. Ово својство ради само на iOS-у и искључује ефекат опруге при досезању ивице ScrollView. На Android-у bounce ефекат не постоји подразумевано, па се својство игнорише.
ScrollView не подржава бесконачно скроловање нативно. Међутим, може се комбиновати onScroll са провером приближавања доњој ивици (contentOffset.y + висина екрана >= contentSize.height) и додавати елементе у стање. За озбиљне количине података користите FlatList са onEndReached.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође