Hero Animation: bu nədir, Flutter-da ümumi elementlərin animasiyası

Müəllif: IT Sectr Dərc olunub: 2026-03-02 Oxuma vaxtı: 8 dəq
Hero Animation — interfeys elementinin ekranlar arasında rəvan hərəkət etdiyi və transformasiya olunduğu animasiya nümunəsidir. Bu, bir kontekstdən digərinə səyahət edən „qəhrəman" effekti yaradır. Standart push/pop keçidindən fərqli olaraq, qəhrəman animasiyası vizual davamlılığı qoruyur: istifadəçi miniatürün tam ekran şəklinə çevrildiyini və ya hüceyrə başlığının ekran başlığına keçdiyini görür. Google Material Design (2025) məlumatına görə, Hero Animation siyahı və təfərrüatlar arasında naviqasiya zamanı koqnitiv yükü 30% azaldır — istifadəçi elementin mövqeyini yadda saxladığı üçün diqqətini itirmir. Flutter-da bu nümunə Hero vidjeti, SwiftUI-da matchedGeometryEffect modifikatoru, Jetpack Compose-da isə Modifier.sharedElement vasitəsilə həyata keçirilir.

Əsas məqamlar

  • Hero Animation — istifadəçi üçün vizual konteksti qoruyan, ümumi elementin ekranlar arasında rəvan keçidi.
  • Flutter Hero — teq üzrə avtomatik olaraq cüt tapan və ekranlar arasında FlightShuttle animasiyasını işə salan vidjet.
  • matchedGeometryEffect — SwiftUI modifikatoru, animasiyalı keçid üçün elementləri namespace-də identifikator vasitəsilə birləşdirir.
  • Shared Element Transition — ActivityOptions və ya Jetpack Compose-da Modifier.sharedElement vasitəsilə həyata keçirilən Android mexanizmi.
  • FlightShuttle — keçid zamanı Hero vidjetinin traektoriyasını və transformasiyasını idarə edən Flutter daxili mexanizmi.

Hero Animation nədir?

Hero Animation — ümumi elementin mənbə ekrandan hədəf ekrana rəvan hərəkət edərək öz şəxsiyyətini qoruduğu interfeys animasiya texnikası. Ad „qəhrəman" metaforasını əks etdirir — əsas element səhnə keçidi vasitəsilə ekranlar arasında hərəkət edir, istifadəçinin diqqətini cəlb edir. Standart keçidlərdən fərqli olaraq, Hero Animation vizual əlaqəni qoparmır: istifadəçi elementin fasiləsiz traektoriyasını görür, bu da naviqasiya iyerarxiyasını anlamağı yaxşılaşdırır.

Hero Animation konsepsiyası Material Design-da siyahı-təfərrüat (list-detail) ekranları, qalereyalar və kartlar üçün tövsiyə olaraq təsbit edilmişdir. Animasiya alqoritmi üç mərhələdən ibarətdir: mənbə ekranda element vurğulanır və mütləq vəziyyətdə sabitlənir; keçid zamanı o, hədəf konteynerə uyğun olaraq miqyaslanır, hərəkət edir və formasını dəyişir; son ekranda element yeni tərtibata inteqrasiya olunur. Material Design 3 məlumatına görə, düzgün tətbiq edilmiş qəhrəman animasiyası səhv „geri" kliklərinin sayını 22% azaldır.

Flutter-da Hero: teqlər və FlightShuttle

Flutter-da Hero Animation Hero vidjeti vasitəsilə həyata keçirilir, o məcburi tag parametrini qəbul edir — unikal identifikator. Flutter mənbə və hədəf marşrutlarında eyni teqə malik Hero cütünü avtomatik tapır və animasiyanı işə salır. Hero vidjeti əl ilə animasiya idarəetməsi tələb etmir — framework FlightShuttle daxili obyekti vasitəsilə traektoriyanı özü hesablayır və transformasiya tətbiq edir.

FlightShuttle — keçid anında Hero vidjetinin örtüklü surətini yaradan, onu mütləq koordinat sistemində yerləşdirən və başlanğıc mövqedən son mövqeyə qədər transformasiyanı (scale, translate, rotate) animasiya edən görünməz „məki"). FlightShuttle-a flightShuttleBuilder xassəsi vasitəsilə fərdi əyrilər ötürülə bilər ki, bu da uçuş traektoriyasını idarə etməyə imkan verir: qövslə uçmaq, sərhədlərdən əks olunmaq və ya gəlməzdən əvvəl yavaşlamaq. Flutter 3.16+-da Hero clipRect və borderRadius-u qoruyaraq animasiyanı dəstəkləyir, bu da düzbucaqlı ekranlara çevrilən yuvarlaq kartlar effekti verir.

SwiftUI-da matchedGeometryEffect

SwiftUI-da Hero Animation-un ekvivalenti matchedGeometryEffect modifikatorudur, iOS 14-də təqdim edilmişdir. O, iki elementi identifikator (id) və ad sahəsi (namespace) vasitəsilə birləşdirir. Flutter-də Hero avtomatik olaraq keçidi ələ keçirdiyi halda, SwiftUI namespace-in açıq şəkildə bəyan edilməsini və modifikatorun səhnənin hər iki hissəsinə — mənbə və hədəf — eyni iyerarxiya daxilində və ya GeometryReader vasitəsilə tətbiq edilməsini tələb edir.

matchedGeometryEffect animasiyası mövqe, ölçü, fırlanma və künc radiusu (cornerRadius) transformasiyasını dəstəkləyir. Hamarlıq üçün withAnimation-da Animation təyin edilir. SwiftUI default easeInOut əyrisi əsasında aralıq vəziyyətləri avtomatik interpolyasiya edir. iOS 17+-də TabView və NavigationStack üçün matchedTransitionSource dəstəyi əlavə edilmişdir — standart keçidlər üçün əvvəlcədən təyin edilmiş traektoriyaya malik sistem analoqu.

Android-da Shared Element Transition

Android-də Hero Animation Shared Element Transition adlanır və ActivityOptions.makeSceneTransitionAnimation və ya FragmentTransaction.addSharedElement vasitəsilə həyata keçirilir. Hər bir ümumi element XML-də transitionName atributu və ya kod vasitəsilə işarələnir, Android isə aktivitələr arasında animasiyaya cavabdehdir. Android 5.0-dan (API 21) etibarən keçidlər framework-un bir hissəsi oldu; bundan əvvəl ValueAnimator vasitəsilə fərdi animasiyalar yazmaq lazım idi.

Jetpack Compose-da Shared Element Transition Modifier.sharedElement və Modifier.sharedBounds modifikatorları vasitəsilə AnimatedContent və ya SharedTransitionLayout ilə birlikdə həyata keçirilir (Compose BOM 2024.01-dən etibarən mövcuddur). View sistemindən fərqli olaraq, Compose elementləri tənbəl şəkildə yenidən çəkir, ona görə də ümumi element CompositionLocal-da keşlənir. Compose həmçinin scrollOffset-u qoruyaraq siyahıdan təfərrüata (list→detail) animasiyanı dəstəkləyir — Hero keçidləri üçün əsas imkan. Google I/O 2024 məlumatına görə, Compose Shared Element Transition RenderNode-un birbaşa idarə edilməsi sayəsində View versiyasından 15% daha sürətli işləyir.

Kod nümunələri

Flutter: Şəkil ilə Hero

Flutter-da Hero Animation-un əsas nümunəsi: siyahı ekranında miniatür və təfərrüat ekranında tam ekran şəkli. image-hero teqi iki vidjeti birləşdirir, FlightShuttle isə kartdan tam ekrana keçidi avtomatik animasiya edir.

dart
import 'package:flutter/material.dart';

class ListScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView(
        children: [
          Hero(
            tag: 'image-hero',
            child: GestureDetector(
              onTap: () {
                Navigator.push(context,
                  MaterialPageRoute(
                    builder: (_) => DetailScreen(),
                  ),
                );
              },
              child: ClipRRect(
                borderRadius: BorderRadius.circular(12),
                child: Image.network(
                  'https://picsum.photos/200',
                  width: 100, height: 100,
                  fit: BoxFit.cover,
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

class DetailScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Detail')),
      body: Center(
        child: Hero(
          tag: 'image-hero',
          child: Image.network(
            'https://picsum.photos/800',
            width: 300, height: 400,
            fit: BoxFit.cover,
          ),
        ),
      ),
    );
  }
}

Əsas məqam — hər iki ekranda eyni teq (image-hero). Flutter marşrut keçidi zamanı Hero vidjetlərini teq üzrə uyğunlaşdırır. Teqlər fərqlidirsə, animasiya işə düşməyəcək — element sadəcə yeni ekranda keçidsiz görünəcək. Teq üçün istənilən tipdən istifadə etmək olar, lakin sətirlər ən etibarlı seçimdir.

SwiftUI: Ekranlar arasında matchedGeometryEffect

SwiftUI-da NavigationStack ilə Hero Animation nümunəsi. matchedGeometryEffect modifikatoru siyahıdakı və təfərrüat ekranındakı şəkli namespace vasitəsilə birləşdirir, withAnimation isə rəvan keçidi işə salır.

swift
import SwiftUI

struct HeroExampleView: View {
    @Namespace private var heroNamespace
    @State private var isDetailShown = false

    var body: some View {
        VStack {
            if isDetailShown {
                DetailView(namespace: heroNamespace)
                    .transition(.identity)
            } else {
                ListView(namespace: heroNamespace)
                    .transition(.identity)
            }
        }
        .animation(Animation.easeInOut(duration: 0.4),
                   value: isDetailShown)
    }
}

struct ListView: View {
    let namespace: Namespace.ID

    var body: some View {
        Image("thumbnail")
            .resizable()
            .frame(width: 100, height: 100)
            .cornerRadius(12)
            .matchedGeometryEffect(id: "hero", in: namespace)
    }
}

struct DetailView: View {
    let namespace: Namespace.ID

    var body: some View {
        Image("thumbnail")
            .resizable()
            .frame(width: 300, height: 400)
            .cornerRadius(0)
            .matchedGeometryEffect(id: "hero", in: namespace)
    }
}

@Namespace matchedGeometryEffect identifikatoru üçün ad sahəsi yaradır. Hər iki element eyni id (hero) və ümumi namespace istifadə edir. isDetailShown dəyişdirildikdə, SwiftUI iki görünüş arasında ölçü, mövqe və cornerRadius transformasiyasını animasiya edərək qəhrəman effekti yaradır. iOS 16+ ilə standart NavigationLink üçün navigationTransition(.hero) istifadə edin.

Android: Jetpack Compose ilə Shared Element Transition

SharedTransitionLayout ilə Jetpack Compose-da Shared Element Transition nümunəsi. sharedElement modifikatoru naviqasiya zamanı ümumi elementi ekranlar arasında animasiya edir.

kotlin
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun HeroExample() {
    SharedTransitionLayout {
        var isDetail by remember { mutableStateOf(false) }

        AnimatedContent(
            targetState = isDetail,
            transitionSpec = {
                fadeIn() togetherWith fadeOut()
            }
        ) { detail ->
            if (detail) {
                Box(
                    modifier = Modifier
                        .fillMaxSize()
                        .sharedElement(
                            state = rememberSharedContentState(key = "hero"),
                            animatedVisibilityScope = this
                        )
                ) {
                    AsyncImage(
                        model = "https://picsum.photos/800",
                        contentDescription = null,
                        modifier = Modifier.fillMaxSize()
                    )
                }
            } else {
                Box(
                    modifier = Modifier
                        .size(100.dp)
                        .sharedElement(
                            state = rememberSharedContentState(key = "hero"),
                            animatedVisibilityScope = this
                        )
                ) {
                    AsyncImage(
                        model = "https://picsum.photos/200",
                        contentDescription = null,
                        modifier = Modifier.fillMaxSize()
                    )
                }
            }
        }
    }
}

Compose SharedTransitionLayout (Compose BOM 2024.01+) iyerarxiyanı əhatə edir, hero açarı ilə sharedElement modifikatoru isə başlanğıc və son elementləri birləşdirir. AnimatedContent vəziyyəti dəyişir və Compose avtomatik olaraq şəklin ölçüsünü, mövqeyini və formasını animasiya edir. Əsas üstünlük — keçid zamanı kartın yuvarlaqlaşdırılması effektini verən bounds və clipBounds animasiyasını dəstəkləməsidir.

Tez-tez verilən suallar

Hero Animation iOS və Android-də işləyir?

Bəli, Hero Animation hər iki platformada mövcuddur. iOS-da SwiftUI-də matchedGeometryEffect və ya UINavigationController.transitioningDelegate istifadə olunur. Android-də — ActivityOptions.makeSceneTransitionAnimation keçidi və ya Jetpack Compose-da Modifier.sharedElement ilə Shared Element Transition. Flutter Hero Animation-u hər iki platformada eyni şəkildə işləyən Hero vidjeti vasitəsilə həyata keçirir.

Eyni anda bir neçə elementi animasiya etmək olar?

Bəli, Hero Animation çoxsaylı ümumi elementləri dəstəkləyir. Flutter-da fərqli teqlərlə bir neçə Hero təyin edin. SwiftUI-da hər elementdə fərqli identifikatorlarla matchedGeometryEffect istifadə edin. Bütün animasiyalar paralel olaraq yerinə yetirilir — hər bir element öz traektoriyası ilə hərəkət edir.

Hero Animation böyük şəkillərdə yavaşlayır?

Performans tətbiqdən asılıdır. Flutter FlightShuttle şəkilləri RenderObject vasitəsilə emal edir, bu da 60fps təmin edir. SwiftUI matchedGeometryEffect vektorlaşdırılmışdır. Böyük şəkillər üçün Flutter-da precacheImage və ya SwiftUI-da prefetch istifadə edin — bu, ilk keçiddə gecikmələri aradan qaldırır. Android Compose AsyncImage vasitəsilə gec yükləmə tələb edir.

Hero standart push keçidindən nə ilə fərqlənir?

Standart push keçidi bütün ekranı hərəkət etdirərək kart yığını illüziyası yaradır. Hero Animation vizual diqqəti bir elementdə cəmləşdirir — istifadəçi onun fasiləsiz hərəkətini görür, bu da ekranlar arasındakı əlaqəni anlamağı yaxşılaşdırır. Push iyerarxik naviqasiya üçün yaxşıdır, Hero — məzmunu vurğulamaq üçün.

Hero Animation üçün əlavə kitabxanalar lazımdır?

Xeyr, Hero Animation daxili vasitələrlə həyata keçirilir. Flutter-da bu, flutter/material.dart paketindən Hero vidjetidir. SwiftUI-da — matchedGeometryEffect modifikatoru. Android Jetpack Compose-da — standart Compose-dan SharedTransitionLayout və Modifier.sharedElement. Əlavə kitabxanalar yalnız qeyri-standart traektoriyalar və ya mürəkkəb transformasiya üçün tələb olunur.

Nəticə

  • Hero Animation — vizual davamlılığı qoruyan və koqnitiv yükü azaldan, ekranlar arasında ümumi elementin animasiyası.
  • Flutter Hero teq və FlightShuttle ilə — animasiyanı əl ilə idarə etmədən qəhrəman animasiyasını həyata keçirməyin ən sadə yolu.
  • SwiftUI matchedGeometryEffect @Namespace.id ilə elementin mövqeyini, ölçüsünü və cornerRadius-unu iki vəziyyət arasında animasiya edir.
  • Android SharedTransitionLayout Modifier.sharedElement ilə Jetpack Compose-da RenderNode keşləməsi ilə keçid təmin edir.
  • Hər üç framework paralel animasiya ilə çoxsaylı ümumi elementləri dəstəkləyir.
  • FlightShuttle Flutter-da flightShuttleBuilder vasitəsilə uçuş traektoriyasını fərdiləşdirməyə imkan verir.
  • Hero Animation Material Design tərəfindən siyahı-təfərrüat ekranları, qalereyalar və kartlar üçün tövsiyə olunur.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun