Asosiy fikrlar
Hero Animation — umumiy element manba ekrandan maqsadli ekranga silliq harakatlanib, o'z identifikatorini saqlaydigan interfeys animatsiya texnikasi. Bu nom „qahramon" metaforasini aks ettiradi — asosiy element ekranlar o'rtasidagi sahna o'tishidan o'tib, foydalanuvchi e'tiborini tortadi. Standart o'tishlardan farqli o'laroq, Hero Animation vizual aloqani uzmaydi: foydalanuvchi elementning uzluksiz traektoriyasini ko'radi, bu navigatsiya ierarxiyasini tushunishni yaxshilaydi.
Hero Animation kontseptsiyasi Material Design-da ro'yxat-tafsilot (list-detail) ekranlari, galereyalar va kartalar uchun tavsiya sifatida mustahkamlangan. Animatsiya algoritmi uch fazadan iborat: manba ekranda element ta'kidlanadi va mutlaq holatda mahkamlanadi; o'tish vaqtida u maqsadli konteynerga muvofiq masshtablanadi, harakatlanadi va shaklini o'zgartiradi; yakuniy ekranda element yangi tartibga o'rnatiladi. Material Design 3 ma'lumotlariga ko'ra, to'g'ri amalga oshirilgan qahramon animatsiyasi xato „orqaga" bosishlar sonini 22% kamaytiradi.
Flutter-da Hero Animation Hero vidjeti orqali amalga oshiriladi, u majburiy tag parametrini qabul qiladi — noyob identifikator. Flutter manba va maqsadli marshrutlarda bir xil tegli Hero juftligini avtomatik topadi va animatsiyani ishga tushiradi. Hero vidjeti qo'lda animatsiyani boshqarishni talab qilmaydi — framework FlightShuttle ichki obyekti orqali traektoriyani o'zi hisoblab, transformatsiyani qo'llaydi.
FlightShuttle — o'tish vaqtida Hero vidjetining qoplamali nusxasini yaratadigan, uni mutlaq koordinatalar tizimida joylashtiradigan va boshlang'ich holatdan yakuniy holatgacha transformatsiyani (scale, translate, rotate) animatsiya qiladigan ko'rinmas „mekik". FlightShuttle-ga flightShuttleBuilder xususiyati orqali maxsus egri chiziqlar uzatilishi mumkin, bu parvoz traektoriyasini boshqarish imkonini beradi: yoy bo'ylab uchish, chegaralardan sakrash yoki kelishdan oldin sekinlashish. Flutter 3.16+-da Hero clipRect va borderRadius-ni saqlagan holda animatsiyani qo'llab-quvvatlaydi, bu to'g'ri burchakli ekranlarga aylanadigan yumaloq kartalar effektini beradi.
SwiftUI-da Hero Animation-ning ekvivalenti matchedGeometryEffect modifikatoridir, iOS 14 da taqdim etilgan. U ikki elementni identifikator (id) va nomlar maydoni (namespace) orqali bog'laydi. Flutter-da Hero avtomatik ravishda o'tishni tutib oladigan bo'lsa, SwiftUI namespace-ni aniq e'lon qilishni va modifikatorni sahnaning ikkala qismiga — manba va maqsadli — bir ierarxiya ichida yoki GeometryReader orqali qo'llashni talab qiladi.
matchedGeometryEffect animatsiyasi pozitsiya, o'lcham, aylanish va burchak radiusi (cornerRadius) transformatsiyasini qo'llab-quvvatlaydi. Silliqlik uchun withAnimation-da Animation o'rnatiladi. SwiftUI standart easeInOut egri chizig'i asosida oraliq holatlarni avtomatik interpolyatsiya qiladi. iOS 17+ da TabView va NavigationStack uchun matchedTransitionSource qo'llab-quvvatlashi qo'shilgan — standart o'tishlar uchun oldindan belgilangan traektoriyaga ega tizim analogi.
Android-da Hero Animation Shared Element Transition deb ataladi va ActivityOptions.makeSceneTransitionAnimation yoki FragmentTransaction.addSharedElement orqali amalga oshiriladi. Har bir umumiy element XML-dagi transitionName atributi yoki kod orqali belgilanadi va Android faoliyatlar o'rtasidagi animatsiya uchun javobgardir. Android 5.0 (API 21) dan boshlab o'tishlar framework-ning bir qismiga aylandi; bundan oldin ValueAnimator orqali maxsus animatsiyalar yozish kerak edi.
Jetpack Compose-da Shared Element Transition Modifier.sharedElement va Modifier.sharedBounds modifikatorlari orqali AnimatedContent yoki SharedTransitionLayout bilan birgalikda amalga oshiriladi (Compose BOM 2024.01 dan boshlab mavjud). View tizimidan farqli o'laroq, Compose elementlarni dangasa qayta chizadi, shuning uchun umumiy element CompositionLocal-da keshga olinadi. Compose shuningdek ro'yxatdan tafsilotga (list→detail) scrollOffset-ni saqlagan holda animatsiyani qo'llab-quvvatlaydi — Hero o'tishlari uchun asosiy imkoniyat. Google I/O 2024 ma'lumotlariga ko'ra, Compose Shared Element Transition RenderNode-ni to'g'ridan-to'g'ri boshqarish hisobiga View versiyasidan 15% tezroq ishlaydi.
Flutter-da Hero Animation-ning asosiy misoli: ro'yxat ekranidagi miniatyura va tafsilot ekranidagi to'liq ekran tasviri. image-hero tegi ikkita vidjetni bog'laydi va FlightShuttle kartadan to'liq ekranga o'tishni avtomatik animatsiya qiladi.
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,
),
),
),
);
}
}
Asosiy nuqta — ikkala ekranda bir xil teg (image-hero). Flutter marshrut o'tishida Hero vidjetlarini teg bo'yicha moslashtiradi. Agar teglar farq qilsa, animatsiya ishga tushmaydi — element shunchaki yangi ekranda o'tishsiz paydo bo'ladi. Teg uchun istalgan turdan foydalanish mumkin, ammo qatorlar eng ishonchli variantdir.
NavigationStack bilan SwiftUI-da Hero Animation misoli. matchedGeometryEffect modifikatori ro'yxat va tafsilot ekranidagi tasvirni namespace orqali bog'laydi, withAnimation esa silliq o'tishni ishga tushiradi.
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 identifikatori uchun nomlar maydonini yaratadi. Ikkala element bir xil id (hero) va umumiy namespace dan foydalanadi. isDetailShown o'zgartirilganda, SwiftUI ikki ko'rinish o'rtasida o'lcham, pozitsiya va cornerRadius transformatsiyasini animatsiya qilib, qahramon effektini yaratadi. iOS 16+ bilan standart NavigationLink uchun navigationTransition(.hero) dan foydalaning.
SharedTransitionLayout bilan Jetpack Compose-da Shared Element Transition misoli. sharedElement modifikatori navigatsiya vaqtida umumiy elementni ekranlar o'rtasida animatsiya qiladi.
@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+) ierarxiyani o'rab oladi va hero kaliti bilan sharedElement modifikatori boshlang'ich va yakuniy elementlarni bog'laydi. AnimatedContent holatni o'zgartiradi va Compose avtomatik ravishda tasvir o'lchami, pozitsiyasi va shaklini animatsiya qiladi. Asosiy afzallik — o'tish vaqtida kartaning yumaloqlanishi effektini beradigan bounds va clipBounds animatsiyasini qo'llab-quvvatlash.
Tez-tez beriladigan savollar
Ha, Hero Animation ikkala platformada ham mavjud. iOS-da SwiftUI-dagi matchedGeometryEffect yoki UINavigationController.transitioningDelegate ishlatiladi. Android-da — ActivityOptions.makeSceneTransitionAnimation o'tishi yoki Jetpack Compose-da Modifier.sharedElement bilan Shared Element Transition. Flutter Hero Animation-ni ikkala platformada bir xil ishlaydigan Hero vidjeti orqali amalga oshiradi.
Ha, Hero Animation bir nechta umumiy elementlarni qo'llab-quvvatlaydi. Flutter-da turli teglar bilan bir nechta Hero belgilang. SwiftUI-da har bir elementda turli identifikatorlar bilan matchedGeometryEffect dan foydalaning. Barcha animatsiyalar parallel ravishda bajariladi — har bir element o'z traektoriyasi bo'ylab harakatlanadi.
Ishlash unumdorligi amalga oshirishga bog'liq. Flutter FlightShuttle rasmlarni RenderObject orqali qayta ishlaydi, bu 60fps ni ta'minlaydi. SwiftUI matchedGeometryEffect vektorlashtirilgan. Katta rasmlar uchun Flutter-da precacheImage yoki SwiftUI-da prefetch dan foydalaning — bu birinchi o'tishdagi kechikishlarni bartaraf qiladi. Android Compose AsyncImage orqali dangasa yuklashni talab qiladi.
Standart push o'tishi butun ekranni siljitadi, kartalar to'plami illyuziyasini yaratadi. Hero Animation vizual e'tiborni bir elementga qaratadi — foydalanuvchi uning uzluksiz harakatini ko'radi, bu ekranlar o'rtasidagi bog'liqlikni tushunishni yaxshilaydi. Push ierarxik navigatsiya uchun yaxshi, Hero — tarkibni ta'kidlash uchun.
Yo'q, Hero Animation o'rnatilgan vositalar bilan amalga oshirilgan. Flutter-da bu flutter/material.dart paketidagi Hero vidjeti. SwiftUI-da — matchedGeometryEffect modifikatori. Android Jetpack Compose-da — standart Compose-dan SharedTransitionLayout va Modifier.sharedElement. Qo'shimcha kutubxonalar faqat nostandart traektoriyalar yoki murakkab transformatsiyalar uchun talab qilinadi.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.