Покретна трака у апликацијама — шта је то, како креирати и подесити

Аутор: IT Sectr Објављено: 2026-07-25 Време читања: 9 мин

Покретна трака (marquee) — визуелни ефекат при којем се текст аутоматски помера хоризонтално унутар ограниченог простора, омогућавајући приказ дугачких редова у компактном контејнеру. Историјски, термин потиче од HTML ознаке <marquee>, популарне у вебу 1990-их. У модерном мобилном развоју scrolling text се користи у плејерима, вестима и статусним тракама. Према Apple Human Interface Guidelines и Google Material Design, покретна трака је дозвољена само у ограниченим сценаријима где статично скраћивање са тачкама погоршава UX.

Главно

  • Покретна трака — аутоматско хоризонтално померање дугачког текста у ограниченом контејнеру.
  • На Android-у се имплементира кроз android:ellipsize="marquee" у TextView.
  • На iOS-у ефекат се ради ручно кроз Core Animation или SwiftUI са анимацијом offset.
  • У вебу HTML ознака <marquee> је застарела; користи се CSS анимација са translateX.
  • За accessibility је обавезна подршка за prefers-reduced-motion.

Шта је покретна трака?

Покретна трака — UI ефекат при којем се текст помера хоризонтално унутар фиксног простора, циклично се померајући како би корисник могао прочитати сав садржај који не стаје у контејнер. За разлику од ellipsize, који скрива део текста, marquee приказује цео текст, али у покрету.

Термин marquee (енгл. — „шатор”, „рекламни пано”) учврстио се захваљујући HTML ознаци <marquee>, која је додата у раним верзијама прегледача Netscape и Internet Explorer. Ознака је омогућавала креирање покретног текста без JavaScript-а и CSS-а, али никада није била део HTML стандарда. Модерни прегледачи настављају да је подржавају ради уназадне компатибилности, али њена употреба се не препоручује.

У мобилном развоју покретна трака решава проблем дугачких натписа у компактним контејнерима: називи песама у плејеру, тикери курсева валута, вести на телевизијским екранима. Међутим, због анимације оптерећује accessibility и може иритирати кориснике — зато се примењује циљано.

Према истраживањима Nielsen Norman Group (2023), покретни текст смањује брзину читања за 15-20% и повећава когнитивно оптерећење. Користите покретну траку само када је статично скраћивање (ellipsize) заиста неприхватљиво.

Покретна трака на Android-у кроз TextView

На Android-у покретна трака се имплементира уграђеним механизмом TextView кроз атрибут android:ellipsize="marquee". Ово је једини режим ellipsize који не скраћује текст, већ анимира његово померање.

За активацију marquee потребна су три услова: singleLine="true" (или maxLines="1"), ellipsize="marquee" и setSelected(true) у коду. Без позива setSelected() анимација се неће покренути.

xml
<!-- XML layout -->
<TextView
    android:id="@+id/marquee_text"
    android:layout_width="150dp"
    android:layout_height="wrap_content"
    android:singleLine="true"
    android:ellipsize="marquee"
    android:marqueeRepeatLimit="marquee_forever" />

// Kotlin: активирај marquee
textView.setSelected(true)
textView.isSingleLine = true

Атрибут marqueeRepeatLimit одређује број понављања анимације: marquee_forever (бесконачно) или конкретан број. Подразумевано — marquee_forever. Ако је текст краћи од ширине контејнера, анимација се не покреће — TextView приказује статичан текст.

Важна карактеристика: setSelected(true) ради само када TextView има фокус или је у режиму selected. У RecyclerView-у то може изазвати проблеме — анимација се покреће само за један елемент. Решење — користите прилагођени MarqueeTextView који преоптерећује isFocused() и увек враћа true.

Почевши од Android 9 (API 28), Google је побољшао понашање marquee — анимација је постала глаткија и не замрзава се при скроловању листе. Међутим, на старијим уређајима marquee може трзати, посебно при високој густини пиксела.

Имплементација scrolling text на iOS-у

На iOS-у не постоји уграђени аналог android:ellipsize="marquee". Покретна трака се имплементира ручно кроз Core Animation или помоћу SwiftUI анимације. Најраширенији приступ — анимација layer.position у комбинацији са clipping контејнером.

У UIKit-у покретна трака се гради на три елемента: контејнер UILabel са clipsToBounds = true, сам текст и CABasicAnimation за померање текста по X са бесконачним понављањем и autoreverses = false, како би се трака померала у једном смеру и враћала скоком.

swift
func startMarquee(for label: UILabel) {
    label.clipsToBounds = true
    label.numberOfLines = 1

    let textWidth = (label.text as? NSString)?
        .size(withAttributes: [.font: label.font as any]).width ?? 0

    guard textWidth > label.bounds.width else { return }

    let animation = CABasicAnimation(keyPath: "position.x")
    animation.fromValue = label.layer.position.x + label.bounds.width / 2
    animation.toValue = label.layer.position.x - textWidth - label.bounds.width / 2
    animation.duration = CFTimeInterval(textWidth / 60)
    animation.repeatCount = .infinity
    animation.autoreverses = false
    label.layer.add(animation, forKey: "marquee")
}

Израчунавање duration = textWidth / 60 даје брзину од око 60 пиксела у секунди — удобан темпо за читање. Ако је брзина већа од 120 px/s, текст постаје нечитак. Ако је испод 30 px/s — анимација изгледа споро. Мењајте speed према конкретном сценарију.

У SwiftUI-ју покретна трака се имплементира једноставније — кроз модификатор offset() са анимацијом која се понавља и .animation(.linear(duration:).repeatForever(autoreverses: false)). SwiftUI аутоматски управља животним циклусом анимације, али захтева GeometryReader за одређивање ширине текста.

CSS анимација уместо ознаке marquee

У вебу застарела ознака <marquee> се не препоручује за употребу, иако прегледачи настављају да је подржавају. Модерна имплементација покретне траке — CSS анимација са кључним кадровима и transform: translateX.

Предности CSS приступа: потпуна контрола над брзином, паузом и кривом анимације, подршка за prefers-reduced-motion за accessibility, одсуство семантички неисправне ознаке.

css
.marquee {
    overflow: hidden;
    white-space: nowrap;
    width: 300px;
}
.marquee-content {
    display: inline-block;
    animation: marquee 10s linear infinite;
}
@keyframes marquee {
    0%   { transform: translateX(0); }
    100% { transform: translateX(-100%); }
}

/* Pause on hover */
.marquee-content:hover {
    animation-play-state: paused;
}

Кључни трик: display: inline-block на садржају гарантује да је ширина елемента једнака ширини текста, а translateX(-100%) га помера тачно за ту ширину улево. Ако садржај има display: block, translateX(-100%) ће бити једнак ширини контејнера, а не текста, и анимација ће се покварити.

За accessibility додајте @media (prefers-reduced-motion: reduce) { .marquee-content { animation: none; } } — корисници са вестибуларним поремећајима видеће статичан текст са могућношћу скроловања.

Када користити и када избегавати

Покретна трака је оправдана у сценаријима где корисник не може сам да прошири контејнер, а пун текст је критично важан: тренутна песма у плејеру на закључаном екрану, вести на телевизијском панелу, покретна трака у апликацији за такси (статус поруџбине).

Покретну траку не треба користити у табелама, листама, обрасцима и дијалозима — свуда где корисник активно интерагује са интерфејсом. Анимација одвлачи пажњу, повећава време проналажења елемента и ствара нелагоду. Према WebAIM (2024), 1 од 3 корисника са вестибуларним поремећајима пријављује нелагоду при гледању анимираног текста.

Правило палца: ако се текст може скратити или поставити у следећи ред — урадите то. Покретна трака је крајња мера, а не универзално решење за дугачке натписе.

Accessibility: анимација и reduced motion

Покретна трака је једна од најпроблематичнијих UI анимација са становишта accessibility. Покретни текст може изазвати вртоглавицу, мучнину и дезоријентацију код особа са вестибуларним поремећајима. Према WCAG 2.2, свака анимација која траје дуже од 5 секунди мора имати механизам паузе или искључивања.

На iOS-у користите својство UIAccessibility.isReduceMotionEnabled за проверу системског подешавања. Ако је reduceMotion укључена — не покрећите анимацију, прикажите статичан текст са ellipsize.

На Android-у проверавајте системску анимацију кроз Settings.Global.ANIMATOR_DURATION_SCALE. Ако је глобална анимација искључена (duration scale = 0), покретну траку не треба укључивати.

У вебу користите медијску функцију prefers-reduced-motion: @media (prefers-reduced-motion: reduce) { .marquee-content { animation: none; } }. Ово је стандардна CSS могућност, подржана од свих модерних прегледача. Проверите у DevTools: укључите емулацију prefers-reduced-motion и уверите се да се анимација искључује.

Често постављана питања

Чиме се Marquee разликује од Ellipsize?

Ellipsize скраћује текст и ставља три тачке, сакривајући део садржаја. Marquee помера цео текст, али у покрету. Избор зависи од приоритета: приказати све (marquee) или сачувати статику (ellipsize).

Како убрзати или успорити покретну траку на Android-у?

Уграђени android:ellipsize="marquee" не дозвољава мењање брзине — она се одређује системским ScrollSpeed. За прилагођену брзину користите Animation или ValueAnimator ручно.

Зашто marquee не ради у RecyclerView-у?

Због поновне употребе view-ова, setSelected(true) се ресетује. Решење: креирајте прилагођени MarqueeTextView који преоптерећује isFocused() и враћа true, или користите прилагођену анимацију у Adapter.onViewAttachedToWindow().

Може ли се направити вертикална покретна трака?

Да, кроз translateY уместо translateX. Вертикални marquee се користи за шпицу (credits) или вести у вертикалним тракама. Принцип је исти, али се мења оса анимације.

Како зауставити покретну траку при фокусу?

У CSS-у: :hover { animation-play-state: paused; }. На Android-у: пратите фокус кроз OnFocusChangeListener и ресетујте setSelected(false). На iOS-у: уклоните анимацију кроз layer.removeAnimation(forKey:).

Резиме

  • Покретна трака — хоризонтално померање текста које приказује садржај у целини кроз анимацију.
  • На Android-у уграђени android:ellipsize="marquee" захтева setSelected(true) и singleLine="true".
  • На iOS-у имплементација се ради кроз CABasicAnimation са кључним путем position.x.
  • У вебу ознака <marquee> је застарела; користите CSS @keyframes са translateX.
  • Примењујте marquee само када ellipsize није прихватљив — у плејерима, тикерима, статусним тракама.
  • Обавезно искључујте анимацију при prefers-reduced-motion на свим платформама.
  • Брзина анимације: ~60 px/s — удобно за читање, изнад 120 px/s — нечитко.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође