Bileşen listesi ve öncelikler
Kaynak: android/snippets deposunun 7bdac078 sürümü. 583 Kotlin dosyasında her androidx.compose.* sembolünün kaç dosyada import edildiği sayıldı (parantez içindeki sayılar). Bir API'nin resmi örneklerde ne kadar sık geçtiği, gerçek uygulamalarda ne kadar gerektiğine iyi bir vekil.
Durum: ✅ var · 🟡 kısmen / farklı biçimde · ⬜ yok
Runtime
| API | Durum | Not |
|---|---|---|
@Composable (276) | ✅ | composable(site, args..., [=]{...}): yeniden başlatılabilir ve atlanabilir. ComposableScope: inline (Column gibi) |
remember (135), mutableStateOf (93) | ✅ | |
rememberSaveable, rememberSaveableStateHolder / SaveableStateProvider | ✅ | değer bir SaveableStateHolder içinde içerik görünmezken korunur (nav girdileri, kaydedilmiş sekmeler, LazyColumn/LazyRow'da kaydırılıp çıkan öğeler, anahtarıyla); rememberScrollState, rememberLazyListState, rememberPagerState, rememberNavController, rememberTextFieldState saveable. Kaydedilebilir türler (Saver<T>: sayı, bool, enum, metin, bunların vektörü/optional'ı, MutableState, kaydırma/liste/pager durumları, TextFieldState, NavController, SaveableStateHolder) ComposeHost::saveState() ile baytlara yazılır: Android arka plana geçerken Activity'nin Bundle'ına koyar, süreci bitirip geri getirince ilk kareden önce geri yüklenir (gezinme yığını, girdilerin ve liste öğelerinin değerleri dahil). Bir sağlayıcının dışındaki değer, composable'ı ayrılınca gider (Compose gibi). ViewModel'ler süreçle gider, SavedStateHandle'larındaki değerler kalır. Yerinde verilen kaydedici (Compose'un Saver(save, restore), listSaver, mapSaver): CustomSaver<T>{save, restore}, listSaver<T>(…), mapSaver<T>(…) ve rememberSaveable(kaydedici, init) — Saver<T>'si olmayan bir tür ya da başka türlü yazılacak bir değer için; init bir MutableState<T> yaparsa durum o kaydediciyle saklanır (Compose'un stateSaver'ı); okunamayan kayıtta init kullanılır. Material durumları da Compose'daki gibi kaydedilir: rememberTopAppBarState (daralma ve kaydırma; başlangıç değerleri parametreyle), rememberDrawerState, rememberFloatingToolbarState/rememberBottomAppBarState, rememberModalBottomSheetState (açık sayfa geri gelince yeniden kayarak açılmaz; yarı yolu kalmadıysa tam açılır), rememberSearchBarState, rememberSwipeToDismissBoxState (kaydırılıp atılan satır kenarın dışında gelir), rememberTimePickerState, rememberWideNavigationRailState, rememberDatePickerState, rememberDateRangePickerState, rememberPaneExpansionState (Saver<...> özelleştirmeleriyle; elle yapılan durumlar da rememberSaveable ile kaydedilebilir) |
getValue/setValue (113/95) | 🟡 | Kotlin by delegasyonu; C++'ta .get() / .set() |
rememberCoroutineScope (33), LaunchedEffect (26), değer döndüren suspend fonksiyonlar, withContext(Dispatchers.IO/Default) | ✅ | C++20 coroutine'leri: -> Task, co_await delay(...), iptal = frame'i yok etme; TaskOf<T>: değer döndüren eşyordam (Kotlin'in değer döndüren suspend fun'ı) — co_return değer;, başka bir eşyordamdan T x = co_await f(); (onun parçası olarak çalışır, onunla iptal olur; attığı istisna bekleyende yakalanır; iç içe olabilir); co_await withBackground([] { return iş(); }) (Compose'un withContext(Dispatchers.IO/Default)'u): iş birkaç çalışan iş parçacığından birinde yapılır, eşyordam UI iş parçacığında dönen değerle (ya da atılan istisnayla) sürer; arada iptal olursa iş biter, sonucu atılır; iş parçacığı olmayan web derlemesinde hemen orada çalışır; test kuralı waitForIdle arka plan işlerini bekler |
mutableIntStateOf/FloatStateOf/LongStateOf (20/8/2), mutableDoubleStateOf | ✅ | mutableStateOf'un takma adları (değer zaten kutusuz tutuluyor) |
CompositionLocalProvider (15), compositionLocalOf (2), staticCompositionLocalOf, providesDefault, CompositionLocalContext | ✅ | Tek tip CompositionLocal<T> (adresiyle tanınır, kopyalanmaz; global tanımlayın): CompositionLocal<T>{varsayılan} ya da compositionLocalOf<T>([] { … }) / staticCompositionLocalOf(…) — varsayılan sağlayıcısız ilk okunduğunda bir kez yapılır, atabilir (sağlanması şart olan yerel: []() -> User { throw … }); ikisi de yalnızca okuyan kapsamları yeniden oluşturur (statik olan da). providesDefault(değer): yukarıda sağlayan yoksa verir (bir kütüphanenin uygulamanın ezebileceği varsayılanı). currentCompositionLocalContext() o noktada sağlanan bütün yerelleri alır (okuyan kapsam hepsine abone), CompositionLocalProvider(bağlam, içerik) başka yerde hepsini yeniden verir. Yok: compositionLocalWithComputedDefaultOf, providesComputed |
ProvideTextStyle | ✅ | ProvideTextStyle({.fontSize = 20, .fontWeight = FontWeight::Bold, .color = …}, içerik): içindekilerin metin stili mevcut olanla birleşir (yazı tipi, boyut, kalınlık, stil, aile LocalTextStyle'a; renk LocalContentColor'a) |
LocalLayoutDirection (LayoutDirection.Rtl), Modifier.absoluteOffset, absolutePadding | ✅ | CompositionLocalProvider({LocalLayoutDirection.provides(LayoutDirection::Rtl)}, …): kendi yönü olmayan metin (yalnızca rakam, noktalama) düzenin yönünde yazılır (TextDirection::Content, Compose gibi; Text, TextField, rememberTextMeasurer), Row sağdan başlar, Start/End (hizalama, Arrangement, padding, offset) aynalanır, yatay kaydırma/LazyRow/Pager sağdan başlar ve parmağı ters yönde izler (fırlatma, sayfa oturtma, odağı görünüme getirme dahil); çekmece sağdan çıkar, SwipeToDismissBox yönleri aynalanır. Aynalanmayanlar: çizim (drawBehind, Canvas), absoluteOffset/absolutePadding, pencere inset'leri, anchoredDraggable (Compose gibi ekran yönünde). Slider/RangeSlider (iz sağdan başlar, başlangıç başparmağı sağda) ve Switch (açıkken başparmak solda) aynalanır; Icons::AutoMirrored::Filled::ArrowBack/ArrowForward/KeyboardArrowLeft/KeyboardArrowRight/List/Send (Compose'un Icons.AutoMirrored'ı) sağdan sola aynalı çizilir (ImageVector::autoMirrored()/mirrored(); ayna bir kez üretilir), DatePicker'ın ay okları da. Açılır menü (DropdownMenu, ExposedDropdownMenuBox) sağdan sola çapanın sağ kenarına hizalanır. Uygulamanın yönü sistemin dilinden gelir: ComposeHost::setLayoutDirection kökte LocalLayoutDirection'ı verir, SDL arka ucu (masaüstü, Android, web) tercih edilen ilk dil sağdan sola yazılıyorsa (isRtlLanguage: ar, he/iw, fa, ur, ps, ckb, sd, ug, yi, dv, ks) RTL açar, dil değişince günceller; KOMPOZ_LAYOUT_DIRECTION=rtl|ltr ile zorlanır |
DisposableEffect (10), SideEffect (5), key (1) | ✅ | |
mutableStateListOf (9) | ✅ | SnapshotStateList<T> |
mutableStateMapOf (SnapshotStateMap) | ✅ | mutableStateMapOf<K, V>({{k, v}, …}): okumak abone eder, değiştirmek okuyanları yeniden oluşturur; girdiler anahtar sırasında (std::map); get(k) (std::optional), getOrDefault, containsKey, put (önceki değeri döner; aynı değer kimseyi yeniden oluşturmaz), putAll, remove (olmayan anahtar kimseyi yeniden oluşturmaz), clear, update |
derivedStateOf (8), rememberUpdatedState (5), produceState (2) | ✅ | derivedStateOf okuyucuları yalnızca değer değişince yeniden kompoze olur |
snapshotFlow (5) | ✅ | co_await snapshotFlow([&] { ... }).collect(...): okunan durumlar değişip sonuç farklı olunca bildirir (kare istemeden) |
viewModel(), ViewModel (onCleared, viewModelScope) | ✅ | en yakın sahibin ViewModel'i: gezinme girdisi (yığından tamamen çıkıp ekrandan kaybolunca temizlenir; saveState ile saklanan sekmede yaşar) ya da uygulama; tür ve isteğe bağlı anahtarla. viewModelScope temizlenince iptal olur. viewModel<T>(*entry.parent()): iç içe grafiğin ekranları grafiğin ViewModel'ini paylaşır. SavedStateHandle: yapıcısı onu alan ViewModel'e verilir; içindeki kaydedilebilir değerler (get/set/remove/keys, getStateFlow gözlenebilir) uygulamanın kayıtlı durumuyla yazılır (gezinme girdisininkiler NavController'la), süreç bitip geri gelince aynı sahip ve anahtardaki ViewModel'e geri verilir; girdi yığından çıkınca onunkiler de gider. Notlar: gezinme argümanları handle'a konmuyor |
Lifecycle, LifecycleOwner, LocalLifecycleOwner, LifecycleEventEffect, LifecycleStartEffect, LifecycleResumeEffect, collectAsStateWithLifecycle | ✅ | durumlar (Initialized→Created→Started→Resumed, aşağı Destroyed) adım adım geçilir, her adım bir olay (OnCreate…OnDestroy); addObserver sonradan ekleneni o anki duruma kadar olaylarla getirir, dönen tutamaç gidince gözlemci kalkar; currentStateAsState() gözlenebilir, currentStateFlow(). Uygulamanınki (ComposeHost::lifecycleOwner()) pencereyi izler: Android'de arka plana geçerken Started (o sırada kaydedilen durum Bundle'a girer) sonra Created, dönünce Resumed; masaüstünde/web'de odak kaybında Started, simge durumuna küçültülünce ya da gizlenince Created; host yok olurken Destroyed. Gezinme girdisi de bir LifecycleOwner (ekranının LocalLifecycleOwner'ı): gösterilen ekran Resumed (geçiş sürerken Started), çıkmakta olan Started, yığında bekleyen ve kaydedilmiş sekme yığınındakiler Created, yığından çıkıp ekrandan kaybolan Destroyed (sonra ViewModel'leri temizlenir); hepsi NavHost'un kendi yaşam döngüsünü (iç içe NavHost'ta üst girdininkini) aşmaz ve onunla anında (kare beklemeden) iner; NavHost kompozisyondan çıkınca ekranları Created'a iner. Efektler olaylara doğrudan bağlı (arka planda kare çizilmese de çalışır); collectAsStateWithLifecycle(flow, minActiveState = Started) altına inince toplamayı bırakır (abone sayılmaz: WhileSubscribed yukarı akışı durdurur), dönünce son değeri alır. Notlar: kaydedilmiş sekme yığınındaki girdiler Jetpack'teki gibi yok edilmez, Created'da bekler; Android'de pencere odağı (bildirim perdesi) yaşam döngüsünü değiştirmez |
collectAsState (6), StateFlow/MutableStateFlow | ✅ | flow.collectAsState() değeri döndürür, değişince çağıranı yeniden kompoze eder; setValue/update (atomik)/compareAndSet her iş parçacığından, toplayıcılar UI iş parçacığında; birleştirilmiş (conflated) |
Soğuk Flow (flow { emit }, flowOf, emptyFlow) ve operatörleri | ✅ üretici bir korutin, co_await emit(v) toplayıcı değeri alınca sürer (geri basınç); map, filter, onEach, transform, take (üreticiyi istisnasız durdurur), distinctUntilChanged, debounce, flatMapLatest (yeni değer öncekini iptal eder), combine (iki akış ya da StateFlow), stateIn(scope, başlangıç) (Kotlin'in SharingStarted.Eagerly'si), launchIn, collectAsState(başlangıç); StateFlow'da asFlow() ve aynı operatörler. Toplayan korutin iptal olunca üretici ve operatörlerin kendi korutinleri de gider. MutableSharedFlow<T>(replay) (her iş parçacığından tryEmit, her toplayıcıya her değer, yeni gelene son replay değer, subscriptionCount), shareIn, stateIn(scope, SharingStarted::Eagerly / Lazily / WhileSubscribed(5000ms), başlangıç): WhileSubscribed yukarı akışı yalnızca dinleyen varken toplar, son dinleyici gidince zaman aşımı kadar bekleyip durdurur, değer kalır. Yok: SharedFlow taşma politikaları (toplayıcı kuyrukları sınırsız), ikiden çok akışlı combine | |
Modifier.blur(radius) / blur(radiusX, radiusY, edgeTreatment), BlurredEdgeTreatment | ✅ Compose'daki gibi: renderEffect'i bir BlurEffect olan bir graphicsLayer; yalnızca iki yarıçap da sıfırdan büyükse bulanıklaştırır; BlurredEdgeTreatment bir şekil tutar: Rectangle (varsayılan) ya da BlurredEdgeTreatment{shape} onu sınırlara ya da şekle göre keser, sınırların ötesindeki pikseller kenarınki sayılır (TileMode::Clamp); Unbounded sınırların dışına solarak yayılmasına izin verir (Decal). GPU renderer'ında yarıçap için Android'in sigmasıyla (0.57735 r + 0.5 px) bir Gauss; geniş olanlar Skia'nın yaptığı gibi küçültülür (birebir Gauss'tan en fazla 3 / 255 farkla); SDL'de doku yarıçapın ikinin kuvveti kadar kez yarıya küçültülüp adım adım geri büyütülür (Gauss'a yakın, birebir değil; yazılım çiziciyle bulanıklık yok). blur(BlurRadiusSpec, edgeTreatment, alpha) ve blur([](BlurScope&) { … }) (çizimde, düğümün boyutuyla okunur) Compose 1.13'ün kademeli bulanıklıklarıdır: BlurRadiusSpec::uniform (bir BlurEffect), verticalGradient, horizontalGradient, linearGradient(start, end, …) ve radialGradient(…, center, fallOffRadius); her biri bir yarıçaptan ötekine ya da BlurStop'lar üzerinden; ve shader(maxRadius, [](Density, Size) { … }) (her piksel en geniş yarıçap çarpı bloğun katmanın boyutu ve düğümün yoğunluğu için yaptığı shader'ın o pikseldeki alfası kadar, katmanın sol üstünden dp'siyle; yalnızca kendine eşit) (BlurRadiusSpec::createRenderEffect(size, edgeTreatment, density) effect'i verir); GPU'da Compose'un çizdiği gibi (shader'ın alfası önce yarım float'lık bir dokuya çizilir) (kendi Gauss'u: sigma r / 2 px, r px'e kadar, en fazla 150 px, önce yatay sonra dikey, her piksel kendi yarıçapıyla); SDL'de keskin pikseller ile en geniş yarıçapla bulanıklaştırılmışlar, her pikselin ne kadar bulanıklaştığına göre karıştırılır (yazılım çiziciyle bulanıklık yok). Geçersiz değerler reddedilmez, aralığa çekilir (0'ın altındaki yarıçaplar 0, kesirler 0..1). Her biçim bir BlurType alır (Kompoz'un): Family (varsayılan, Compose'unki: düğüm ve çocukları), Morph (buzlu cam: düğümün arkasında çizilen, şekli içinde bulanıklaşır, düğüm ve çocukları üstünde keskin kalır; GraphicsContext::drawBackdrop, aynı hedefin o ana dek tuttuğunu okur — offscreen bir katmanda o katmanınkini) ya da Self (yalnızca düğümün kendi çizdiği — arka plan, kenarlık, resim, drawBehind — çocukları aradaki öğelerin yerleştirdiği gibi üstünde keskin); alfa bulanıklaşanla gider. Bir Morph düğümünün arkasındaki bir değişiklik okuduğu her yeri yeniden çizdirir. | |
movableContentOf (MovableContent) | ✅ remember([] { return movableContentOf([] { … }); }), sonra card(): aynı bileşimde başka bir yerde çağrılınca (Row yerine Column, öbür bölme) hatırlanan değerleri, düğümleri ve süren efektleri (LaunchedEffect devam eder, DisposableEffect bitmez) oraya taşınır; yeni yer eski yerden önce ya da sonra bileşilsin. Aynı bileşimde iki yerde çağrılırsa ikincisi yeni bir örnektir; hiç çağrılmayınca bileşim sonunda bir kez unutulur. Parametreli biçimler: movableContentOf<P1, P2…>([](const P1&, const P2&…) {...}) her çağrıda verilen parametrelerle kompoze olur, durumu yanında taşınır; movableContentWithReceiverOf<R, P…>([](R&, const P&…) {...}) alıcıyı ilk parametre olarak alır (Compose'un R.(P) -> Unit'i) | |
Channel (channel.hpp), BufferOverflow, produce, consumeEach, receiveAsFlow/consumeAsFlow | ✅ Kotlin'in Channel'ı: her öğe bir kez alınır. Kapasite Rendezvous (varsayılan, gönderen alıcıyı bekler), sayı, Buffered (64), Conflated (yalnızca sonuncusu), Unlimited; dolunca BufferOverflow::Suspend (bekler) / DropOldest / DropLatest. co_await send(v) → alındı ya da tampona girdiyse true, kapalıysa (ya da beklerken iptal edildiyse) false; trySend beklemez, her iş parçacığından. co_await receive() → sıradaki öğe ya da kapanıp boşalınca nullopt (Kotlin'in receiveCatching'i; hiçbir şey istisna atmaz); tryReceive. close() gönderimi bitirir, kalanlar yine alınır; cancel() kalanları da atar. isClosedForSend/Receive, isEmpty. receiveAsFlow() öğeleri toplayıcılar arasında paylaştırır; consumeAsFlow()/consumeEach() bitince kanalı iptal eder. produce<T>(scope, blok, kapasite): blok bitince kapanan, iptal olursa iptal edilen kanal. Korutinler UI iş parçacığında sürer. Not: öğe verildikten sonra ama korutin sürmeden iptal edilen alıcıya verilen öğe kaybolur (Kotlin'de onUndeliveredElement olmadan da öyle) | |
withFrameNanos (1) | ✅ | co_await awaitFrame() |
Layout (foundation.layout)
| API | Durum |
|---|---|
padding (120), fillMaxSize/Width/Height (117/67/6), size (51), width/height (18/39) | ✅ |
Column (108), Box (92), Row (50), Arrangement (66), Spacer (36) | ✅ Compose'daki gibi tam piksellerde yerleşir (roundToPx boyutlar, padding kenarları ve aralık; hizalama yarım yukarı; ağırlıkların artan pikselleri ilklere) |
PaddingValues (16), offset (16), heightIn/widthIn (4/3), safeDrawingPadding (3) | ✅ |
aspectRatio (14), wrapContentSize/Width/Height (13), requiredSize/Width/Height (5), requiredSizeIn/WidthIn/HeightIn | ✅ required*In gelen kısıtları yok sayan aralıklar: verilmeyen (en büyüğü kInfinity) gelenini, verilenin izin verdiği kadar korur; gelen kısıtların dışına taşan ortalanır |
sizeIn, defaultMinSize, offset { } | ✅ offset { } lambda ile (layout'ta okunur); defaultMinSize sadece gelen en küçük 0 iken uygulanır |
WindowInsets (7), windowInsetsPadding (4), imePadding (3), systemBars, navigationBarsPadding, consumeWindowInsets | ✅ türler (status/navigation bar, ime, cutout, sistem hareketleri, captionBar — serbest pencerenin başlık çubuğu, systemBars'a dahil —, mandatorySystemGestures, tappableElement, waterfall, safeGestures = hepsinin hareket kenarları, safeDrawing/safeContent; captionBarPadding, waterfallPadding, systemGesturesPadding, mandatorySystemGesturesPadding, safeGesturesPadding; Android 11+), preferredFrameRate(hz) / preferredFrameRate(FrameRateCategory::Normal|High|NoPreference): yerleşimdeyken ekranın tazeleme hızına istek (en hızlısı kazanır; Android 11+'da çizdiği yüzeye Surface.setFrameRate, High ekranın en hızlı kipi, Normal 60 Hz; başka yerde bir şey yapmaz). Bir istektir, Compose'unki gibi: sistemin politikası son sözü söyler — ör. HyperOS 14 Ultra'da tanımadığı uygulamaları 60 Hz'e kısar (dumpsys display: render: (0.0 60.0)), istek SurfaceFlinger'a ulaşsa da ekran 60'ta kalır; imeNestedScroll(): içindeki kaydırılabilir sonuna gelip çekilmeye devam edince klavye parmakla gelir, aşağı itince önce o gider, bırakınca fırlatmaya ya da yarıya göre açık/kapalı biter (Android 11+, WindowInsetsAnimationController; bir metin alanı odaktayken; başka yerde bir şey yapmaz); onConsumedWindowInsetsChanged { tüketilen -> } yerleşimde, kendisinden önce (aynı zincirde ve atalarında) tüketilen insetler değişince çağrılır, iç içe padding'lerde tüketme; windowInsetsTopHeight/BottomHeight/StartWidth/EndWidth (çubuğun altına/üstüne boşluk; çevrede alınmışı saymaz, kendisi almaz; sağdan solada başlangıç sağdır); bileşenler Compose varsayılanlarıyla; sistem çubuğu ikonları SystemBarsAppearance. Android 11+'da WindowInsets::ime() klavye kayarken onu kare kare izler (WindowInsetsAnimation: imePadding klavyeyle birlikte yükselir, bir kerede zıplamaz); WindowInsets::imeAnimationSource()/imeAnimationTarget() kaymanın başladığı ve gittiği yer (dururken ime()), WindowInsets::isImeVisible() klavye açık ya da açılıyor mu |
BoxWithConstraints (6) | ✅ layout kısıtları state'e yazılır, içerik aynı karede yeniden kompoze olur |
IntrinsicSize (4), FlowRow/FlowColumn (1) | ✅ width(IntrinsicSize::Min): metinler en geniş kelimeleri kadar (her boşlukta kırılır, kelime bölünmez, biçimli kısımlar kendi boyutlarıyla; maxLines sayılmaz), Row bunların toplamı, Column en genişi — Compose'un min intrinsic'i gibi; Max: tek satırdaki genişlik; yükseklikte Min = Max (verilen genişlikte doğal yükseklik) |
AlignmentLine (FirstBaseline, LastBaseline), Modifier.alignByBaseline/alignBy, paddingFrom/paddingFromBaseline | ✅ metinler ve metin alanları (tek satırda metnin çizgisi, çok satırda ilk ve son görünen satırınki) taban çizgilerini bildirir, üstteki düzenler çocuklarınınkini devralır (ilkinde en üstteki, sonuncusunda en alttaki; dolgu dahil); Row içinde alignByBaseline() farklı boyutlu metinleri ve düğme etiketlerini aynı çizgiye koyar (satır gerekirse uzar); paddingFromBaseline(üst, alt) ilk taban çizgisini üstten, sonuncusunu alttan o kadar uzağa koyar; kendi Layout'unda placeable[FirstBaseline] / node->alignmentLine(...) |
Foundation
| API | Durum | |
|---|---|---|
background (57), clickable (36), border (14), verticalScroll (15), rememberScrollState (17), BorderStroke, shadow(…, clip, ambientColor, spotColor) | ✅ border(BorderStroke(genişlik, renk ya da fırça), şekil): fırçalı (degrade) kenarlık, şeklin içinde; shadow(yükseklik, şekil, clip, ambientColor, spotColor): gölge iki rengin karışımıyla, alfaları oranında soluk ya da güçlü, clip içeriği şekle kırpar (Compose'unki gibi; iki parametreli shadow Compose'dan farklı olarak kırpmaz). ScrollState: value() ve maxValue() gözlenebilir (Compose'daki gibi: okuyan composable kaydıkça yeniden oluşur; derivedStateOf ile yalnızca gereken), canScrollForward/Backward(), isScrollInProgress() (gözlenebilir: kullanıcı sürüklerken ve ardından fırlatırken, animateScrollTo/animateScrollBy sürerken; LazyListState, LazyGridState ve — animasyonsuz — LazyStaggeredGridState'te de; tekerlek ya da dokunuş fırlatmayı durdurunca biter). verticalScroll(durum, enabled, reverseScrolling) / horizontalScroll(…): enabled = false ve tembel liste, ızgara ve kademeli ızgaralarda userScrollEnabled = false — yalnızca kodla (scrollTo, scrollToItem, animasyonlar) ve bir şeyi görünüme getirmek için kayar; sürükleme, fırlatma, tekerlek, iç içe kaydırmada içindekinin artanı (bir üstteki alır) ve erişilebilirlik kaydırması yok; reverseScrolling: sondan (alttan, sağdan) başlar, değeri oradan geri sayar | |
| Overscroll (Android 12+ esnemesi) | ✅ verticalScroll/horizontalScroll, lazy listeler ve pager'lar parmakla ucundan öteye çekilince içerik çekilen kenardan esner (direnç artarak), parmak geri gelince önce esneme geri alınır, bırakınca yayla geri döner; uca çarpan fling kısa bir esneme yapar. Fare ve tekerlek esnetmez; çıplak scrollable() ve iç içe kaydırmada ebeveynin (ör. PullToRefresh) aldığı kısım esnemez. LocalOverscrollFactory (Compose 1.8): CompositionLocalProvider({LocalOverscrollFactory.provides(std::nullopt)}, …) içinde yapılan kaydırma kapları (verticalScroll/horizontalScroll, tembel listeler ve ızgaralar, pager'lar) esnemez. OverscrollEffect (Compose 1.8): kendi efektiniz — applyToScroll(delta, kaynak, performScroll) (önce bir kısmını alıp kalanını kaydırmaya verir, artanı gösterir), applyToFling(hız, performFling) (coroutine; co_await performFling(kalan) kullanılan hızı döndürür, gerisi uca çarpınca kalan), isInProgress(), draw(ContentDrawScope&) ve onRemeasured(boyut); rememberOverscrollEffect() (esneme; fabrika kapalıyken null), withoutVisualEffect/withoutEventHandling; verticalScroll/horizontalScroll(state, efekt, …), LazyListOptions/LazyGridOptions/LazyStaggeredGridOptions/PagerOptions::overscrollEffect (boş: esneme, nullptr: yok), scrollable(state, yön, efekt, …) (yalnızca olaylar) + Modifier.overscroll(efekt) (çizildiği yer). Yalnızca dokunmatik sürüklemeler ve fırlatmaları efekte gider | |
isSystemInDarkTheme (15) | ✅ | |
Image (34) + ContentScale (28), ImageBitmap, Painter, Modifier.paint | ✅ imageResource: JPEG, PNG, WebP, BMP (web'de eşzamanlı yalnızca PNG/BMP), kodla piksel. Painter (Compose'daki gibi): BitmapPainter, painterResource("images/x.png"), VectorPainter/rememberVectorPainter (Compose'un VectorPainter'ı gibi: vektör çizildiği boyutun pikselleri kadar bir bitmap'e çizilir — vektör o boyut için onu saklar, son sekizini — ve o 1:1 çizilir; painter'ın renk süzgecinden, yoksa vektörün tintColor/tintBlendMode'undan, o da yoksa, hepsi tek renkse, o renkte bir Alpha8 maske olarak; autoMirror'lıysa sağdan solda aynalanır; rememberVectorPainter(varsayılanGenişlik, yükseklik, [viewportGenişlik, yükseklik, [ad, tintColor, tintBlendMode, autoMirror]], [&](float viewportGenişlik, float viewportYükseklik) { vector::Group({…}, [&] { vector::Path({…}); }); }) Compose'unki gibi composable içerikten vektör yapar (kompoz::vector: Group, Path ve bir ağacı her adın VectorConfig'iyle, onun VectorProperty'lerini değiştirerek çizen RenderVectorGroup(grup, configs), Compose'un animasyonlu vektörlerinin yaptığı gibi): okuduğu durum/animasyon vektörü yeniden yapar (onu hatırlayan composable yeniden oluşur), aynı sonuç aynı vektör kalır; viewport verilmezse varsayılan boyutu piksel olarak; adı verilmezse VectorRootGroup), ColorPainter, BrushPainter, Painter::custom([](DrawScope&) {...}, içselBoyut); yerleşikler çizdikleri aynıysa eşit (kompoze atlanır). Image(painter, açıklama, modifier, alignment, contentScale, alpha, colorFilter) Compose'un PainterNode'u gibi boyutlanır (genişliği sabit bir resim Fit'te içsel yüksekliğinde kalır, FillWidth büyütür) ve kırpılır; Icon(painter) kendi boyunda (yoksa 24 dp), LocalContentColor ile boyanır; Modifier.paint(painter, sizeToIntrinsics, alignment, contentScale, alpha, colorFilter) içeriğin arkasına çizer (sağdan solda Start sağda). Bir painter'ın renk süzgeci, çizdiği şeylerin çevresinde yürürlüktedir (GraphicsContext::pushColorFilter), özel painter'ın çizimi de dahil. Not: özel painter'ın alfası katmanla | |
ColorFilter (tint, colorMatrix, lighting), ColorMatrix (setToSaturation, setToScale, timesAssign), BlendMode | ✅ Image(…, colorFilter), AsyncImageOptions::colorFilter, DrawScope::drawImage(…, colorFilter), painter'lar: süzgeç onlar çizerken yürürlüktedir (GraphicsContext::pushColorFilter, içteki süzgeç önce); Kompoz'un GPU renderer'ı onu piksel başına uygular, SDL_Renderer her renge ve fırçaya, resimlere de her biri için CPU'da bir kez yapılan bir kopyayla (resim yaşadıkça saklanır, son 32). Bir vektörün path'leri süzgeçten kendi boyalarıyla geçer (gri matris gri kalır). tint 29 karışım modunun hepsini alır (varsayılan SrcIn: biçimi o renkte); blend(kaynak, hedef, mod) birini hesaplar; Icon zaten tint alır | |
AsyncImage (Coil), rememberAsyncImagePainter | ✅ AsyncImage(model, açıklama, modifier, {placeholder, error, contentScale, crossfadeMillis}): varlık/dosya yolu ya da http(s) adresi, arka planda yüklenip çözülür (Linux masaüstünde libjpeg-turbo, libwebp, libcurl varsa; Android'de BitmapFactory ve HttpURLConnection; web'de tarayıcı ve fetch; Windows'ta WIC ve WinINet), aynı model tek yükleme, 64 MB bellek önbelleği (en az kullanılan gider), geçiş efekti, onState; resim yerleşimin ilk verdiği boyutta çözülür (Coil gibi: büyük resim küçük kutuda 2'nin kuvvetleriyle küçültülür, kutudan küçük olmaz; libjpeg-turbo/libwebp/WIC/BitmapFactory çözerken küçültür), indirilenler disk önbelleğinde kalır (DiskCache, uygulamanın önbellek dizini, Application::imageDiskCacheBytes = 64 MB, KOMPOZ_IMAGE_CACHE, KOMPOZ_IMAGE_LOG); rememberAsyncImage(model, size) durumu verir; rememberAsyncImagePainter(model) yüklenince resmin Painter'ı (öncesinde boş, boyutsuz), Image(painter) ya da Modifier.paint için. Notlar: Android'de ağ için INTERNET izni, düz http:// için usesCleartextTraffic; Windows'ta WebP sistemin WebP codec'iyle; web'de disk önbelleği tarayıcınınki; HTTP önbellek başlıklarına bakılmaz | |
LazyColumn (45), items (21), LazyRow (5), rememberLazyListState (7) | ✅ key, contentPadding, spacing, fling; rememberLazyListState(index) bir öğede açılır; reverseLayout (ilk öğe altta, sohbetler gibi); animateScrollToItem (uzaktakine önce yaklaşıp atlar, sonra yay ile kayar; öğe ölçüldükçe hedefi düzeltir), animateScrollBy, stopScroll; ScrollState::animateScrollTo/By (sürükleme ya da yenisi durdurur); LazyListState::layoutInfo() (gözlenebilir, her düzenden sonra yalnızca değişince): visibleItemsInfo (indeks, anahtar özeti, içeriğin başından — dolgu sonrası — ofset, boy, contentType; sabitlenen başlık önce), viewportStartOffset (−önceki dolgu) / viewportEndOffset, totalItemsCount, viewportSize, yön, reverseLayout, dolgular, aralık — derivedStateOf ile "sona yaklaştı mı" (daha fazla yükle); contentType (items(n, key, contentType, …), item(key, contentType, …), liste biçimi) layoutInfo'da geri söylenir (öğeler yeniden kullanılmadığı için başka etkisi yok); metin anahtarlar (item("başlık", …)) metinleriyle özetlenir. Izgaralarınki LazyGridState / LazyStaggeredGridState üzerinden (layoutInfo()); LazyListOptions::arrangement (Compose'un verticalArrangement/horizontalArrangement'ı): spacing yerine aralığı verir ve öğelerin hepsi sığınca ekrandaki yerlerini (Arrangement::Bottom, Center, SpaceBetween, spacedBy(8, Kind::Center)…; ters listede Top uzak uç); sığmayınca her zamanki gibi baştan kayar | |
RoundedCornerShape (32), CircleShape (17), clip (26) | ✅ çizim bağlamından katmansız kırpar (GraphicsContext::pushClipShape); RoundedCornerShapePercent(50) (Compose'un RoundedCornerShape(percent): kısa kenarın yüzdesi), lerp(şekil, şekil, t) köşeleri karıştırır (dönüşen köşeler; köşesi kendine ait olanlarda köşe köşe); shadow(yükselti, şekil). Köşeleri kendine ait şekiller: RoundedCornerShape(üstBaş, üstSon, altSon, altBaş) (dp) ya da CornerSize ile ({8} dp, CornerPercent(50) pay) — RTL'de baş sağdadır; Compose gibi bir kenarın iki köşesi kısa kenara sığmazsa ikisi birlikte küçülür. Arka plan, çerçeve, kırpma, gölge, graphicsLayer kırpması ve dalga (ripple) bu köşeleri izler; arka uçlar CornerRadii ile çizer (tek yarıçap dört eşit köşeye dönüşür) | |
Canvas (10), drawBehind (11), drawWithContent (5) | ✅ Compose'un imzaları ve parametreleriyle DrawScope: drawLine, drawRect, drawImage (piksel boyutunda ya da srcOffset/srcSize pikselini dstOffset/dstSize'a, FilterQuality'nin dediği gibi örneklenerek: None en yakın piksel, Low (varsayılan) bilinear, Medium mipmap'lerden bilinear, High Mitchell'in kübiği — GPU renderer'ında premultiplied texellerden, saydam bir pikselin rengi sızmasın diye; SDL_Renderer Medium ve High'ı Low gibi örnekler), drawRoundRect (CornerRadius(x, y): çeyrek elipsler), drawCircle, drawOval, drawArc(…, useCenter, …) (Skia'nın çizdiği yol: pasta dilimi, kiriş, açık yay; bir tur ve fazlası), drawPath, drawPoints (kıl kalınlığında noktaları bir piksel) — her biri bir renk ya da fırçayla, alpha, style (Fill ya da Stroke(width, miter, cap, join, pathEffect): genişlik 0 kıl kalınlığında, dönüşüm ne olursa olsun bir piksel), colorFilter ve blendMode ile; density(), layoutDirection(); metin ve vektörler (Kompoz'un drawText(text, topLeft, font, color)'ı, drawVector); translate (içindeki drawContent() da kayar)/inset/clipRect/rotate/scale; PathEffect (Stroke(…, pathEffect), bir Paint'inki), Skia'nınki (Android'inki) gibi ve Skia'nın uyguladığı gibi uygulanır: yol çizilirken, çizildiği piksellerde (daha ince bir ölçekte eğriler daha ince ölçülür): dashPathEffect(aralıklar, phase) (her kontur desene yeniden başlar; kapalı olanın son kesiği ilkine bağlanır; eğriler kendi parçaları olarak kesilir; uçları düz bir çizgi dikdörtgenler olarak kesilir; sıfır uzunluklu bir kesik, uçları için sıfır uzunluklu bir çizgidir; dolgu kesilmez; tek kalan son aralık Android'deki gibi bırakılır), cornerPathEffect(r) (iki çizgi arasındaki her köşe r kadar, en çok çizginin yarısı kadar geri kesilir ve bir ikinci derece eğriyle birleşir; eğriler olduğu gibi, dolgular da), stampedPathEffect(şekil, advance, phase, StampedPathEffectStyle::Translate / Rotate / Morph) (şekil her konturda her advance'te bir basılır: oraya taşınarak, gittiği yöne çevrilerek ya da boyunca bükülerek, her kenarı ortasından geçen bir ikinci derece eğri olarak; çizilmez, doldurulur; p, ilk basımı advance − p'ye koyar), chainPathEffect(dış, iç) (önce içtekinin etkisi, sonra yaptığına dıştakinin); Skia'nın reddettiği (aralık yok, negatif bir aralık, hiç açık yok; yarıçap yok; advance yok ya da boş şekil) etkisizdir; filterPath bir etkinin ne yaptığını gösterir. PathMeasure Android'inki (Skia'nın SkPathMeasure'ı) gibi: uzunluğu olmayan konturlar atlanır, eğriler her parça bir çizgiye yarım birim yaklaşana dek ikiye bölünür (daha ince çizilen bir yol için resScale), getPosition/getTangent eğrilerin kendisi üzerinde (kontur yoksa NaN: Compose'un Offset.Unspecified'ı), getSegment eğrilerin parçalarını eğri olarak verir (ikinci derece eğrininki ikinci derece, koniğinki konik), isClosed, nextContour — dikdörtgen, daire, yay, yol ve drawLine(…, cap, pathEffect) çizgilerinde; drawPoints (PointMode.Points/Lines/Polygon); her çizimde blendMode (renk ya da fırçayla): Kompoz'un GPU renderer'ında Compose'un 29 modunun hepsi (Porter-Duff olanlar, Modulate, Plus, ayrılabilir ve ayrılamaz olanlar), W3C'nin kompozisyon belirtimi ve Skia'nın tanımladığı gibi; SDL_Renderer SrcOver, DstIn, DstOut, Clear, Src, Dst ve Plus çizer (öbürlerini SrcOver gibi) — graphicsLayer { compositingStrategy = CompositingStrategy::Offscreen } katmanı her zaman ekran dışında açar, içindeki karışım modları yalnızca o katmana etki eder (kenarı solan liste: drawContent() sonra drawRect(degrade, blendMode = DstIn)); BlendMode'da 29'unun hepsi var (ColorFilter::tint'te de hepsi); Path.op(a, b, PathOperation::Union / Intersect / Difference / ReverseDifference / Xor) ve Path::combine, a + b, a - b, a | b, a & b, a ^ b (yolların fillType'ına göre; sonuç içi solunda kalan, işlenenlerin onu sınırlayan segment parçalarından oluşan kapalı konturlar — bir eğrinin parçası aynı eğri (conic'inki conic), uçları eğrilerin buluştuğu yerde, dp'nin yüzde biri içinde; delikler, kendini kesen yollar, ortak kenarlar, köşeden değen parçalar ayrı konturlar), Path::contains(nokta); PathMeasure: length, getPosition, getTangent, getSegment, nextContour (eğriler ince çoklu çizgi olarak ölçülür, parçalar çizgi olarak döner) | |
Brush (solid, linearGradient, horizontalGradient, verticalGradient, radialGradient, sweepGradient), TileMode | ✅ renk durakları ya da eşit aralıklı renkler; uçlar alanın kenarı (kInfinity); TileMode::Clamp (uç renk), Repeated (baştan tekrar), Mirror (ileri geri), Decal (dışı saydam) — doğrusal ve dairesel degradelerde; SDL'de döşenen degrade 256 tekselli bir dokudan, ağın UV'leriyle çizilir (tekrarlar keskin), kırpılmış yollarda tepe noktası renkleriyle | |
Shader, LinearGradientShader, RadialGradientShader, SweepGradientShader, ImageShader, CompositeShader, ShaderBrush (Brush::shader), Brush.composite, ShaderBrush.transform, Brush.intrinsicSize, lerp(Brush) | ✅ Compose'daki gibi: bir shader boyadığının dp'sinde piksel piksel boyar (bir resmin pikseli bir dp): degrade duraklarında (ya da eşit aralıkla) döşeme moduna göre, resim önceden çarpılmış piksellerinden bilineer olarak ve iki döşeme moduna göre yatayda ve dikeyde döşenerek, iki shader bir karışım moduyla birleştirilerek; transformed(Matrix) (p'de boyadığını matrisin p'sinde boyar; ikincisi birinciden sonra). Brush::shader(createShader, intrinsicSize) shader'ını boyadığı boyut için yapar, yalnızca başka bir boyut için yeniden, ve yalnızca kendine ve kopyalarına eşittir; Brush::shader(shader) her boyutta aynı shader'dır; Brush::composite(dst, src, blendMode) iki fırçanın shader'larını birleştirir (renk tek renkli bir degrade olarak) ve aynı üçlüden yapılmışa eşittir; withTransform(Matrix) bir degradenin ya da shader'ın boyamasını taşır (createShader(size) shader'ı onunla verir); boyamanın alfası shader fırçasını soldurur (shaderAlpha); intrinsicSize() (doğrusal degradenin verilen uçları arası, dairesel olanın çapı, shader fırçasının kendi boyutu; olmayanda NaN); lerp(a, b, t) iki rengi, aynı türden iki degradeyi (renkler sıra sıra, verilen durakların konumları, uçlar, merkezler ve yarıçaplar; döşeme modu ve verilmemiş merkez yarı yolda değişir) ve bir renkle bir degradeyi (o renkteki degrade) karıştırır; gerisi yarı yolda değişir. GPU renderer'ı shader'ları dönüşümlerinden geçirerek (perspektif de) piksel piksel hesaplar; resimler döşeme modlarıyla kendi dokularından örneklenir, bir birleşimin ikisi de aynı biçimde hesaplanıp pikselin olduğu yerde karıştırılır (birleşimlerin birleşimi önce kendi dokusuna çizilir); SDL'de shader fırçası CPU'da (Shader::colorAt) alanın dokusuna hesaplanır, yolun kapsamıyla çarpılır. Henüz yok: RuntimeShader (AGSL) | |
Color (64 bit), ColorSpace, ColorSpaces, Rgb, Connector, WhitePoint, Illuminant, TransferParameters, Adaptation, ColorModel, RenderIntent, lerp(Color), compositeOver, luminance, toArgb, Color.hsv/hsl | ✅ Compose'unki gibi: bir Color, Compose'un paketlediği gibi paketlenmiş 64 bittir: sRGB'de ARGB'si üst 32 bitte, kanal başına 8 bit (Color{1, 0.5f, 0}, Color::hex(0xFF8000), Color::argb(0xFFFF8000), Color(value)), başka bir yerleşik renk uzayında (Color(r, g, b, alpha, ColorSpaces::DisplayP3); Compose'un 20 uzayı, onun kimlikleriyle) bileşenleri uzayın aralığında yarım float'lar, 10 bitlik bir alfa ve uzayın kimliği. red(), green(), blue(), alpha() (bir L*a*b* ya da Oklab renginin L, a, b'si), colorSpace(), convert(uzay) (uzayların connector'ı üzerinden, algısal olarak), copy(alpha) ve copy(alpha, red, green, blue), compositeOver (arka planın uzayında), luminance, toArgb, isSpecified, colors::Unspecified (0x10). lerp(başlangıç, bitiş, t) Oklab'da karıştırır, t 0..1 içinde, bitişin uzayında; canlandırılan bir renk Compose'un Color.VectorConverter'ı gibi gider (Oklab'da, bir yay ya da easing aştıkça hedefinin ötesine, her bileşen aralığında tutularak): animateColorAsState, geçişler, sonsuz geçişler ve animasyonlu vektörlerde. colorspace paketi Compose'unki gibi: birincil renkler ve beyaz noktadan ya da bir matristen, aktarım fonksiyonları, ICC parametrik eğrileri (PQ ve HLG de) ya da bir gamayla RGB uzayları, isWideGamut/isSrgb, CIE XYZ, L*a*b* ve Oklab, herhangi ikisi arasında connector'lar (yerleşiklerinki saklanır), başka bir beyaz noktaya adapt (Bradford, von Kries, CIECAT02), ColorSpaces::match. Gradyanlar renklerini Skia'nınkiler gibi sRGB'de karıştırır. sRGB'de çizilir: başka bir uzayın rengi çizilirken (genişletilmiş) sRGB'ye çevrilir, yolda 8 bite yuvarlanmadan (F16 bir bitmap daha incesini tutar); malzeme renk araçları bir rengin sRGB'sini alır. Henüz yok: geniş gamlı çıktı (P3 bir ekranınki), arka uç aşamalarıyla | |
ImageBitmap(width, height, config, hasAlpha, colorSpace), ImageBitmapConfig, Canvas(ImageBitmap), readPixels, toPixelMap, PixelMap | ✅ Compose'daki gibi, yani Android'in Bitmap'i: içine çizilen bir bitmap, pikselleri saydam (alfası olmayanda siyah ve opak: Rgb565 ya da hasAlpha = false); kopyaları aynı bitmap'tir. graphics::Canvas(bitmap) ona piksel başına bir birimle, canvas giderken platformun renderer'ıyla UI iş parçacığında çizer (başka iş parçacığından beklenir; renderer yoksa — platformsuz testler — biri gelene dek tutulur). Her config çizileni Android'deki gibi saklar: Argb8888 ve Gpu kanal başına 8 bit, F16 yarım float (8 bitten ince, 0..1'in ötesi de), Alpha8 yalnızca alfa (maske olarak çizilir: canvas'tan boyanın rengi ya da shader'ıyla, DrawScope'tan Compose'daki gibi siyah), Rgb565 siyahın üstüne 5, 6 ve 5 bit, opak; alfası olmayan çizileni siyahının üstünde tutar. GPU renderer'ında bir Argb8888, Gpu ya da F16 bitmap dokusu olarak tutulur (eskisinin üstüne yeni bir dokuya çizilir, önce kaydedilen çizimler eskisini okur) ve pikselleri istenince geri okunur (readPixels, pixels()); öbürleri çizildikçe geri okunur; SDL_Renderer bir hedefe çizip geri okur (F16'yı 8 bitte). readPixels(buffer, startX, startY, width, height, bufferOffset, stride) ARGB verir, toPixelMap() bir PixelMap (map(x, y) bir Color); version() her çizimde değişir ve onu gösteren (doku, görüntü listesi, renk filtresinin kopyası, ImageShader) bunu izler. colorSpace() yapıldığı uzaydır (verilmezse sRGB); pikselleri çizildikleri ve gösterildikleri gibi sRGB'de tutulur | |
drawIntoCanvas, Canvas (ui.graphics: graphics::Canvas), Paint, PaintingStyle, CanvasDrawScope.draw | ✅ Compose'daki gibi, yani Android'in Canvas'ı: save, restore (kaydedilmiş bir şey yoksa bir şey yapmaz), saveLayer(bounds, paint) (boyanın alfası, renk filtresi ve karışım moduyla birleştirilen bir katman), withSave, withSaveLayer; translate, scale (bir pivot etrafında da), rotate (saat yönünde; pivot etrafında), rotateRad, skew(sx, sy) (Android'in Canvas'ı ve Compose'unki gibi katsayılar: x' = x + sx·y, y' = sy·x + y; Compose belgesinde derece yazar), skewRad (degrees(radyan)'ı aynı biçimde iletir), concat(Matrix) (z satırı ve sütunu Android'deki gibi atlanır) — her biri var olanın önüne; clipRect (sıralanır, ClipOp), clipPath; drawLine (stil ne olursa olsun çizgi, butt uçlar butt), drawRect, drawRoundRect(…, radiusX, radiusY), drawOval, drawCircle, drawArc/drawArcRad (Skia'daki gibi sıralanır), drawPath, drawImage ve drawImageRect (boyanın alfasıyla solar; rengi ve shader'ı kullanılmaz), drawPoints, drawRawPoints, drawVertices(Vertices, blendMode, paint) (Skia'nın çizdiği gibi bir üçgen ağı: Vertices(VertexMode::Triangles / TriangleStrip / TriangleFan, positions, textureCoordinates, colors, indices) ya da dizili biçimi; ortası bir üçgenin içinde kalan her piksel, kenar yumuşatması olmadan; boyanın shader'ı doku koordinatının olduğu yerde ya da rengi opak olarak, köşe renkleriyle — aralarında önceden çarpılmış olarak, perspektifte de hesaplanır — blendMode ile, boya kaynak olarak; boyanın alfasıyla solar; konumlarla eşleşmeyen doku koordinatları ya da renkler ve aralık dışı indisli bir üçgen, Compose'un hata fırlattığı yerde, atlanır; Android'de Compose blendMode'u kullanmaz ve çarpar, çünkü Android'in Canvas'ı karışım modu almaz; öbür platformları kullanır, burada olduğu gibi); enableZ/disableZ bir şey yapmaz (Kompoz katmanları sırayla çizer; z sırası yerleşimin zIndex'idir). Paint (Compose'unki, struct olarak): color (alfası alpha()/setAlpha), shader (canvas'ın koordinatlarında, alfayla solar), style (Fill/Stroke), strokeWidth (0: kıl kalınlığı), strokeCap, strokeJoin, strokeMiterLimit, pathEffect (dolgularda da, kesikler hariç: Skia yalnızca çizgileri keser), colorFilter, blendMode, filterQuality, isAntiAlias (false: her piksel Skia'nın karar verdiği gibi ya tümüyle içeride ya dışarıda — ortası şeklin içindeyse: piksellere dik bir dikdörtgenin sol ve üst kenarı dışarıda, sağ ve alt kenarı içeride; bir yol ortadaki sarım sayısıyla, Skia'nın tarama dönüştürücüsünün bir kenarın uçlarını yuvarladığı gibi; kıl çizgi uzun ekseni boyunca her adımda bir piksel; GraphicsContext::pushAntiAlias; SDL_Renderer'da kenarlar soldurulmadan ve yollar FreeType'ın tek bitlik rasterleştiricisiyle). Bir DrawScope'un canvas()/drawIntoCanvas'ının orijini kapsamın sol üstündedir; kaydedip dönüştürüp kırptığı, içinde bulunduğu blok (translate, clipRect, withTransform…) ya da kapsam bitene dek kapsamın sonraki çizimleri için geçerlidir, Compose'un geri yüklediği gibi. graphics::Canvas(context, origin) herhangi bir GraphicsContext'e çizer; DrawScope(canvas, size) bir kapsamı canvas'a çizer (Compose'un CanvasDrawScope.draw'ı). Bir düğüm üzerindeki her kapsam (drawBehind, drawWithContent, Canvas, boyut, yoğunluk ya da yerleşim yönü değişince yeniden kurulan drawWithCache'in CacheDrawScope'u, bir kayıt, özel bir Painter) ekranın yoğunluğunu ve düğümün yerleşim yönünü bilir. Bir DrawScope'un negatif boyutlu dikdörtgenleri, yuvarlak dikdörtgenleri, ovalleri ve yayları Skia'daki gibi sıralanır. | |
rememberGraphicsLayer, GraphicsLayer (record, drawLayer, toImageBitmap) | ✅ Compose 1.7'deki gibi: d.record(layer, [&](DrawScope&) { d.drawContent(); }) içeriği (ya da çizilen her şeyi) burada çizmek yerine katmana kaydeder (kapsamın sol üstünden, kendi ya da kapsamın boyunda); d.drawLayer(layer) kaydı properties()'teki yerinde bir graphicsLayer gibi çizer: pivotOffset (boşsa ortası) etrafında ölçek, kaydırma, 2B ya da 3B dönme ve cameraDistance, alfa, dış hattına clip (setRectOutline, setRoundRectOutline, setPathOutline), blendMode, colorFilter, compositingStrategy istendiği kadar çizer — yansıma, gölgeli kopya; toImageBitmap() kaydı ekranın yoğunluğunda piksele çevirir (platform ekran dışı çizer: SDL'de hedef doku + okuma; önceden çarpılmış renkler düzeltilir), Compose'da askıya alan bu işlev burada hemen döner; görüntü pikseli dp sayan Image'a boyut verin | |
drawWithCache (5), Path (5), arcTo/addArc, PathIterator, PathHitTester, DrawScope.drawOval/clipPath/withTransform | ✅ Compose'unki, yani Android'inki (Skia'nın SkPath'i) gibi Path: çizgiler, quadratic'ler, conic'ler (conicTo: kontrol noktası ağırlıklı bir quadratic; oval, yuvarlak dikdörtgen ve yaylar bunlardan oluşur, çeyrek çemberler birebir) ve kübikler; addRect, addOval, addRoundRect(RoundRect, Direction) Path::Direction'ın dediği yönde döner (Compose'daki gibi varsayılan saat yönünün tersi), Skia'nın başlangıç noktalarından (dikdörtgenin sol üstü, ovalin sağı, yuvarlak dikdörtgenin sol kenarı; bir yarıçapı 0 olan köşe kare); arcTo/arcToRad(oval, başlangıç, tarama, forceMoveTo) (0 sağda, saat yönünde; conic'ler; en çok bir tur; 0'dan taramasızsa tek nokta; kalem orada değilse ona çizgiyle bağlanır), addArc/addArcRad (kendi konturu; çeyrek açısından bir tur ya da fazlası oradan tüm oval); bir move'un hemen ardından gelen move onun yerini alır, close()'tan sonra çizmek konturun başından başlar; transform(Matrix) (perspektifte quadratic ve conic'ler birebir conic olur, kübikler bölünür, gözün arkasına geçen kesilir), isConvex(), rewind(), relativeQuadraticTo/relativeConicTo/relativeCubicTo, addPath(yol, kaydırma), translate; eğrilerde kesin contains(nokta) (Skia'nınki: dış hattın üstü içeride); iterator(ConicEvaluation::AsConic ya da AsQuadratics, tolerans) PathSegment'ler verir (noktaları her birinin başladığı yerden; conic'ler conic olarak ya da toleransta Skia'nın quadratic'leri olarak); PathHitTester(yol, tolerans) (Compose'unki: açık konturlar kapatılmaz, kenar içeride sayılmaz). SDL_Renderer'da FreeType ile dolgu (NonZero/EvenOdd) ve FT_Stroker ile çizgi (conic'ler pikselin onda biri içinde quadratic'ler olarak), maske önbelleği. DrawScope: drawOval(renk ya da fırça, solÜst, boyut, stil); clipPath(yol, blok, ClipOp::Intersect/Difference) ve clipRect(solÜst, boyut, blok, op): dolgu kuralına göre herhangi bir yol, kenarı yumuşatılmış, çizim bağlamının clip yığınından (GraphicsContext::pushClipPath, pushClipRoundRect), katmansız (SDL_Renderer böyle bir clip'in içeriğini bir katmanda çizip şekille maskeler; software renderer'da maskelemeyi CPU yapar); withTransform([](DrawTransform& t) { t.translate(…); t.rotate(…); t.scale(…); t.transform(matris); t.inset(…); t.clipRect(…); t.clipPath(…); }, blok): sırayla, her biri öncekinin içinde. Matrix (Compose'un 4x4'lüğü, işlemi işlemine) ve rotateRad; dönüşümler bir katmandan değil GraphicsContext::pushTransform'dan geçer: Compose'daki gibi hiçbir şey çizimin alanına kırpılmaz (SDL_Renderer döndürülmüş ya da ölçeklenmiş bir çizimi hâlâ görünebilecek alanı kaplayan bir katmandan çizer) | |
FocusRequester (12), onFocusChanged (3), LocalFocusManager (4) (clearFocus, moveFocus), Modifier.focusProperties, Modifier.focusGroup | ✅ Tab/Shift+Tab ve IME Next/Previous ile gezinme; focusProperties({.canFocus = false}) (Tab, dokunma ya da requestFocus ile odak almaz), {.next = r, .down = r2, .right = FocusRequester::cancel()} (o yöndeki hareket o istekçinin düğümüne — ya da içindeki ilk odaklanabilene — gider, cancel() ile yerinde kalır; hedef odak alamıyorsa her zamanki yol); Compose gibi bir odak hedefinin üstündeki düğümlerden de gelir (bir alanın modifier'ı). focusGroup(): ok tuşları önce odağın içinde olduğu en içteki grupta en yakını arar, yoksa gruptan gruba dışa doğru; dışarıdan bir grup (sınırlarıyla) tek hedeftir, seçilince içindeki o yöndeki en yakın odaklanabilene (yoksa ilkine) girilir, iç içe gruplarda dıştaki sayılır (Compose'un iki boyutlu odak araması); Tab sırası değişmez; onEnter/onExit yok. Odak alan düğüm (nasıl alırsa alsın) görünür alana getirilir, Compose'un odaklanabilirleri gibi. focusRestorer(yedek): odak dışarıdan geri girince (tuşlarla ya da gruba requestFocus) çıktığı yere döner; ilk seferde (ya da o gitmişse) yedek istekçinin düğümüne; focusTarget() (focusable()'ın alt düzey adı) onFocusEvent (her odak olayında — odak çocuklar arasında gezinirken durum aynı kalsa da — çağrılır, onFocusChanged yalnızca değişince) | |
BringIntoViewRequester, Modifier.bringIntoViewRequester | ✅ co_await requester.bringIntoView() (ya da bringIntoView(Rect{...}) ile düğümün bir parçası): çevresindeki kaydırılabilirler, içten dışa, en az kaydırmayla onu gösterir; kaydırılabilirlerin yayıyla (orta-düşük sertlik) canlandırılır; dıştakiler hedefi içtekinin götüreceği yerde görür (iç kutu yeterse sayfa kıpırdamaz) | |
BringIntoViewSpec, LocalBringIntoViewSpec | ✅ kaydırılan kabın içindekini görünür alana nasıl getireceği (Compose'unki): calculateScrollDistance(offset, size, containerSize) ne kadar kaydırılacağını verir (odaktaki öğe, klavyenin üstündeki alan, BringIntoViewRequester); CompositionLocalProvider({LocalBringIntoViewSpec.provides(...)}, …) içinde yapılan verticalScroll/horizontalScroll, scrollable, tembel liste ve ızgaralar onu yakalar (ör. TV satırı gibi odaktaki kartı üçte birde tutmak). Sağdan solada uzaklık sağdan ölçülür. Varsayılan: görünecek kadar, görünür alandan büyükse başı | |
Özel gösterge (IndicationNodeFactory, IndicationNode) | ✅ Compose'unki gibi kendi göstergen: fabrika bileşen başına bir düğüm yapar; düğüm onInteraction ile basma (yeriyle), bırakma, iptal, üzerine gelme ve odak etkileşimlerini duyar, draw(ContentDrawScope&) ile içeriğin çevresine çizer, coroutineScope() içinde anime eder (bileşen gidince işleri de gider). Indication(fabrika): clickable(…, {.indication = …}), LocalIndication (Material düğmeleri de) ya da Modifier.indication(kaynak, …); kaynağı verilmemiş tıklanabilirde düğüm kendi kaynağını dinler. Aynı fabrika yeniden bileşimde aynı düğümü korur | |
TextToolbar, LocalTextToolbar | ✅ metin seçiminin araç çubuğu kendi çubuğunla değişir (Compose'unki): LocalTextToolbar verilince Kompoz kendi açılır çubuğunu çizmez, showMenu(seçimin dikdörtgeni, kopyala, yapıştır, kes, tümünü seç) çağırır (yapılamayanlar boş: salt okunur alanda yapıştır/kes yok, SelectionContainer'da yalnızca kopyala ve tümünü seç), yer ya da eylemler değişince yeniden; seçim bitince hide(). Kendi çubuğunu bir açılır pencerede göster ki ona basmak seçimi bitirmesin | |
LocalUriHandler, LocalSoftwareKeyboardController, LocalHapticFeedback, LocalClipboardManager | ✅ uriHandler().openUri(adres) (uygulamanın kendi adresleri — kompozisyondaki bir NavHost'un derin bağlantıları, ör. kompoz://item/7 — uygulamanın içinde açılır; diğerleri SDL_OpenURL ile: tarayıcı, Android'de intent, xdg-open, ShellExecute), softwareKeyboardController().hide()/show() (alan odakta kalır, dokununca klavye geri gelir; donanım klavyesinde gizlenecek bir şey yok), hapticFeedback().performHapticFeedback(HapticFeedbackType::…) (Android'de görünümün performHapticFeedback'i, eski sürümlerde en yakın sabit; web'de navigator.vibrate; masaüstünde yok), clipboardManager() (setText/getText/hasText); uzun tıklama ve metin seçen uzun basış LongPress, tutamaç her karakterde TextHandleMove titreşir; Compose 1.8'in LocalClipboard'ı: Clipboard clip = clipboard(); — co_await clip.getClipEntry() (std::optional<ClipEntry>, boşsa yok), co_await clip.setClipEntry(ClipEntry::withPlainText(metin)) (std::nullopt boşaltır); eşyordamda beklenir, burada hemen tamamlanır; yalnız düz metin | |
focusable (10) (metin dışı odak) | ✅ tıklanabilirler de klavyeyle odaklanır; Tab/Shift+Tab, oklarla yönlü odak, Enter/Space ile tıklama, odak halkası, odaklananı görünür alana kaydırma | |
Ripple: ripple(), Indication, LocalIndication, clickable(indication = …) | ✅ her tıklanabilirde Material dalgası: basılan yerden büyük kenarın 0,3'ünden en uzak köşeye, merkezi ortaya kayarak 225 ms'de yayılır (FastOutSlowIn), 75 ms'de belirir, bırakılınca (yayılmayı bitirince) 150 ms'de söner; şekle kırpılır; basılı tutulurken kare istemez. ripple(bounded, radius, color): sınırsız olan ortadan, verilen yarıçapta, kırpılmadan (üzerine gelme/odak katmanı ve odak halkası da o yarıçapta bir daire); Indication::Kind::StateLayer düz katman, false hiçbiri (indication = null); LocalIndication alt ağacınkini belirler. Klavyeyle tıklamada dalga ortadan. Hover/odak katmanları (0,08/0,1) yalnızca fareyle/klavyeyle. Modifier.indication(source, ripple()): bir kaynağın basışlarını (dalga) ve hover/odağını başka bir düğümde gösterir — clickable(…, {.interactionSource = s, .indication = false}) bir satırı, dalgası yalnızca içindeki simgede. Notlar: dalga alfası 0,12; indication() dalgası basışı ilk çizdiği karede başlar | |
MutableInteractionSource, Interaction (PressInteraction, HoverInteraction, FocusInteraction, DragInteraction), collectIsPressedAsState/collectIsHoveredAsState/collectIsFocusedAsState/collectIsDraggedAsState, Modifier.hoverable, clickable(interactionSource, indication = null) | ✅ clickable(onClick, {.interactionSource, .indication = false, .onLongClick, .onDoubleClick}); Button/IconButton ailesinin stili ve TextFieldOptions interactionSource alır; focusable(enabled, source), hoverable(source), draggable(…, source), scrollable(…, source); ScrollState/LazyListState/PagerState::interactionSource() kullanıcının sürüklemelerini duyar. Basma: bırakılınca Release (tıklamadan önce), parmak kayıp gidince ya da kaydırma başlayınca Cancel; klavyeyle tıklama Press+Release; hover yalnızca fareyle (dokunma fareninkini bitirir), iç içe hoverable'ların hepsi; düğüm basılıyken/odaktayken giderse uç olay gelir. interactions() bir SharedFlow (salt okunur alan + Release ile seçici açma); collectIs…AsState() gözlenebilir, kaynağın o anki durumunu verir; kendi olaylarınız: Interaction::press(konum), press.release(), tryEmit. Slider/RangeSlider: SliderOptions::interactionSource (dokunuştan bırakmaya Press, yana kayınca DragStart, fareyle üstündeyken hover; giderse ikisi de iptal), RangeSlider'da başlangıç başparmağı bu kaynağa, bitiş başparmağı endInteractionSource'a; iki başparmak üst üsteyken basma, sürüklemenin yönü bir başparmağı seçince bildirilir. Parmağın kaydırabildiği bir şeyin içindeki basma (etkileşimi, dalgası) Compose'daki gibi dokunma zaman aşımından (100 ms) sonra gösterilir: önce kaydırma başlarsa hiç gösterilmez, önce bırakılırsa basılıp hemen bırakılır; fareyle ve kaydırılabilir dışında hemen | |
pointerInput (10), detectTapGestures/detectDragGestures (4/4), combinedClickable (3), PointerEventPass, detectDragGesturesAfterLongPress | ✅ coroutine tabanlı awaitPointerEvent, tüketme (consume) kuralları, yatay/dikey sürükleme. Her olay üç geçişte dolaşır (Compose'daki gibi): Initial dıştakinden içe (ebeveyn içindekilerden önce görür ya da tüketir), Main içtekinden dışa (varsayılan), Final yine dıştan içe (herkesten sonra: başkası tüketti mi); awaitPointerEvent(PointerEventPass::Initial) o geçişi bekler, aynı olay bir işleyiciye geçiş geçiş birden çok kez gelebilir; Initial'da tüketilen basışı tıklanabilirler de almaz. Not: tıklanabilir ve kaydırılabilirlerin kendi işleyişi Main sırasında; detectDragGesturesAfterLongPress(scope, {onDragStart, onDrag, onDragEnd, onDragCancel}): parmak uzun basma süresi (400 ms) kımıldamadan durunca sürükleme başlar (onDragStart parmağın yerinde), sonra yolun tamamını izler (dokunma eşiği düşülmez) ve olayları tüketir; daha önce eşiği aşan hareket hareketi bırakır (çevredeki kaydırma alır); Compose'un yapı taşları (TaskOf ile): co_await awaitFirstDown(scope, requireUnconsumed = true) (sonraki basış; tüketilmişse istenmedikçe sayılmaz), co_await waitForUpOrCancellation(scope) (son parmak kalkınca onun değişikliği; tüketilen ya da öğeden çıkan hareket, tüketilmiş bırakış ya da iptal: hiçbir şey), awaitEachGesture(scope, [](PointerInputScope& s) -> Task {…}) (hareket bitince bütün parmaklar kalkmadan yenisi başlamaz); scope.anyPointerDown() | |
Çoklu dokunma: detectTransformGestures (2), Modifier.transformable, calculateZoom/Rotation/Pan/Centroid | ✅ parmak başına kimlik, PointerEvent::changes; tek parmakla kaydırma canPan ile sayfaya bırakılabilir; sayfa ilk parmakla kaymaya yeni başlamışken (250 ms / 48 dp) ikinci parmak inerse hareket yakınlaştırmaya geçer; transformable fareyle Ctrl+tekerlek, touchpad sıkıştırmasıyla (Wayland/macOS'ta SDL pinch, Windows ve web'de Ctrl+tekerlek olarak gelir) da yakınlaşır (ComposeHost::zoom); masaüstünde dokunmatik ekran | |
horizontalScroll (2), LazyVerticalGrid (5) (GridCells.Fixed/Adaptive, tam satır span), HorizontalPager (3) / VerticalPager (PagerState, fling ile sayfa çevirme, animateScrollToPage), PageSize, PagerSnapDistance, PagerDefaults.flingBehavior | ✅ Pager: pageSize (PageSize::Fill — dolgusuz alanın tamamı, PageSize::Fixed(dp), ya da PageSize{[](float alan, float aralık) {…}}), snapPosition (SnapPosition::Start/Center/End: geçerli sayfanın durduğu yer; sayfalar uçlarından öteye kaymaz — ilk sayfanın başı baş dolgusunda, sonuncunun sonu son dolgusunda; ilk ve son sayfaları ortaya getirmek için contentPadding), görünen bütün sayfalar (bir fazlası ve beyondViewportPageCount kadarı) beste içinde; sayfalar istedikleri kadar yer alır (pager boyunca sayfa boyuna kadar, yuvasının başında), çapraz eksende verticalAlignment (HorizontalPager, varsayılan ortada) / horizontalAlignment (VerticalPager) ile hizalanır; flingBehavior = PagerDefaults::flingBehavior(state, PagerSnapDistance::atMost(n), eşik): fling hızının götürdüğü kadar sayfa çevirir (o yöndeki en az bir, bıraktığı sayfadan en çok n), yavaş sürükleme sayfanın snapPositionalThreshold kadarını geçince çevirir (iki yönde de), snapAnimationSpec ile oturur. PagerState: settledPage() (en son durduğu sayfa, kayarken değişmez), targetPage() (fling'in ya da animateScrollToPage'in götürdüğü sayfa; parmak araya girince yine currentPage), getOffsetDistanceInPages(sayfa) (o sayfanın oturma yerinden kaç sayfa uzakta olduğu — graphicsLayer bloğunda okuyarak uzaklaştıkça küçülen sayfalar), canScrollForward/Backward(), scrollToPage(sayfa, kesir), animateScrollToPage(sayfa, kesir, spec). reverseLayout: sayfalar sondan dizilir (ilk sayfa sağda — dikeyde altta —, sonrakiler solunda; dolgular yerinde kalır), parmak ters yönde (sürükleme, fırlatma, sayfa içindeki kaydırılabilirle iş birliği; sağdan sola düzende ikisi birbirini götürür). key = [](int sayfa) { return anahtar; }: sayfa durumunu anahtarıyla tutar; geçerli sayfanın önüne sayfa eklenince ya da önünden sayfa çıkınca geçerli sayfa aynı sayfa kalır (indeksi kayar). Yok: layoutInfo | |
LazyGridState (rememberLazyGridState, firstVisibleItemIndex, scrollToItem/animateScrollToItem, layoutInfo) | ✅ LazyGridOptions::state artık LazyGridState: konum öğeyle (görünen ilk satırın ilk öğesi), bir öğeye kaydırma onun satırına gider (ızgara henüz yerleşmediyse yerleşince), layoutInfo().visibleItemsInfo her öğenin satır/sütununu, konumunu ve kendi boyutunu verir (yatay ızgarada satırlar sütundur), maxSpan; kaydedilir. Altındaki satır listesi lines() | |
LazyStaggeredGridState (rememberLazyStaggeredGridState, firstVisibleItemIndex, scrollToItem/animateScrollToItem, layoutInfo) | ✅ LazyStaggeredGridOptions::state artık LazyStaggeredGridState: ilk görünen öğe görünenlerin en küçük dizini (gözlenebilir), scrollToItem öğenin üstünü içeriğin başına koyar ve yanındakilerin yükseklikleri ölçülene dek orada tutar (ölçülmemişlerin yeri ortalamayla tahmin edilir; başka bir kaydırma bırakır), layoutInfo().visibleItemsInfo şerit (lane, tam satırsa fullLine), kaydırılmış konum ve boyut, lanes; dp kaydırma scrollState() | |
HorizontalMultiBrowseCarousel, HorizontalUncontainedCarousel, rememberCarouselState (M3 Carousel) | ✅ çoklu göz atma: pencereye sığan büyük öğeler (tercih edilen genişliğe yakın), bir orta, bir küçük; öğeler kaydıkça anahtar çizgiler arasında büyüyüp küçülür (her an pencereyi doldurur), içerik büyük boyutta kalıp ortadan maskelenir (itemShape, varsayılan 28 dp köşe), bırakınca bir öğeye oturur, listenin sonunda düzen döner (son öğe de büyük görünür); sınırsız: sabit genişlik, serbest kaydırma; itemSpacing, contentPadding, currentItem, scrollToItem/animateScrollToItem, kaydedilebilir. HorizontalCenteredHeroCarousel(state, maxItemWidth, …): ortada büyük bir öğe, iki yanında küçükler (56 dp); listenin başında ilk öğe başta, sonunda son öğe sonda büyük (aradaki geçişler yumuşak), bırakınca bir öğe büyük olarak oturur; maxItemWidth büyüğü sınırlar, kalan yeri küçükler alır. İçerik CarouselItemScope da alabilir: index ve carouselItemInfo (size() maskenin şimdiki genişliği, minSize()/maxSize() en küçük ve en büyük hâli); her kaydırma adımında yeniden kompoze etmeden değişir, çizerken okunur (örn. etiket öğe büyüdükçe belirir). CarouselItemScope::maskClip(shape) / maskBorder(border, shape): içerik öğenin o an gösterdiği parçaya (ortadaki, öğe genişliğinde maske) kırpılır ya da onun çevresine çerçeve çizilir (öğenin kendi maskesi itemShape; RectangleShape ile yalnızca sınırları) | |
nestedScroll (4) (NestedScrollConnection, NestedScrollDispatcher, NestedScrollSource) | ✅ pre/post scroll ve fling zinciri; iç içe listeler, pager içinde satır (ucundan öteye fırlatılan satırın kalan hızı sayfayı çevirir, pager'ın ebeveynlerine gitmez; Compose 1.11'in kaynağında sayfa bağlantısı bu hızı pager'dan önce yutar), alt sayfada liste; kaydırılabilir öğe dıştaki sürükleme işleyicilerinden önce davranır | |
Modifier.anchoredDraggable, AnchoredDraggableState, DraggableAnchors | ✅ değerler (herhangi bir == türü, çoğunlukla enum) ve dp konumları: DraggableAnchors<T>{{Start, 0}, {End, 300}} / .at(v, p), positionOf, closestAnchor(p[, yukarı]), min/maxPosition; durum: currentValue/targetValue/settledValue (gözlenebilir; hedef yalnızca değişince yeniden kompoze ettirir), offset() (çapalar gelene dek NaN; requireOffset() o zaman 0), progress(from, to), isAnimationRunning, lastVelocity, updateAnchors(çapalar[, hedef]) (onSizeChanged'den; dururken değerinde kalır ve onun yeni yerine geçer, animasyon yeni yere yönelir, sürükleme sınırlar içinde sürer), snapTo, animateTo, settle(hız), dispatchRawDelta. Bırakınca Compose'un kuralı: velocityThreshold'dan (125 dp/s) hızlı fırlatma o yöndeki çapaya, değilse positionalThreshold (varsayılan yarı yol) geçildiyse sonrakine, yoksa geri; confirmValueChange reddederse geri döner (koddan animateTo/snapTo sormaz). Sürükleme kullanıcının: animasyonu durdurur, dokunma eşiğini ve hızı host'tan alır, etrafındaki kaydırılabilirlere taşmaz, fare tekerleğiyle oynamaz; reverseDirection, interactionSource. rememberAnchoredDraggableState (T kaydedilebilirse değeri kaydedilir). SwipeToDismissBox ve BottomSheetScaffold'un sayfası kendi çapa mantıklarını kullanıyor, ikisi de bırakış hızını taşıyan yayla oturur (uçları aşmadan); SwipeToDismissBox Compose'daki gibi 125 dp/s'lik bir fırlatmayla da kapanır (hızla geri fırlatılırsa yerine döner), yavaş bırakılınca genişliğin %40'ını geçmişse | |
animateItem (5), SwipeToDismissBox (4), draggable (1), draggable2D, scrollable2D | ✅ Modifier.scrollable2D(rememberScrollable2DState([](Offset d) { ...; return kullanılan; })) (Compose 1.9): dokunma eşiğinden sonra her yöne kaydırma, bırakınca iki eksende ayrı ayrı (kaydırıcıların yavaşlamasıyla) fling — bir eksen ucuna varınca o eksen durur —, basış fling'i durdurur, fare tekerleği (yan tekerlek de; uçtayken çevredeki sayfaya bırakır); isScrollInProgress, dispatchRawDelta, stopScroll; overscroll yok. Modifier.draggable2D(rememberDraggable2DState([](Offset d) {...}), {.interactionSource, .startDragImmediately, .onDragStarted, .onDragStopped, .reverseDirection}) (Compose 1.7): her yöne sürükleme dokunma eşiğinden sonra (ya da basar basmaz) duruma gider, sürükleme tüketilir (çevredeki kaydırma almaz), bırakınca hız (dp/s, iki eksen) söylenir; dispatchRawDelta koddan sürükler; geri çağrılar her kompozede yenilenir, hareket yeniden başlamaz. animateItem: yer değiştirme (yay), eklenince belirme, çıkarılınca son haliyle (yeniden kompoze edilmeden; verisi gitmiş olabilir) eski yerinde solma, solarken dokunma almaz; animateItem(fadeInSpec, placementSpec, fadeOutSpec) | |
PullToRefreshBox (PullToRefreshState, PullToRefreshDefaults.Indicator) | ✅ Modifier.pullToRefresh'li bir Box; eşiği geçip bırakınca onRefresh, yenilenirken dönen gösterge. Seçenekler: state, threshold, enabled, contentAlignment, indicator. Kutu artık içeriği kırpmıyor (gösterge kendi kırpıyor, Compose'daki gibi) | |
Modifier.pullToRefresh, PullToRefreshDefaults.IndicatorBox | ✅ Compose 1.4.0'daki gibi: pullToRefresh(isRefreshing, state, onRefresh, enabled, threshold) herhangi bir kutuya; parmağın yarısı kadar iner, eşikten sonra gittikçe yavaşlar (en çok eşiğin iki katı), durum (distanceFraction: 0 gizli, 1 eşikte) animasyondayken çekmeler sayılmaz, yenilenirken kaydırmalar listeye geçer; ilk çizimde isRefreshing neyse durum oraya konur (animasyonsuz). PullToRefreshState.snapTo. IndicatorBox(state, isRefreshing, modifier, content, maxDistance, shape, containerColor, elevation): üst kenarın altından çıkan daire (o kenarın üstünde hiçbir şeyi görünmez), çıkınca gölge; kendi göstergenizi koymak için. Indicator(state, isRefreshing, modifier, containerColor, color, maxDistance): Compose'un oklu yayı (ilk %40'ta boş, eşiğe dek soluk, eşikte tam renk, aşınca döner) ile 16 dp dönen gösterge arasında geçiş; renkler indicatorContainerColor (surfaceContainerHigh) ve indicatorColor (onSurfaceVariant). Not: eski Indicator(state, isRefreshing, threshold, modifier) imzası değişti | |
stickyHeader (LazyColumn/LazyRow) | ✅ bölüm başlığı üstte kalır, sonraki başlık iter; uzaktaki başlık da kompoze edilir | |
LazyHorizontalGrid | ✅ satırlar yüksekliği böler, sütunlar LazyRow gibi tembel; FullLine tüm sütun | |
LazyVerticalStaggeredGrid, LazyHorizontalStaggeredGrid, StaggeredGridCells | ✅ öğeler kendi yüksekliğinde en kısa sütuna (yatayda kendi genişliğinde en kısa satırın ardına; horizontalItemSpacing, verticalSpacing; durumun yerleri, kaydırması ve layoutInfo'su x boyunca); görünen alan ve yarım ekran payı kompoze edilir; FullLine başlık; durum LazyStaggeredGridState (kaydırması scrollState() ile, dp) | |
scrollable (3), rememberScrollableState, scrollableArea | ✅ sürükleme/fling parmak yönünde delta; kullanılmayan kısım dıştaki kaydırılabilire; reverseDirection. scrollableArea(state, orientation[, overscrollEffect], enabled, reverseScrolling) (Compose 1.9'unki): içeriğini durumdan kendisi yerleştiren düzenler için scrollable + eksen boyunca kırpma (kaydırma kapları gibi, enine 30 dp pay) + aşırı kaydırmanın üstüne çizilmesi (esneme ya da verilen efekt; nullptr: yok); enabled false: yalnızca kodla kaydırılır, kırpma sürer | |
KeyboardOptions/KeyboardActions (3/1) | ✅ Android'de klavye türü (e-posta, sayı, şifre...) ve eylem tuşu; showKeyboardOnFocus = false: koddan odaklanınca (FocusRequester, Tab) yazılanlar alana gider ama yazılım klavyesi açılmaz, dokununca (ya da uzun basınca) açılır | |
rememberTextFieldState (5) (TextFieldState), çok satırlı alan (singleLine, minLines, maxLines, TextFieldLineLimits) | ✅ Compose gibi varsayılan çok satırlı; kelime sınırından kaydırma, Enter ile yeni satır, satırlar arası oklar/Home/End, dokunarak satıra imleç, maxLines sonrası iç kaydırma; Android'de çok satırlı klavye. TextFieldState seçimi de tutar (selection(), gözlenebilir; UTF-8 bayt ofsetleri), edit([](TextFieldBuffer& b) { b.append(…); b.placeCursorAtEnd(); }) (replace/insert/remove/selectAll/setSelection; değiştirme seçimi arkasındaki metinle kaydırır), setTextAndSelectAll; odaktayken koddan yapılan değişikliği klavye metin ve seçimiyle alır, odaklanınca o seçimden başlar. TextFieldOptions::inputTransformation: InputTransformation::maxLength(n) (kod noktası; aşan düzenleme reddedilir), allCaps("tr") (yalnızca yazılanı büyütür; Türkçede i → İ, ı → I), byValue([](const std::string& şimdiki, const std::string& önerilen) { … }), a.then(b); değiştirilen ya da reddedilen düzenleme klavyeye bildirilir, koddan yapılan değişiklikler dönüştürülmez. TextFieldOptions::outputTransformation: OutputTransformation{[](TextFieldBuffer& b) { b.insert(3, " "); }} yalnızca gösterimi değiştirir (telefon/kart gruplama, ön/son ek); değer, klavye, kopyalama ve erişilebilirlik metnin kendisini alır; imleç ve dokunmalar eklenenlerin üstünden geçer (bir konuma eklenenin önünde durur, en baştakinin arkasında: "$ | 250 USD"). state.undoState(): canUndo()/canRedo() (gözlenebilir), undo(), redo(), clearHistory(); alanda Ctrl+Z, Ctrl+Shift+Z / Ctrl+Y. Yazılanlar kelime kelime geri gelir (kelimeden sonraki boşluk yeni adım başlatır, satır sonu ayrı adım), art arda silmeler tek adım; koddan yapılan düzenleme kendi başına adımdır; yeni düzenleme yinelenebilecekleri siler; en çok 100 adım lineLimits = TextFieldLineLimits::SingleLine / MultiLine(en az, en çok) (Compose'un durum tabanlı alanlarındaki gibi) singleLine/minLines/maxLines yerine geçer |
BasicTextField (1) | ✅ dekorasyonsuz düzenlenebilir metin (yer tutucu, tek/çok satır) | |
| Dokunmatik seçim tutamaçları | ✅ metin alanında uzun basınca kelime seçilir; sürüklenebilir damla tutamaçlar, Kes/Kopyala/Yapıştır/Tümünü seç araç çubuğu; yazınca, odak değişince ya da başka yere dokununca biter Tutamaç ya da imleç parmakla sürüklenirken Android'deki metin büyüteci (Compose'daki gibi): parmağın 42 dp üstünde 100×48 dp'lik yuvarlak köşeli bir mercek, içinde satırın o kısmı 1,25 kat büyük (parmağı yatayda izler, satırın ortasında durur), gölgeli; bırakınca kaybolur (salt metin seçiminde de) | |
Modifier.magnifier | ✅ magnifier([] { return kaynak; }, {.magnifierCenter, .zoom = 1.25f, .size = {100, 48}, .cornerRadius = 24, .elevation = 4}) (Compose'daki gibi): her şeyin üstünde, modifier'ın yerine göre kaynak noktanın çevresi büyütülmüş (sahne o katmanda yeniden çizilir), varsayılanı kaynağın 42 dp üstü; kaynak çizilirken okunur, NaN gizler. Not: açılır pencereler büyüteçte görünmez | |
| İmleç tutamacı (parmakla dokununca), fareyle çift tıklayınca kelime seçimi | ✅ tutamaç sürüklenince imleç kayar, dokununca Yapıştır/Tümünü seç; host parmak ile fareyi ayırır (fareyle uzun basma seçmez) | |
Salt metinde seçim (SelectionContainer, DisableSelection) | ✅ tek seçim içindeki bütün Text'lere yayılır (okuma sırasıyla): parmakla uzun basınca kelime, tutamaçlar metinden metne sürüklenir, Kopyala/Tümünü seç; fareyle sürükleyerek seçim, çift tıklayınca kelime, Ctrl+C / Ctrl+A / Escape; DisableSelection içindekiler seçilmez. Renkleri LocalTextSelectionColors'tan (TextSelectionColors{tutamaç, vurgu}; MaterialTheme şemanın primary'si ve %40'ını verir), alanlarda da |
Material 3
| API | Durum |
|---|---|
Text (160), MaterialTheme (75), Button (59), Surface (18), Card (17), TextButton (12) | ✅ |
MotionScheme, MaterialExpressiveTheme, MaterialTheme.motionScheme | ✅ MotionScheme: hareket edenler (spatial: yer, boyut, şekil) ve görünüşü değişenler (effects: renk, saydamlık) için default/fast/slow yaylar; MotionScheme::standard() (spatial 0,9 sönüm — 700/1400/300 sertlik; effects 1,0 — 1600/3800/800) ve MotionScheme::expressive() (spatial 0,8/380, 0,6/800, 0,8/200 — zıplar; effects aynı); motionScheme() çevredekini verir (LocalMotionScheme, en üstte standard). MaterialTheme(renkler, hareket, içerik); iki parametreli MaterialTheme çevredeki hareketi korur; MaterialExpressiveTheme(renkler ya da std::nullopt, [hareket = expressive()], içerik). Bileşenler hareketi şemadan alır: şekli değişen düğmeler ve liste öğeleri, ButtonGroup'ta basılan düğmenin büyümesi, SplitButton okunun dönüşü, ToggleFloatingActionButton (fastSpatial), Snackbar'ın girişi (fastSpatial + fastEffects), ShortNavigationBar göstergesi (defaultSpatial) |
BasicText, BasicSecureTextField, BasicTextField decorationBox / decorator | ✅ BasicText(metin, modifier, stil): çevresinden bir şey almaz (Compose'un TextStyle.Default'u: 14 sp, siyah; LocalTextStyle ve LocalContentColor değil), metin ve AnnotatedString ile; BasicSecureTextField(durum, modifier, seçenekler): süslemesiz parola alanı — yalnızca noktalar (kapsayıcı, çizgi, etiket yok), kopyalanmaz; BasicTextField ve BasicSecureTextField decorator alır (Compose'un decorationBox/decorator'ı): [&](const Content& innerTextField) {…} metnin çevresini kendisi çizer, metni innerTextField() ile yerleştirir (Row içinde kalan yeri alır); süslemeye — içindeki tıklanabilirlerin almadığı — dokunuş alana gider (odak, imleç metnin en yakın ucunda) |
lightColorScheme/darkColorScheme (11/10), HorizontalDivider (8), Checkbox (4), TriStateCheckbox (ToggleableState On/Off/Indeterminate), Switch (3) | ✅ Compose 1.4'teki gibi: 20 dp kutu, 2 dp çerçeve içinde; tik yol boyunca çizilir (varsayılan uzamsal yay), belirsizde ortada çizgiye bükülür, kaldırılınca 100 ms sonra birden gider; renkler efekt yaylarıyla, devre dışı onSurface %38 (anında). Boyutlar Compose'daki gibi (bkz. minimumInteractiveComponentSize) |
Switch(checked, onCheckedChange, modifier, SwitchOptions{enabled, interactionSource, thumbContent}) | ✅ Compose 1.4'ün renkleri: açıkken primary iz ve onPrimary başparmak, kapalıyken surfaceContainerHighest iz, outline başparmak ve çerçeve; devre dışıyken yüzeyin üstüne soluk (onSurface %12 iz, surface başparmak; kapalıda %38). Başparmak hızlı uzamsal yayla (0,9 / 1400) kayar, basınca anında 28 dp olur. thumbContent: başparmakta 16 dp'lik bir simge (açıkken onPrimaryContainer, kapalıyken surfaceContainerHighest), başparmağı büyük boyunda tutar ve onunla kayar (RTL'de aynalı); başparmak 16 dp kapalı, 24 dp açık, basılıyken 28 dp (geçişler canlı) |
TextField (8), OutlinedTextField (6) | ✅ yüzen etiket, ikonlar, destek metni, hata, şifre; dokunarak imleç; masaüstünde oklar/seçim/pano; textStyle (yazı tipi, renk, hizalama); readOnly; prefix/suffix ({.label = "Tutar", .prefix = "₺", .suffix = ",00"}: etiket yukarı çıkınca — etiket yoksa hep — metnin iki yanında, sakin renkte; metin onlara yer açar, dokunma ve imleç buna göre); colors (TextFieldColors, Compose'un TextFieldDefaults.colors()'u): metin, kapsayıcı, imleç, seçim, gösterge çizgisi, ikonlar, etiket, yer tutucu, destek metni, ön/son ek için odaklı/odaksız/hatalı renkler (hata odağa üstün gelir); verilmeyenler M3'ünkiler, textStyle rengi metin rengine üstün gelir; SecureTextField da alır; enabled = false (odaklanmaz, düzenlenmez, seçilmez; devre dışı renkler: onSurface %38, outlined kenarlık %12; odaktayken kapatılırsa odağı bırakır); shape (kapsayıcının ve kenarlığın köşeleri; varsayılan dolgulu alanda yalnızca üstte 4 dp — Compose'un TextFieldDefaults.shape'i —, outlined'da dört köşede 4 dp; kenarlık şeklin köşelerini izler, etiket boşluğu korunur); etiketli OutlinedTextField üstte 8 dp yer ayırır (64 dp; yukarı çıkan etiket alanın içinde kalır, Compose gibi); labelPosition: TextFieldLabelPosition::Attached(true) etiketi hep yukarıda tutar (boşken yer tutucu ve ön/son ek de görünür), Above(hizalama) etiketi alanın üstüne, dışına koyar (bodySmall, 4 dp kenar ve alt boşluk) |
SecureTextField, OutlinedSecureTextField, TextObfuscationMode | ✅ tek satır, şifre klavyesi (öneri yok), kopyalanmaz/kesilmez; RevealLastTyped (varsayılan: tek yazılan karakter — ortaya da — 1,5 sn görünür; silme, yapıştırma ya da odak kaybı onu hemen gizler), Hidden, Visible (göz düğmesi için); textObfuscationCharacter |
Icon (43) + material ikonları (icons.filled 92) | ✅ Compose'un materialIcon'unun yaptığı gibi yapılmış 35 Filled ikon (Filled.Add… adlı, 24 × 24, siyah dolu tek yol); Icons::AutoMirrored::Filled (ArrowBack, ArrowForward, KeyboardArrowLeft/Right, List, Send) sağdan solda aynalanan ayrı vektörler. Icon(imageVector), Compose'daki gibi Icon(rememberVectorPainter(imageVector))'dır: varsayılan boyutunda (Material ikonunda 24 dp), LocalContentColor ile SrcIn renk süzgeciyle boyanır (tek renkli ikon renkte bir Alpha8 maske) |
ImageVector, ImageVector.Builder, VectorPath, VectorGroup, PathNode, PathParser, PathBuilder, addPathNodes | ✅ Compose'unki gibi: bir ImageVector name'i, varsayılan boyutu (dp), viewport'u, bir ağaç (root(): VectorNode'lardan, her biri bir VectorPath ya da VectorGroup, VectorGroup'lar), tintColor/tintBlendMode'u (SrcIn) ve autoMirror'ıdır; bunların hepsiyle eşittir (kimliğiyle değil). ImageVector::Builder(ad, varsayılanGenişlik, yükseklik, viewportGenişlik, yükseklik, tintColor, tintBlendMode, autoMirror) (ad verilmeyebilir) .addPath({.pathData = addPathNodes("M…"), .fill = …}), .path({.stroke = …, .strokeLineWidth = 2}, [](PathBuilder& p) { p.moveTo(…).lineTo(…); }), .addGroup({.name, .rotation, .pivotX, .pivotY, .scaleX, .scaleY, .translationX, .translationY, .clipPathData}) … .clearGroup() ya da .group({…}, [](ImageVector::Builder& b) { … }), .build() (açık gruplar kapanır). VectorPath: name, pathData, pathFillType, fill/stroke Brush'ı (verilmezse yok; degradeler yolun birimlerinde, uzak kenar çizilen boyut), alfaları, strokeLineWidth (0: kıl çizgi), uç/birleşim/miter, trimPathStart/End/Offset (Android'in ölçtüğü gibi ilk konturunun uzunluğunun kesirleri; ucundan başa sarar). Grup içindekileri Compose'un matrisiyle (çevirisi ve pivotu kadar taşınır, döner, ölçeklenir, pivotu kadar geri taşınır) çizer ve kırpma yoluna kırpar. Yol verisi Compose'un PathParser'ının okuduğu gibi okunur (PathNode'lar: 19 komut, mutlak ve göreli; bitişik sayılar, üsler, +; yayın bayrakları her kümede birer karakter) ve toPath öyle çizer (yansıyan eğriler kendi türlerinden sonra; yaylar en çok sekizde bir turluk kübikler, yetmeyen yarıçaplar büyütülür; sıfır yarıçap SVG'deki gibi doğru); PathParser düğümleri tutar, PathBuilder/PathData çağrılarla yapar. ImageVector::fromSvgPath(veri): siyah dolu tek yol |
vectorResource (Android vector drawable XML) | ✅ vectorResource("vectors/pusula.xml") uygulamanın varlıklarındaki (Android'de APK'nın) <vector> dosyasını bir kez okuyup ImageVector yapar; ImageVector::fromVectorXml(xml) metinden. width/height (dp), viewportWidth/viewportHeight, autoMirrored, tint/tintMode (src_in, src_over, src_atop, multiply, screen, add), alpha (yollarının dolgu ve çizgilerini soldurur); iç içe <group> (name, rotation, pivotX/Y, scaleX/Y, translateX/Y, Android'in sırasıyla); <path> pathData, fillColor/strokeColor (#RGB, #ARGB, #RRGGBB, #AARRGGBB), fillAlpha/strokeAlpha, strokeWidth (Compose'un okuduğu gibi verilmezse 1), strokeLineCap/Join, strokeMiterLimit, fillType; <aapt:attr name="android:fillColor|strokeColor"> içindeki <gradient>: linear (startX/Y, endX/Y), radial (centerX/Y, gradientRadius), sweep (centerX/Y), <item offset color> durakları ya da startColor/centerColor/endColor, tileMode (clamp, repeat, mirror), yolunun birimlerinde (gruplarının içinden çizilir). Yolların, grupların ve <clip-path>'lerin name'leri; trimPathStart/End/Offset; <clip-path> grubunda kendinden sonrakileri kırpar. Henüz yok: @color/… başvuruları siyah |
AnimatedImageVector, animatedVectorResource, rememberAnimatedVectorPainter | ✅ Android'in tek dosyalık <animated-vector>'ı (Android Studio ve Shape Shifter'ın yazdığı gibi): çizimi <aapt:attr name="android:drawable"> içinde, her <target android:name>'in animasyonu <aapt:attr name="android:animation"> içinde: <objectAnimator> (propertyName ya da <propertyValuesHolder>'lar; valueFrom — yoksa öğenin kendi değeri — ve valueTo; valueType float/color/path; duration, startOffset, repeatCount, repeatMode; Android'in interpolator'ları), <set> birlikte ya da sırayla. Canlanır: grupların dönüşü, pivotu, ölçeği, ötelemesi; yolların pathData'sı (aynı komutlardan yollar arasında morf, değilse yarıda geçiş), dolgu/çizgi renkleri ve alfaları, strokeWidth, trimPath*; vektörün alfası. AnimatedImageVector::vectorAt(ms) o andaki vektör; rememberAnimatedVectorPainter(avd, atEnd) başında ya da sonunda çizer, atEnd değişince oraya oynatır (kapanınca geriye). Henüz yok: ayrı dosyalardaki animatörler (@animator/…), keyframe'ler, path interpolator'lar; sonsuz tekrar bir kez oynar |
Scaffold (34), TopAppBar (16), NavigationBar, BottomAppBar (5) | ✅ |
FlexibleBottomAppBar (M3 Expressive), BottomAppBarDefaults::exitAlwaysScrollBehavior | ✅ esnek alt çubuk 64 dp, içeriği yanlardan 16 dp içeride yayılmış (horizontalArrangement SpaceBetween, contentPadding, expandedHeight); BottomAppBarSlots::scrollBehavior / FlexibleBottomAppBarOptions::scrollBehavior: içerik ilerledikçe çubuk o kadar yüksekliğini yitirip aşağı kayar (Scaffold'un içeriği büyür), geri kaydıkça döner, yarıda bırakılınca hızına ya da yakın uca göre tamamlar; bağlantı nestedScrollConnection kaydırılan içeriğin bir atasına (Scaffold) |
ShortNavigationBar, ShortNavigationBarItem (M3 Expressive) | ✅ 64 dp yüksekliğinde (surfaceContainer, sistem çubuklarının yan ve alt boşlukları windowInsets ile): EqualWeight öğeler genişliği paylaşır, simge etiketin üstünde, gösterge simgenin arkasında 56×32; Centered öğeler en genişi kadar eşit genişlikte ortada toplanır, etiket simgenin yanında, gösterge (40 dp hap) ikisini sarar. Varsayılan düzen pencereye göre (600 dp altı eşit paylaşım, üstü ortada), öğenin iconPosition'ı düzene göre. Gösterge ortadan büyüyerek gelir (yay), dalga ona sınırlı; seçili simge onSecondaryContainer, etiket secondary; erişilebilirlikte sekme rolü ve seçili durumu |
WideNavigationRail, WideNavigationRailItem, rememberWideNavigationRailState (M3 Expressive) | ✅ kapalıyken 96 dp, her simge etiketinin üstünde (64 dp öğeler, 56×32 gösterge); state.expand()/collapse()/toggle() ile (çoğu zaman başlıktaki bir menü düğmesinden) 220 dp'ye yayla genişler, öğeler 56 dp'lik satırlara döner: etiket simgenin ardında, gösterge ikisini sarar (20 dp içeriden). Öğeler rayın durumunu kendiliğinden izler (railExpanded ile ezilebilir); başlık ile öğeler arası 40 dp, collapsedWidth/expandedWidth, sistem çubuklarının baş/üst/alt boşlukları windowInsets ile. ModalWideNavigationRail(modifier, öğeler, {state, header, hideOnCollapse, …}): kapalıyken yerinde kapalı ray (ya da hideOnCollapse ile hiçbir şey), açılınca her şeyin üstünde baş kenardan kayarak gelir (surfaceContainer, son köşeleri 16 dp yuvarlak) ve arkasını karartır; karartıya dokunmak ya da geri tuşu kapatır, rayın boş yerine dokunmak kapatmaz; içerik yalnız kapalı ray kadar yer bırakır |
TopAppBarDefaults kaydırma davranışları (pinned/enterAlways/exitUntilCollapsed), MediumTopAppBar/LargeTopAppBar, TopAppBarState | ✅ nestedScroll ile; yarıda kalan bar en yakın uca yerleşir |
AppBarRow, AppBarColumn (AppBarScope: clickableItem, toggleableItem, customItem), AppBarMenuState | ✅ Compose 1.5 gibi: sığan eylemler çubukta ikon düğmesi, gerisi ⋮ menüsünde (yalnızca bir şey dışarıda kalınca görünür; düğmeye yer ayrılır, son eylem o yeri kullanabilir); maxItemCount ile en çok o kadar yer (menü düğmesi sonuncusu); overflowIndicator kendi açma düğmeniz; AppBarColumn aynısı dikey (ray, dikey araç çubuğu; menü düğmesi altta) |
Üst çubuk renkleri, yükseklikleri ve inset'leri (Compose'un TopAppBarColors, expandedHeight, collapsedHeight, windowInsets) | ✅ TopAppBarSlots'ta: containerColor (surface), scrolledContainerColor (surfaceContainer), navigationIconContentColor ve titleContentColor (onSurface), actionIconContentColor ve subtitleContentColor (onSurfaceVariant; eylemler artık Compose'daki gibi onSurfaceVariant). expandedHeight (tek satırlılar 64 dp; orta/büyük 112/152, alt başlıkla 24 fazla) ve collapsedHeight (orta/büyük 64; genişlik ondan küçükse ona eşitlenir), sabitleri TopAppBarDefaults::TopAppBarExpandedHeight, Medium/LargeAppBarCollapsed/ExpandedHeight. windowInsets (varsayılan TopAppBarDefaults::windowInsets(): güvenli çizim alanının üstü ve yanları; WindowInsets{} hiç). Not: Compose 1.4.0'da titleHorizontalAlignment ve Flexible çubuklar henüz iç API |
IconButton (16), FloatingActionButton (10), ExtendedFloatingActionButton (4) | ✅ |
MediumFloatingActionButton, SmallExtendedFloatingActionButton / MediumExtendedFloatingActionButton / LargeExtendedFloatingActionButton (M3 Expressive) | ✅ orta FAB 80 dp (simge 28, köşe 20); genişletilmiş FAB'lar 56 / 80 / 96 dp yüksek (simgeler 24 / 28 / 36, etiketler titleMedium / titleLarge / headlineSmall, kenar boşlukları 16 / 26 / 28, simge-etiket arası 8 / 12 / 16, köşeler 16 / 20 / 28); expanded kapanınca etiket solar ve düğme simgesinin çevresinde kare bir FAB'a daralır (yayla), erişilebilirlikte etiketi okunur |
ToggleFloatingActionButton, FloatingActionButtonMenu, FloatingActionButtonMenuItem (M3 Expressive) | ✅ işaretli kalan FAB: primaryContainer → primary, yuvarlatılmış kareden (16 dp) daireye, istenirse boyuttan boyuta (containerSize → checkedContainerSize, contentAlignment'a doğru küçülür); içerik checkedProgress() okur (artı işaretini 45° çevirip çarpıya döndürmek gibi), içerik rengi de geçer. Menü: eylemler düğmenin üstünde bir sütunda (4 dp aralık, düğmeye 8 dp), hap biçiminde (56 dp, primaryContainer, simge + etiket); açılırken alttan yukarı, kapanırken üstten aşağı 50 ms arayla belirir/kaybolur (genişleyip solarak); horizontalAlignment (varsayılan sona). Not: geri tuşu menüyü kendiliğinden kapatmaz (Compose'daki gibi BackHandler uygulamanın) |
HorizontalFloatingToolbar, VerticalFloatingToolbar, FloatingToolbarDefaults (M3 Expressive) | ✅ içeriğin üstünde yüzen hap biçimli araç çubuğu (64 dp, 8 dp iç boşluk, gölge): ortadaki eylemler hep görünür, leadingContent/trailingContent yalnız expanded iken açılıp kapanır (yatay ya da dikey genişleyerek). Renkler standardFloatingToolbarColors() (surfaceContainer; FAB'ı secondaryContainer) ya da vibrantFloatingToolbarColors() (primaryContainer; FAB'ı tertiaryContainer). FAB'lı sürüm: araç çubuğu ve sonunda (dikeyde altında) 8 dp arayla FAB; kapalıyken yalnız FAB kalır (StandardFloatingActionButton/VibrantFloatingActionButton). exitAlwaysScrollBehavior(yön): içerik ileri kaydıkça çubuk o yöne (Bottom/Top/Start/End) kadar kayarak çıkar, geri kaydıkça döner; yarıda bırakılınca hızına ya da yakın uca göre tamamlar (kaydırmayı tüketmez); sınır çubuğun boyu + ScreenOffset (16 dp) |
ToggleButton, ElevatedToggleButton, TonalToggleButton, OutlinedToggleButton, ButtonShapes (M3 Expressive) | ✅ ToggleButton(checked, onCheckedChange, modifier, {shapes, renkler, enabled, interactionSource}, içerik): işaretlenince köşeler yuvarlaktan köşeliye (12 dp), basılıyken daha köşeli (8 dp) döner (Compose'un hızlı uzamsal yayı: sönüm 0,9, sertlik 1400); işaretsiz/işaretli renkler türüne göre (surfaceContainer → primary; Elevated surfaceContainerLow + gölge; Tonal secondaryContainer → secondary; Outlined çerçeve → inverseSurface), erişilebilirlikte onay kutusu rolü ve durumu. Düz düğmeler de ButtonStyle::shapes = ButtonShapes{} ile basılıyken köşeleşir |
ButtonGroup, ButtonGroupScope::animateWidth (M3 Expressive) | ✅ ButtonGroup([&](const ButtonGroupScope& group) { Button(onClick, group.animateWidth(kaynak), {.interactionSource = kaynak}, …); … }): düğmeler aralıklı (spacing, 12 dp) bir satırda; basılı tutulan expandedRatio (%15) kadar genişler, komşuları payı yarı yarıya (uçtakinde tek komşusu tümünü) verir, satırın genişliği değişmez (hızlı uzamsal yay); sıkışan düğme yüksekliğini korur. Düğmelerin (ve ToggleButton'ların) yatay iç boşluğu artık esner: tam genişlik dar verilince yazıdan önce kenarlar küçülür. Bağlı grup (segmentli düğmelerin yerine): ToggleButton'lar ButtonGroupDefaults::ConnectedSpaceBetween (2 dp) aralıkla, connectedLeading/Middle/TrailingButtonShapes() (dış köşeler yarım, iç köşeler 8 dp, basılıyken 4 dp; işaretli olan tam yuvarlak, köşeler tek tek döner). Öğelerden grup: ButtonGroup({{.label, .icon, .onClick} / {.label, .checked, .onCheckedChange}, …}) sığanları düğme (işaretli durumu olanları ToggleButton) olarak gösterir, sığmayanları sondaki ⋮ menüsüne koyar (menüde simgeleriyle, işaretli olanlar onay imiyle; seçilince menü kapanır); genişlikler görünmeden ölçülür |
SplitButtonLayout, SplitButtonDefaults::LeadingButton/TrailingButton/TrailingButtonIcon (M3 Expressive) | ✅ ana eylem ve menü düğmesi 2 dp aralıkla; dış köşeler yarım, buluştukları iç köşeler 4 dp (basılıyken 8 dp); menü düğmesi (48 dp) menüsü açıkken işaretli: tam yuvarlağa döner, oku (TrailingButtonIcon) ters çevrilir; renkler SplitButtonStyle::kind ile (Filled/Tonal/Elevated/Outlined, işaretliyken de aynı); erişilebilirlikte işaret durumu |
FilledIconButton/FilledTonalIconButton/OutlinedIconButton, IconToggleButton/FilledIconToggleButton/FilledTonalIconToggleButton/OutlinedIconToggleButton | ✅ IconToggleButton(checked, onCheckedChange, modifier, {.checkedContainerColor, .checkedContentColor, .enabled, .interactionSource}, içerik); renkler Material 3 varsayılanları (dolu: gri kap → birincil; tonal: → ikincil kap; çerçeveli: açıkken çerçeve gider, koyu ters yüzey gelir); erişilebilirlikte işaretli/işaretsiz onay kutusu; ripple dairenin içinde, içerik renginde |
SnackbarHost/SnackbarHostState (7/8), Circular/LinearProgressIndicator (5), ListItem (13) | ✅ İlerleme göstergeleri Compose 1.4'ünkiler gibi: yuvarlak uçlar, gösterge ile iz (secondaryContainer) arasında 4 dp (ve uçlar kadar) boşluk, belirli doğrusalın sonunda durdurma noktası; belirsiz doğrusal iki çizgiyle (1,75 sn'de baş ve kuyrukları kendi zamanlarında, emphasized accelerate), belirsiz dairesel izsiz, 6 sn'lik döngüde 1080° döner, her 1,5 sn'de 300 ms'de 90° daha, yayı %10'dan %87'ye çıkıp iner. co_await state.showSnackbarAsync(mesaj, eylem, süre, kapatmaDüğmesi) → SnackbarResult::ActionPerformed / Dismissed (Compose'un askıya alan showSnackbar'ı): sıradakilerden sonra gösterilir, gidince döner; eylemsiz olan Short, eylemli olan yanıtlanana dek kalır (Compose varsayılanları); bekleyen coroutine iptal olursa snackbar da gider; withDismissAction kapatma düğmesi. Eski showSnackbar(mesaj, eylem, onAction, süre) da duruyor. Snackbar(içerik, modifier, {.action, .dismissAction, .actionOnNewLine, .shape, renkler}) ve Snackbar(data): Compose'un düzeni (en çok 600 dp; tek satır 48 dp, eylem metnin taban çizgisinde; daha uzunsa ilk taban çizgisi 30 dp aşağıda, en az 68 dp; actionOnNewLine ile eylem altta sonda); SnackbarHost(state, modifier, [](const SnackbarData& d) { … }) kendi snackbar'ınız (d.performAction(), d.dismiss()); giriş/çıkış Compose gibi solma + %80'den büyüme. CircularProgressIndicator'ın çizgi kalınlığı strokeWidth (varsayılan 4 dp) |
Etkileşimli ListItem(onClick / selected / checked, ...), SegmentedListItem, ListItemShapes, ListItemDefaults::segmentedShapes | ✅ M3 Expressive gibi: satırın tamamı dokunuşu alır (tıklama, seçme ya da işaretleme; uzun basma), şekli duruma göre biçim değiştirir (dururken 4 dp, üzerine gelince 12, basılı, odakta ya da seçiliyken 16), seçili/işaretli olan secondaryContainer üzerinde; devre dışı onSurface %38; 16/10 dp dolgu, 12 dp ara, en az 56 dp. SegmentedListItem + segmentedShapes(i, n): bir kart gibi duran satırlar (ilkinin üst, sonuncunun alt köşeleri 16 dp), SegmentedGap (2 dp) arayla |
LinearWavyProgressIndicator, CircularWavyProgressIndicator (M3 Expressive), WavyProgressIndicatorDefaults | ✅ belirli (progress) ve belirsiz sürümler: gösterge dalgalanarak ilerler, iz (trackColor, varsayılan secondaryContainer) düz kalır ve göstergeden gapSize kadar ayrılır; doğrusalın izinin sonunda durdurma noktası (stopSize). Dalga yüksekliği amplitude(progress) ile (varsayılan: %10'un altında ve %95'in üstünde düz, değişimi 500 ms'de canlanır), wavelength (doğrusal 40 / belirsiz 20 / dairesel 15 dp), waveSpeed (dp/sn, varsayılan saniyede bir dalga boyu; düzken dalga durur, kare istemez); doğrusal olanın dalgası yüksekliğini doldurur (10 dp − çizgi), dairesel olanınki ±1,6 dp ve çemberde tam sayıda dalga döner. Belirsiz doğrusal: Compose'un iki çizgisi 1750 ms'de kovalaşır, iz aradaki boşluklarda; belirsiz dairesel: döner, uzar ve kısalır. Doğrusal olanlar düzenin başından başlar (RTL'de sağdan; düz LinearProgressIndicator da artık öyle). Genlik geçişi Compose'daki gibi 500 ms (artarken standard, azalırken emphasized accelerate eğrisiyle). Not: belirsiz dairesel zamanlaması CircularProgressIndicator'ınki |
LoadingIndicator, ContainedLoadingIndicator (M3 Expressive) | ✅ 48 dp içinde 38 dp'lik bir şekil sürekli döner ve 650 ms'de bir sonrakine dönüşür (yumuşak patlama, 9 dilimli kurabiye, beşgen, hap, güneş, 4 dilimli kurabiye, oval; her dönüşüm biraz taşarak çeyrek tur da çevirir, üstüne 4,7 sn'de bir tur); belirli sürüm ilerleme 0'dan 1'e çemberden yumuşak patlamaya büyür ve yarım tur döner. Kaplı (contained) olan primaryContainer dairede onPrimaryContainer; diğeri primary. Not: Material'ın şekilleri (androidx.graphics.shapes poligonları ve Morph) yerine merkezden uzaklık işlevleriyle yaklaşık çizilir, dönüşüm açı açı harmanlanır |
Slider başparmağı ve izi (thumb/track), SliderState (rememberSliderState), SliderColors, SliderDefaults::Thumb/Track | ✅ SliderOptions::thumb/track slider'ın durumundan (değer, aralık, adımlar, basılı/sürükleniyor, colors) yapılır; varsayılanı klasik daire başparmak ve ince iz. Hazırlar: CircleThumb (klasik, basılıyken hale), Thumb (Material 3'ün 4×44 dp çubuğu, basılıyken yarı kalın; dikeyde yatık), ShapeThumb(shape) (herhangi bir biçim: kare, MaterialShapes elmas/kurabiye/güneş…; basılıyken biraz büyür), IconThumb(icon), ValueThumb (değeri yazan hap); ClassicTrack (4 dp, adım noktaları), Track (Material 3: 16 dp, başparmaktan 6 dp boşluk, iç köşeler 2 dp, sonda durma noktası, adım noktaları 8 dp içeriden; adımdaki başparmak noktasının üstünde). SliderDefaults::colors() Material 3'ün, classicColors() klasiğin renkleri. Slider(state) kendi değerini tutar (setValue aralığa ve adıma oturtur). RangeSlider: startThumb/endThumb (yoksa thumb, o da yoksa klasik daire) her biri kendi SliderState'iyle (değeri, tutuluyor mu), rangeTrack aralığın RangeSliderState'iyle (activeRangeStart/End, held(), setActiveRange sıralı ve adımlı); SliderDefaults::ClassicTrack/Track aralık için de (Material 3'ünde iki başparmaktan da boşluk, iki uçta durma noktası); rememberRangeSliderState. Değer balonu: SliderDefaults::Label(state, label, thumb, isPersistent) başparmak tutulurken (ya da hep) üstünde bir etiket (PlainTooltip) gösterir. Slider'lar Compose'daki gibi 48 dp dokunma alanı alır (minimumInteractiveComponentSize) |
Label (M3), Modifier.minimumInteractiveComponentSize, LocalMinimumInteractiveComponentSize | ✅ Label(label, modifier, interactionSource, isPersistent, content): etkileşim kaynağı basılı/sürüklenen/üzerinde dedikçe (ya da hep) içeriğin üstünde, ortalı, 4 dp arayla (yer yoksa altında) etiket; girdi almaz. minimumInteractiveComponentSize: daha küçük olan 48 dp'ye (yerel değer; 0: kapalı) büyür, içerik ortada; o alana düşen dokunuşlar (ve fare tıkları) içindeki tıklanabilire gider. Compose'daki gibi kullananlar: Slider, RangeSlider, bütün IconButton/IconToggleButton türleri (40 dp daire 48 dp alanda), kendi tıklamasını alan Checkbox/TriStateCheckbox/RadioButton (24 dp, 48 dp alan, 40 dp'lik sınırsız dalga) ve Switch (52×32, 48 dp yükseklik). Tıklamayı satıra bırakanlar (geri çağırma yok) kendi boylarında: kutu ve radyo 24 dp, anahtar 52×32. Bu yüzden üst çubukta başlık artık gezinme düğmesinden sonra 56 dp'de (Compose'daki gibi). Compose'da tıklanabilir Surface üstüne kurulanlar da: bütün Button türleri, ToggleButton türleri, SplitButton parçaları (40 dp yükseklik, 48 dp alan), bütün çipler (32 dp, 48 dp alan) ve SmallFloatingActionButton (40 dp, 48 dp alan); büyük FAB'lar zaten 48'den büyük. SegmentedButton satırı 48 dp: çerçeve, yuvarlak uçlar ve seçili dolgu ortadaki 40 dp'lik bantta, her parça yukarıdan aşağı dokunuş alır (Compose'da her parça kendi çerçevesini çizer; görünüş aynı). Not: parçanın klavye odak halkasının üst ve alt kenarı banda kırpıldığı için görünmüyor |
FilterChip (3), AssistChip/SuggestionChip/InputChip (ve gölgeli, çerçevesiz ElevatedAssistChip/ElevatedSuggestionChip/ElevatedFilterChip), RadioButton, Slider (2), SegmentedButton (2) (SingleChoiceSegmentedButtonRow: radyo düğmeleri, selectableGroup; MultiChoiceSegmentedButtonRow + SegmentedButton(checked, onCheckedChange, …): onay kutuları; {.enabled, .icon, .interactionSource}), PrimaryTabRow/Tab (2) (ve simgesi metninin yanında LeadingIconTab, 48 dp), Badge/BadgedBox, ElevatedButton/FilledTonalButton, ElevatedCard/OutlinedCard, VerticalDivider, ButtonDefaults | ✅ Butonlar Compose 1.4'teki gibi: 40 dp yükseklik, en az 58 dp genişlik, 8 dp dikey dolgu; ButtonStyle::contentPadding (ButtonDefaults::ButtonWithIconContentPadding vb.: simgeli butonda başta 16 dp); çizgili buton outlineVariant; dolu/tonlu buton üzerine gelince 1 dp, gölgeli buton 1 dp (üzerine gelince 3), basılıyken geri iner |
RangeSlider | ✅ basılan yere yakın başparmak gelir, birbirini geçmezler; üst üsteyken sürükleme yönü seçer; steps |
VerticalSlider (M3 Expressive) | ✅ ayakta duran kaydırıcı: olabildiğince uzun, 44 dp geniş; değer yukarı doğru artar (reverseDirection ile aşağı), dokunuş ve dikey sürükleme ayarlar (yatay sürükleme almaz), SliderOptions'ın tümü (adımlar, interactionSource, onValueChangeFinished, enabled); yatay Slider ile aynı uygulamayı paylaşır |
SecondaryTabRow, PrimaryScrollableTabRow/SecondaryScrollableTabRow (ScrollableTabRow) | ✅ ikincil: sekme genişliğinde ince gösterge; kaydırılabilir: sekmeler kendi genişliğinde (en az 90 dp), kenar boşluğu, seçilen ortaya kayar |
dynamicLight/DarkColorScheme (10/10) | ✅ Android 12+ duvar kağıdı paleti (JNI, Compose'un ton eşlemesi); Linux'ta masaüstünün vurgu renginden (XDG portalı, TonalPalette::fromSeed); diğer masaüstlerinde varsayılan şema |
Dialog/AlertDialog (5/2), ModalBottomSheet (3), DropdownMenu/DropdownMenuItem, Popup, BackHandler | ✅ overlay katmanı: popup'lar yerinde kompoze edilir, en üstte çizilir, girdiyi alır; geri/Escape kapatır. ModalBottomSheet(onDismissRequest, rememberModalBottomSheetState(skipPartiallyExpanded), …): ekranın yarısından uzun sayfa yarıya kadar açılır (PartiallyExpanded), yukarı sürüklenince tam açılır, aşağı inince gizlenir (anchoredDraggable üzerinde, fırlatma hızıyla); currentValue/targetValue/isVisible gözlenebilir; show(), hide() (koddan: onDismissRequest çağrılmaz — co_await state.hide(); göster.set(false);), expand(), partialExpand(); scrim, geri ve aşağı sürükleme kaydırır sonra onDismissRequest'i çağırır; içindeki liste önce kayar, yarı açık sayfa liste kaymadan önce açılır. Geri hareketi (Android 14+) M3'teki gibi sayfayı alt ortasına doğru küçültür (en çok 48 dp dar, 24 dp alçak; içerik esnemez): bitince gizlenir, yarıda durağı olan tam açık sayfa yarıya iner, vazgeçilince büyür. Odaklanabilen popup'ların (Dialog, sayfa, menü) içindeki BackHandler/PredictiveBackHandler geriyi popup kapanmadan önce alır; pencereninkiler üstte popup varken almaz |
PredictiveBackHandler(enabled) { progress -> ... }, BackEventCompat | ✅ Android 14+ geri hareketi: açıkken hareket başlayınca onBack eşyordamı adımların akışıyla (Flow<BackEventCompat>: progress 0..1, touchX/touchY dp, swipeEdge) başlar; akış hareket bitince biter ve eşyordam devam eder (kapat, geri git), vazgeçilirse eşyordam iptal edilir (içindeki RAII koruması geri alır); geri tuşu/Escape boş akışla başlatır. Popup ya da odak varsa hareket bitince onlar kapanır/temizlenir. Android 13+'te uygulama OnBackInvokedCallback'i yalnızca geriyi alacak bir şey varken kaydeder: yoksa sistem uygulamadan kendi "ana ekrana dön" animasyonuyla çıkar; 13 öncesinde geri tuşu SDL'den gelir |
Modifier.systemGestureExclusion(), systemGestureExclusion(rect(koordinatlar)) | ✅ kenardan başlayan sürüklemeler sistemin geri/ana ekran hareketine değil uygulamaya gider (Compose'unki; Android 10+ hareketli gezinmede, Android her kenarda en çok 200 dp'ye izin verir): host yerleşimden sonra görünen dikdörtgenleri toplar (ComposeHost::systemGestureExclusion()), Android'de değişince View.setSystemGestureExclusionRects; ikincisi düğüme göre yerel bir dikdörtgenle daraltır |
Autofill (ContentType, autofillManager()) | ✅ Compose 1.8'in autofill'i: semantics({.contentType = ContentType::Username + ContentType::EmailAddress}) (Username, Password, NewPassword, EmailAddress, PhoneNumber, CreditCardNumber, PostalCode, SmsOtpCode ve Compose'un öbür türleri; + ile birleşir) metin alanının ne aldığını söyler. Android 8+'da metin alanları yüzeyin sanal görünümleri olarak autofill'e verilir (ipuçları, parola alanları setDataIsSensitive): odak alana girince/çıkınca, metin değişince, alan gelip gidince parola yöneticisine bildirilir; yönetici alanları doldurur (SemanticsAction::SetText, giriş dönüşümünden geçer). autofillManager().commit() (form gönderildi: kaydetmeyi önerir) ve cancel(); composition'da alınıp olay işleyicisine yakalanır. Erişilebilirlik hizmetleri de ACTION_SET_TEXT ile alanlara metin yazabilir. Masaüstünde ve web'de etkisiz |
Modifier.sensitiveContent(isContentSensitive = true) | ✅ düğüm yerleşimde durdukça hassas içerik (parola, kart numarası) gösterdiğini söyler (Compose'unki): host yerleşimden sonra varlığını izler (ComposeHost::sensitiveContent()), Android 15+'ta pencere ekran paylaşımında ve kayıtta gizlenir (View.setContentSensitivity(SENSITIVE)); false ipucunu geri alır. Masaüstünde ve web'de etkisiz |
Modifier.clipScrollableContainer(orientation) | ✅ yalnızca o eksende kırpar, çapraz eksende her iki yana 30 dp pay bırakır (Compose'unki; kaydırılan kapların kırptığı gibi, kart gölgeleri görünsün diye) |
Modifier.keepScreenOn() | ✅ düğüm yerleşimde durdukça ekran kararmaz/uyumaz (Compose'unki; video, tarif); host yerleşimden sonra varlığını izler (ComposeHost::keepScreenOn()), platform SDL'in ekran koruyucusunu kapatır (Android'de FLAG_KEEP_SCREEN_ON). Kompoz uygulamaları artık varsayılan olarak ekranın kararmasına izin veriyor (SDL'in varsayılanı ekranı hep açık tutuyordu) |
BottomSheetScaffold, rememberBottomSheetScaffoldState, SheetState (expand/partialExpand/hide) | ✅ hep orada duran alt sayfa: sheetPeekHeight kadar görünür (gezinme çubuğunun üstünde), sürükleme/fırlatmayla içeriği kadar (en çok ekran) açılır; içindeki liste sayfa tamamen açılınca kayar, aşağı çekilince önce liste başa döner sonra sayfa iner; sheetDragHandle, sheetSwipeEnabled, topBar, snackbarHost; currentValue/targetValue gözlenebilir, kaydedilir (rememberSaveable); çevresindeki düzenin zaten tükettiği sistem çubuğu boşluklarını tekrar eklemez |
ModalNavigationDrawer (4) (DrawerState, ModalDrawerSheet, NavigationDrawerItem), NavigationRail (3) | ✅ sürükleyerek açma/kapama, geri tuşu; LocalWindowSize ile bar ↔ rail. Geri hareketi (Android 14+, M3 gibi): ModalDrawerSheet/DismissibleDrawerSheet drawer'ın kendi kenarından gelen harekette en çok 12 dp genişler, öbür kenardan gelende 24 dp daralır, 48 dp alçalır (dış kenarının ortasından; içerik biçimini korur); bitince drawer kapanır (genişlemiş olan kapanırken geri daralır), vazgeçilince eski hâline döner. M3'teki gibi DrawerState alan sheet sürümleri de var |
SearchBar (3), SearchBarDefaults.InputField | ✅ yerleşimde hap, açılınca tam ekran arama görünümü (geri kapatır, klavyenin Ara tuşu onSearch) |
BasicAlertDialog, AlertDialogDefaults, AlertDialog(onDismiss, slots, modifier, properties), DialogProperties::usePlatformDefaultWidth | ✅ Compose 1.4.0'daki gibi. BasicAlertDialog(onDismiss, modifier, content, properties): kendi içeriğiniz, 280–560 dp genişlikte; en az genişlik içeriğe de geçer (Compose'un propagateMinConstraints'i). AlertDialog: shape (28 dp köşe), containerColor (surfaceContainerHigh), iconContentColor (secondary), titleContentColor (onSurface), textContentColor (onSurfaceVariant); metin kısa pencerede butonlara yer bırakır (weight(1, false)); butonlar sonda 8 dp arayla, sığmayınca satırlar yukarı doğru dizilir (onay butonu üstte, satırlar 12 dp arayla). usePlatformDefaultWidth = false: kenarlardan 48/24 dp boşluk yok, pencere kadar büyüyebilir (tam ekran diyalog). Not: AlertDialog'un imzası değişti (modifier eklendi, properties ondan sonra) |
DatePicker, DatePickerDialog, rememberDatePickerState | ✅ ay sayfaları kaydırılır ya da oklarla geçilir, ay adına dokununca yıl ızgarası; gün, ay ve yıl istenen sırada seçilir (ay değişince seçili tarih aynı güne taşınır); std::chrono tarihleri, Türkçe/İngilizce metinler (DatePickerStrings, verilmezse LocalStrings'inkiler); giriş modu (DisplayMode::Input, başlığın yanındaki kalem ya da rememberDatePickerState(..., DisplayMode::Input)): tarih outlined bir alana yalnızca rakamla yazılır, ayırıcılar kendiliğinden görünür (GG.AA.YYYY kalıbı strings.inputPattern'dan), tamamlanıp geçerliyse seçilir ve takvim o aya açılır; geçersiz gün ya da yıl aralığı dışı alanın altında söylenir (Compose'un metinleriyle, Türkçesi de); showModeToggle = false düğmeyi gizler |
TimePicker, TimeInput, TimePickerDialog, rememberTimePickerState | ✅ kadran (dokun/sürükle, saat seçilince dakikaya geçer; 24 saatte iç halka), 12 saatte ÖÖ/ÖS, yatay pencerede yan yana; TimeInput iki sayı alanı |
DateRangePicker, rememberDateRangePickerState | ✅ başlıkta Başlangıç/Bitiş sekmeleri, seçili olanı DatePicker'ın takvimi düzenler (Compose'daki dikey liste yerine); aralık bantla, bitiş başlangıçtan önce olamaz; giriş modu (kalem ya da DisplayMode::Input): başlangıç ve bitiş yan yana iki alana yazılır (DatePicker'ınki gibi); bitişten sonraki başlangıç ya da başlangıçtan önceki bitiş "Geçersiz tarih aralığı girişi" der, seçilmez; bir an yanlış yazılan başlangıç önceden yazılan bitişi kaybettirmez |
DockedSearchBar | ✅ alan yerinde kalır, öneriler altında aynı genişlikte sayfanın üstüne açılır (240 dp – pencerenin 2/3'ü); dışarı dokunmak / geri kapatır |
SearchBarState, rememberSearchBarState, ExpandedFullScreenSearchBar, ExpandedDockedSearchBar (yeni arama API'si) | ✅ açık/kapalı durumu bir nesnede (currentValue/targetValue/progress gözlenebilir; animateToExpanded()/animateToCollapsed() co_await edilir, snapTo), sorgu bir TextFieldState'te: SearchBarDefaults::InputField(state, metin, {.onSearch, .placeholder, ikonlar}), kapalı çubuk SearchBar(state, alan), açık hâli ayrı: tam ekran (M3'teki gibi kapalı çubuktan büyüyerek açılır ve ona geri döner: yüzey çubuğun sınırlarından pencereninkine, alan çubuğun yüksekliğinde durum çubuğunun 8 dp altına, sonuçlar solarak; geri hareketi görünümü onda dokuza küçültür, geldiği kenarın karşısına ve parmakla en çok 24 dp yukarı/aşağı kaydırır, çubuğun ötesine geçirmez; bitince oradan çubuğa döner) ya da kapalı çubuğun yerinde ve genişliğinde (dışarı dokunmak kapatır). Animasyonlar durumun kapsamında sürer; açılırken alanı kapalı çubuktan ayrılsa da kesilmez. BasicTextField(TextFieldState) da var. AppBarWithSearch(state, alan, mod, {.navigationIcon, .actions, .scrollBehavior}): üst çubuk olarak arama (72 dp, durum çubuğunun altında, hap gezinme simgesiyle eylemlerin arasında); SearchBarDefaults::enterAlwaysSearchBarScrollBehavior() ile içerik ilerledikçe önce çubuk yukarı kayıp çekilir (içerik onun yerini alır), geri kaydırınca liste kıpırdamadan önce o döner. TopSearchBar(state, alan, mod, kaydırma) (M3 1.4): yalnızca arama çubuğu üst çubuk olarak — durum çubuğunun altında, kenarlardan 8 dp içeride, en çok 720 dp genişlikte ortada, arkasında zemin yok; kaydırma davranışıyla aynı biçimde kayıp çekilir |
TooltipBox, PlainTooltip, RichTooltip, rememberTooltipState | ✅ uzun basınca (alttaki tıklama olmaz) ya da fare üzerinde bekleyince; çapanın üstünde, yer yoksa altında; geçici 1.5 sn, kalıcı dışarı dokununca kapanır; caretSize (TooltipDefaults::caretSize) ile çapanın ortasını gösteren ok (zengin ipucunda gölgeli). M3 1.4'ün konumlandırması: TooltipBox(TooltipDefaults::rememberTooltipPositionProvider(TooltipAnchorPosition::Above/Below/Left/Right/Start/End, aralık = 4), …) — o yanda, çapaya çapraz eksende ortalı, yer yoksa karşı yanda; Start/End yazı yönüne göre; ok da o yana döner |
MenuBar, MenuBarMenu, MenuBarItem, KeyShortcut (Compose Multiplatform masaüstü pencere menüleri) | ✅ pencerenin üstünde bir şerit olarak çizilir (yerel menü değil): başlığa tıklamak menüyü altında açar, biri açıkken fare başka başlığa gelince o açılır; öğeler kısayollarını sağda gösterir (Ctrl+Shift+S), işaretli öğeler (checked), alt menüler (fare üzerine gelince yanında açılır; sağda yer yoksa solda), ayraç, kapalı öğeler; dışarı tıklamak / Escape kapatır, kartlar pencereye sığdırılır. Kısayollar menü kapalıyken de çalışır: odaklı düğüm ve çevresindeki işleyiciler (metin alanının Ctrl+A'sı gibi) almazsa pencerenin işleyicilerine gider (ComposeHost::addKeyHandler); kapalı öğenin kısayolu çalışmaz. Showcase'te masaüstü/web'de Dosya/Görünüm/Git menüleri |
Modifier.onPointerEvent (PointerEventType.Enter/Exit/Move/Press/Release/Scroll), Modifier.onClick (PointerMatcher, keyboardModifiers), TooltipArea (TooltipPlacement.CursorPoint/ComponentRect) (Compose Multiplatform masaüstü) | ✅ onPointerEvent: fare düğümün üstüne gelince/gidince (pencereden çıkınca da), üstünde gezerken, bir tuş basılıp bırakılınca (event.button: Primary/Secondary/Tertiary/Back/Forward; SDL'in tuşları, betikte rclick/mclick), tekerlek dönünce (change.scrollDelta, aşağı artı; tüketmek kaydırmayı durdurur); keyboardModifiers basılı Shift/Ctrl/Alt (platform her fare ve tuş olayında bildirir: ComposeHost::setKeyboardModifiers); olay geçişi (PointerEventPass) yok, en içteki önce. onClick: birincil tuş ve parmak dokunmayla (çift tık, uzun basma), öbür tuşlar basılıp aynı düğümde bırakılınca; dalga, odak, semantik yok. TooltipArea: fare alanın üstüne geldikten delayMillis (500) sonra ipucu imlecin 16 dp altında (sığmazsa üstünde) ya da alanın bir noktasına göre çıkar, fareyi izler; basınca ya da çıkınca kapanır, girdiyi geçirir |
ContextMenuArea, ContextMenuItem, metin alanı sağ tık menüsü (Compose Multiplatform masaüstü) | ✅ sağ tık (ComposeHost::secondaryClick; SDL'in sağ tuşu, betikte rclick x y) altındaki en içteki menüyü tıklanan yerde açar, pencereye sığmazsa sola/yukarı döner; satırlar en geniş öğe kadar (112–280 dp); seçince çalışır ve kapanır, dışarı tıklamak / Escape kapatır, enabled = false öğe soluk ve tıklanmaz. Metin alanında tıklama alanı odaklar, imleci seçimin dışındaysa oraya taşır; Kes/Kopyala seçim yoksa ya da şifrede kapalı, salt okunurda Kes/Yapıştır kapalı; menüden kopyalamak seçimi bırakmaz (dokunmatik araç çubuğundaki gibi imlece dönmez) |
VerticalScrollbar, HorizontalScrollbar, rememberScrollbarAdapter, ScrollbarStyle (Compose Multiplatform masaüstü) | ✅ başparmak görünen payın uzunluğunda (en az 16 dp) ve içeriğin olduğu yerde, çizilirken okunur (kaydırma bir şey kompoze etmez); sürüklemek içeriği başparmağın yolu kadar kaydırır, raya tıklamak o yöne bir sayfa (görünen boy) kaydırır; fare üzerindeyken ve sürüklenirken renk koyulaşır (hoverDurationMillis); kaydıracak bir şey yoksa başparmak yok. rememberScrollbarAdapter(ScrollState) (ScrollState::viewportSize da var) ve (LazyListState) (içerik boyu görünen öğelerin ortalamasından, Compose gibi); kendi ScrollbarAdapter'ınız da olur; ScrollbarOptions{.reverseLayout, .style, .interactionSource} |
Shape.createOutline, Outline (Rectangle, Rounded, Generic), RoundRect, CornerRadius, GenericShape | ✅ Compose'daki gibi: her şekil bir boyutta ve yerleşim yönünde kendi Outline'ını yapar (shape.createOutline(boyut, yön)); GenericShape([](Path& p, Size boyut, LayoutDirection y) { … }) herhangi bir yol, OutlineShape([](Size boyut, LayoutDirection y) { return Outline::Rounded(RoundRect{…}); }) herhangi bir dış çizgidir (bir RoundRect'in köşeleri eliptik olabilir: CornerRadius(x, y); Path::addRoundRect(RoundRect)). Arka plan, çerçeve, gölge, clip ve dalgalar dış çizgiye göre çizilir: bir dikdörtgen ya da köşeleri dairesel yuvarlak bir dikdörtgen kendisi olarak, gerisi yolu olarak; clip katmansız kırpar (GraphicsContext::pushClipShape) |
ShapeOutline, OutlineShape, MaterialShapes, RoundedPolygon, Morph | ✅ köşeleri yuvarlak dikdörtgen olmayan şekiller: OutlineShape(çizgi) (birim karede, saat yönünde noktalar; herhangi bir çokgen) arka planda, çerçevede (içte), gölgede, clip'te, graphicsLayer kırpmasında ve dalgada çalışır, RTL'de aynalanır. MaterialShapes::Cookie9Sided() gibi Material'in 35 şekli (all() adlarıyla; Material'inkilere yakın: yuvarlatılmış çokgenler, yıldızlar, yapraklı ve piksel şekiller), toShape(çizgi); kendi şekilleriniz için roundedPolygon({{x, y, yuvarlaklık}, …}) ve roundedStar(uç, iç oran, uç/girinti yuvarlaklığı). Morph(baştan, sona): iki şekil arasında açı açı karışım, 64 adımda (toShape(ilerleme) animasyonla kullanılır; morph'u remember edin). Notlar: Compose'un yumuşatmalı köşeleri (smoothing) yok; morph kutupsal örneklemeli |
DropdownMenuPopup, DropdownMenuGroup, MenuDefaults, işaretli/seçili DropdownMenuItem (M3 Expressive menüler) | ✅ açılır pencerenin kendi kartı yok, her grup bir kart (surfaceContainerLow, gölgeli), gruplar MenuDefaults::GroupSpacing (2 dp) arayla; groupShape(sıra, sayı) menünün uçlarında 16, birleşimlerde 4 dp, itemShape grubun uçlarında 12, arada 4 dp. DropdownMenuItem(checked, onCheckedChange, …) (onay kutusu rolü) ve DropdownMenuItem(selected, onClick, …) (radyo rolü): işaretli/seçiliyken tertiaryContainer'da, 12 dp yuvarlak, metninden önce ✓ (checkedLeadingIcon); gruptaki öğeler 4 dp içeride. Her öğede MenuItemOptions::supportingText (altta küçük açıklama) |
ExposedDropdownMenuBox, ExposedDropdownMenu, ExposedDropdownMenuDefaults.TrailingIcon | ✅ alana dokununca açılır/kapanır, menü alanla aynı genişlikte altında (yer yoksa üstünde), uzun listede kayar; salt okunur ya da yazdıkça süzen alanla |
PermanentNavigationDrawer/PermanentDrawerSheet, DismissibleNavigationDrawer/DismissibleDrawerSheet | ✅ kalıcı: içerik yanında; açılır: karartma yok, içeriği iter, sürükleme ve geri tuşu |
currentWindowAdaptiveInfo(), WindowSizeClass, NavigationSuiteScaffold (material3-adaptive) | ✅ pencere boyut sınıfları (genişlik Compact < 600 ≤ Medium < 840 ≤ Expanded dp, yükseklik 480 / 900; isWidthAtLeastBreakpoint); NavigationSuiteScaffold öğeleri pencereye göre alt çubukta, rayda ya da (istenirse) kalıcı çekmecede gösterir (NavigationSuiteScaffoldDefaults::calculateFromAdaptiveInfo: Compose gibi alçak pencerede çubuk, orta/geniş genişlikte ray), içerik pencere bir eşiği geçince de yerinde kalır (durumu korunur) ve çubuğun/rayın zaten kaçındığı sistem boşluklarını tekrar eklemez; Scaffold da artık çevresinin tükettiği boşlukları saymıyor. ListDetailPaneScaffold<T>(navigator, liste, ayrıntı(optional<T>)) + rememberListDetailPaneScaffoldNavigator<T>() (navigateTo(rol, anahtar), navigateBack, canNavigateBack, currentDestination, detailKey; gözlenebilir): geniş pencerede (≥ 840 dp) liste (360 dp) ve ayrıntı yan yana, daha darda tek bölme — ayrıntı sondan kayarak gelir, geri tuşu (handleBack) kaydırarak listeye döner, çıkan ayrıntı gösterdiğini korur, ayrıntıdan ayrıntıya geçiş yerinde; maxHorizontalPartitions, listPaneWidth, spacerSize. SupportingPaneScaffold<T>(navigator, ana, destek(optional<T>)) + rememberSupportingPaneScaffoldNavigator<T>() (navigateTo(SupportingPaneScaffoldRole::Supporting, anahtar), supportingKey): geniş pencerede ana bölme ve sonda destek bölmesi (supportingPaneWidth, 360 dp; RTL'de solda), daha darda ana bölme — destek sondan kayarak gelir, geri tuşu döndürür; iki iskele aynı gezgin ve tek/iki bölme mantığını paylaşır. Yan yanayken aradaki boşlukta bir tutamaç (paneExpansionDragHandle, ör. VerticalDragHandle(paneExpansionDraggable(state, kaynak), kaynak)) ilk bölmenin genişliğini sürükler; rememberPaneExpansionState({PaneExpansionAnchor::Proportion(0.5f), PaneExpansionAnchor::Offset(360), PaneExpansionAnchor::Offset(-100) /* sondan */}) bırakınca en yakın çapaya, fırlatınca o yöndeki sonrakine oturur (çapasızsa bırakıldığı yerde kalır), RTL'de ters yönde; setFirstPaneWidth/setFirstPaneProportion/clear koddan. VerticalDragHandle: 4 × 48 dp, basılı/sürüklenirken 12 × 52 dp ve onSurface. Notlar: üçüncü (extra) bölme ve katlanabilir duruş (windowPosture) yok; LocalWindowInfo.current() (Compose'unki): isWindowFocused (başka bir pencere, sistem iletişim kutusu ya da bildirim perdesi üstündeyken değil; SDL'in pencere odak olaylarından) ve containerSize (pencerenin boyutu, dp — Compose'da piksel); LocalViewConfiguration.current() (Compose'unki): longPressTimeout, doubleTapTimeout, doubleTapMinTime, touchSlop (dp), minimumTouchTargetSize, maximumFlingVelocity (dp/s) — Android'de cihazın android.view.ViewConfiguration'ından; host'un tıklama/sürükleme/fırlatmaları ve pointerInput blokları (kompoze edildikleri yerdeki değerle: PointerInputScope::viewConfiguration()) bunlara uyar, ilk dokunuştan doubleTapMinTime içinde gelen ikinci dokunuş çift dokunma sayılmaz. En küçük dokunma hedefi (Compose'unki): parmakla dokunulan yerde (ya da dokunulan kartın/listenin içinde) doğrudan bir hedef yoksa minimumTouchTargetSize'dan (48 dp) küçük tıklanabilir/pointerInput öğelerin alanı o boyuta eşit büyütülür, dokunuşu içerenlerin en yakını dokunulmuş sayılır; bırakma da büyütülmüş alanda tıklamadır; PointerInputScope::extendedTouchPadding() ve isOutOfBounds(boyut, dolgu) dokunma algılayıcıları için; fare yalnızca gerçek sınırları kullanır |
Animasyon
| API | Durum |
|---|---|
animateFloatAsState (7), animateColorAsState (3), FastOutSlowInEasing (4) | ✅ |
tween (18), spring (7), infiniteRepeatable (5), repeatable, snap, easing'ler | ✅ |
Animatable (13), animateDecay, exponentialDecay/rememberSplineBasedDecay, VelocityTracker | ✅ co_await anim.animateTo(...); float için: animateTo(hedef, spring, başlangıçHızı) (yay fiziği hızı taşır: fırlatılan aşar, bırakılan sürükleme hızıyla geri döner), animateDecay(hız, DecayAnimationSpec) (hız exp(−sürtünme·t) ile düşer, eşiğin altında durur), updateBounds(alt, üst) (snapTo ve animasyonlar sınırda durur), velocity(), targetValue() (decay'in duracağı yer). exponentialDecay(sürtünmeÇarpanı, hızEşiği) (Compose'unki: 4,2/s), splineBasedDecay() (kaydırılabilirlerin fırlatması), calculateTargetValue (sayfaya oturtma), valueAt/velocityAt/durationMillis. VelocityTracker: addPosition(ms, konum), calculateVelocity() (son 100 ms'nin en küçük kareler eğimi; 40 ms duraklama öncesini saymaz), resetTracking(). rememberDraggableState(onDelta, [](float hız) { … }) bırakış hızını söyler; anchoredDraggable yay ile otururken fırlatma hızını taşır (uçları aşmadan). splineBasedDecay() / rememberSplineBasedDecay() Android'in fırlatma eğrisi (OverScroller'ın spline'ı, Compose'un AndroidFlingSpline/FlingCalculator'ı; dp cinsinden, yoğunluk sadeleşir): fırlatma o hızla başlar, 0,015 sürtünme ve fiziksel yavaşlamayla mesafesi hızın ~1,74'üncü kuvvetiyle büyür (2000 dp/s → 647 dp, 925 ms; 8000 dp/s → 7186 dp); bütün kaydırılabilirlerin (verticalScroll, tembel listeler, pager tahmini, yakalamalı listeler, scrollable2D — parmağın yönünde) fırlatması bu eğriyi izler; exponentialDecay üstel kalır |
AnimatedVisibility (11) + fadeIn/fadeOut (11), AnimatedContent (10), Crossfade (2) | ✅ fade/expand/shrink/slide/scale; çıkan içerik dokunma ve odak almaz; AnimatedContent(n, [](const int&) {...}) tür argümanı vermeden de çalışır; transitionSpec olarak [](const T& önceki, const T& hedef) { return togetherWith(…); } (yön durumlara göre: sayaç artınca aşağıdan, azalınca yukarıdan); SizeTransform (varsayılan: kap eski içeriğin boyutundan yenisininkine yayla büyür, clip ile kırpar; togetherWith(…).withSizeTransform(SizeTransform{.clip = false}) ya da std::nullopt — gösterilenler kadar büyük, Crossfade gibi). keyframes(süre, {{ms, değer, easing}, …}[, gecikme]): float animasyonlarda değerler mutlak (1 → 1,3 → 1 nabız), renk gibi diğerlerinde başlangıçtan hedefe yolun kesri; repeatable/infiniteRepeatable ile tekrarlanır. AnimatedContentOptions: {.contentAlignment = Alignment::Center} (içerikler kapta — boyutu canlanırken de — o hizada durur; varsayılan üst başlangıç), {.contentKey = [](const Ekran& e) { return uint64_t(e.tür); }} (aynı anahtarlı yeni durum geçişsiz, içeriğin durumunu koruyarak yerine geçer: Yükleniyor → Yüklendi kayar, Yüklendi'deki yeni veri kaymaz; geçiş sürerken gelen veri yalnızca giren içeriğe gider). İçerikteki bir çocuğun kendi giriş/çıkışı: scope.animateEnterExit(slideInVertically(1), slideOutVertically(1)) (Compose'un Modifier.animateEnterExit'i; içerik girerken o da girer, çıkarken kendi yoluyla çıkar, içerik onların hepsi çıkana dek kalır; yarıda dönerse olduğu yerden döner; baştan görünen içerikte giriş yok); EnterTransition::None/ExitTransition::None (içerik anında gelir/gider, yalnızca çocuklar canlanır); targetContentZIndex (togetherWith(…).withTargetContentZIndex(-1): giren içerik çıkanın altından gelir — geri gidiş; varsayılan 0'da yeni olan üstte) |
rememberInfiniteTransition (4), animateContentSize (2), updateTransition (6), MutableTransitionState, rememberTransition, AnimatedVisibility(visibleState) | ✅ MutableTransitionState<S>(başlangıç): setTargetState(…) geçişi başlatır — başlangıçtan farklı hedef, ilk görünüşte de canlandırır (ekran açılırken gelen AnimatedVisibility, listeye eklenen satır); currentState() değerler varınca yetişir, isIdle() orada durduğunu söyler (yolda geri dönmüşse değil; tümüyle gitmiş satırı şimdi listeden çıkarın); hepsi gözlenebilir. AnimatedVisibility(visibleState, modifier, enter, exit, içerik): hedefe göre gösterir, mevcut durumdan başlar; içerik tümüyle girince ya da gidince currentState'i günceller. rememberTransition(state) (ve updateTransition(state)): değerleri mevcut durumdan hedefe canlandırır, vardıklarında durumu günceller |
Modifier.animateBounds, LookaheadScope (Compose 1.8) | ✅ yerleşim düğümü taşıyınca ya da boyutunu değiştirince çizildiği yerden yaylı (ya da verilen AnimationSpec'le) oraya kayar, içeriği yoldaki boyutta yerleşir; yeri en yakın LookaheadScope'a (bir Box) göre ölçülür, o kaydırılınca animasyon olmaz. Önden bakma (lookahead) geçişi yok: hizalı bir üstte boyutu büyürken yeri de değişirse yol hedefe süresi içinde yetişir ama tam doğrusal değildir; dokunma yerleştiği yere gelir; movableContentOf olmadığından başka bir üste taşınan içerik yeniden yaratılır (animasyonsuz). Modifier.skipToLookaheadSize(): çevresindeki düzen boyutunu canlandırırken (animateBounds, hareket eden paylaşılan öğe) içerik gideceği boyutta dizilir, kendi boyutu canlandırmayı izler (Compose'unki: metin büyürken yeniden kırılmaz) |
Modifier.approachLayout, DeferredTargetAnimation | ✅ içerik önce gideceği gibi ölçülür (lookahead: ApproachMeasureScope::lookaheadSize); isMeasurementApproachInProgress(lookaheadSize) doğru oldukça approachMeasure(scope, measure, constraints, placeAt) onu yoldaki boyutta dizer, sonra lookahead gibi; orada okunan durum yeniden dizer. DeferredTargetAnimation<T>(spec): ilk hedef olduğu gibi alınır, yenisine updateTarget(target, scope) ile canlanarak gider; isIdle, pendingTarget. Not: lookahead yerel (Compose'unki bütün LookaheadScope'un), yerleşim yaklaşımı (isPlacementApproachInProgress) yok |
Navigation: NavHost, NavController, rememberNavController, composable(route), navigate, popBackStack, currentBackStackEntryAsState | ✅ rotalar {ad} parçalı yol ve isteğe bağlı ?ad={ad} sorgu parametreleri (arguments().getInt/getString/…); NavOptions{popUpTo, inclusive, saveState, launchSingleTop, restoreState} (alt gezinme sekmeleri kendi yığınlarını korur); geri tuşu yığını boşaltır; geri hareketi (Android 14+) alttaki ekranı pop geçişiyle hareketin ilerlemesi kadar gösterir (Compose'daki gibi geçiş zaman çizelgesinde aranır), bitince pop eder ve geçiş kaldığı yerden sürer, vazgeçilince üstteki ekran yeniden tam görünür; ileri ve geri geçişleri (NavHostOptions, varsayılan 700 ms çapraz solma; Compose'daki gibi ileri gidilen girdi öncekinin üstünden, geri dönülen altından gelir — birikimli z-index); her girdinin rememberSaveable durumu yığındayken korunur. İç içe grafikler: navigation(startDestination, route) { … } (grafiğin rotası başlangıç hedefine gider; grafiğin yığında kendi girdisi ve ViewModel'leri olur, son ekranından geri çıkınca o da kalkar; popUpTo grafiğin rotasıyla bütün akışı kapatır), getBackStackEntry, entry.parent(), entry.hierarchy() (sekme seçimi). Derin bağlantılar: composable(route, {navDeepLink("kompoz://item/{n}")}, …), navigate(uri), handleDeepLink (başlangıç ekranı + grafikler + hedef); masaüstünde komut satırı, web'de adresin # kısmı (gösterilen ekran oraya yazılır), Android'de VIEW intent'i. Tür güvenli rotalar: alanları argüman olan bir struct ve KOMPOZ_ROUTE(Tip, alanlar…) (ya da adıyla KOMPOZ_NAMED_ROUTE); zorunlu alanlar yol parçası, std::optional'lar sorgu parametresi; composable<T>, navigation<T>(başlangıç, …), navigate(T{…}), toRoute<T>(), hasRoute<T>(), getBackStackEntry<T>(), popBackStack<T>(), navDeepLink<T>(taban); alanlar metin, sayı, bool, enum ve bunların std::optional'ı (MSVC'de /Zc:preprocessor, CMake ekliyor) |
SharedTransitionLayout (8), sharedElement, sharedBounds, rememberSharedContentState | ✅ AnimatedContent/AnimatedVisibility içeriği AnimatedVisibilityScope alır; giren öğe eşinin yerinden (ya da yarıda kesilen geçişte o an çizildiği yerden) yay animasyonuyla kendi yerine gider, içeriğin üstünde (ebeveyni solsa da) çizilir, eşi gizlenir; sharedElement ara boyutta yeniden ölçülür, sharedBounds ikisini çapraz soldurur ve Compose'daki gibi genişliğe ölçekler (metin akmaz); çıkan içerik geçiş bitene kadar bekler. sharedBounds(…, boundsTransform, SharedResizeMode::scaleToBounds(ContentScale, Alignment)) (varsayılan FillWidth + orta; Fit, FillBounds… her içerik kendi boyunda ölçülüp sınırlara o ölçekle sığdırılır) ya da SharedResizeMode::remeasureToBounds() (ikisi de her karede ara boyutta yeniden ölçülür, çapraz solarak; Compose'un ResizeMode'u). Eksikler: boundsTransform yalnızca AnimationSpec, skipToLookaheadSize yok. Katman: sharedElement/sharedBounds(…, boundsTransform, [resizeMode,] renderInOverlayDuringTransition, zIndexInOverlay) (hareket ederken katmanda z sırasıyla ya da false ile içerikteki yerinde, ondan sonra gelenlerin altında); Modifier.renderInSharedTransitionScopeOverlay(scope, renderInOverlay, zIndexInOverlay) bir düğümü (alt çubuk gibi) koşul sürdükçe (boş: bir öğe hareket ettikçe) katmanda, hareket edenlerin arasında z sırasıyla çizer |
UI, çizim ve metin
| API | Durum |
|---|---|
Modifier (207), Alignment (98), Color (86), dp (147) | ✅ |
graphicsLayer (14), alpha, shadow (2) | ✅ Compose'un GraphicsLayerScope'u gibi: ölçek, öteleme, transformOrigin etrafında rotationX/rotationY (3B, Android'in çizdiği gibi cameraDistance × 72 px uzaktaki bir kameradan) ve rotationZ, alfa, shape + clip, blendMode, colorFilter, compositingStrategy (Auto: yalnızca soldurulunca offscreen; Offscreen; ModulateAlpha: her çizim soldurulur, katman yok), outsets, renderEffect (herhangi bir TileMode ile BlurEffect(radiusX, radiusY, edgeTreatment), OffsetEffect; her biri önce içinden geçilecek bir başkasını alır: katmanın sınırları içinde çizilen onun içinden geçer, clip açıksa sonra şekline göre kesilir; GraphicsContext::pushEffectLayer) ve lambdada okunacak size. Yalnızca gereken yerde offscreen (soluk, bir blend modu, bir renk süzgeci, bir render effect, Offscreen); yoksa matris ve clip doğrudan çizime gider (pushTransform, pushClipShape). Lambda sürümü çizimde okunur. ambientShadowColor ve spotShadowColor ile shadowElevation (Compose'unki, bir GraphicsLayer'da da): şeklinin gölgesi (kırpılsın ya da kırpılmasın) önce, onunla birlikte döndürülüp taşınarak çizilir, Android'in bir RenderNode'unkini çizdiği gibi — pencerenin üst ortasının 500 dp yukarısından, 800 dp genişlikte bir ışıkla, ortam gölgesi %3.9, spot gölgesi %19 (GraphicsContext::light, ShadowLight, platform ayarlar), katmanla birlikte soldurulur (alfa 1'in altındaysa altı da görünür), her nokta 3B dönüşünün koyduğu yükseklikte. GPU renderer'ında tek yarıçaplı bir yuvarlak dikdörtgen (bir dikdörtgen, bir daire), düz, bir benzerlik dönüşümüyle, Android GPU'sundaki Skia'nın analitik gölgesi gibi (ortam gölgesi px cinsinden yüksekliğin yarısı kadar, en fazla 150, yayılır; onun 1 + z / 128 katı boyunca exp(−4 (1 − t)²) − 0.018 ile azalır; spot gölgesi ışıktan altındaki düzleme düşürülür; opak bir şeklin altında ikisi de bırakılır); başka bir dış hat, 3B dönüş ya da perspektif Skia'nın bulanıklaştırdığı gibi (dış hat çizilip doldurulur, ışıktan düşürülür, bulanıklaştırılır; perspektifte Skia'nın amaçladığı yönde düşürülür, onun kendi kontrolü bazı şekillerinkini aynalı bırakır); offscreen bir katmanda Android'deki gibi onun px'inde. Başka yerlerde (SDL) bu bulanıklıklar, gölgeleriyle. Modifier.shadow(elevation, shape, clip, ambientColor, spotColor) Compose'unki: bunlarla bir graphicsLayer, yükseklik 0'dan büyükse varsayılan olarak kırpılır (shadow(elevation, cornerRadius) kısaltmadır). SDL_Renderer bir katmanın blend modunu ve renk süzgecini yok sayar |
Modifier.dropShadow, Modifier.innerShadow (Compose 1.9; Shadow(color, offset, blurRadius, spread)) | ✅ şeklin altına (yayılıp kaydırılmış, bulanık) ya da içine (kenarından düşüyormuş gibi) gölge, sonrakilerden önce çizilir; SDL'de bulanık maske CPU'da üç kutu bulanıklığıyla (Skia'nın sigma'sı) her boyut, köşe ve bulanıklık için bir kez yapılır, kullanılmayınca bir saniyede bırakılır; çok büyüğü (4096 px'ten büyük) ve öbür çizim yüzeyleri solan halkalara düşer (iç gölge orada yok). Köşeleri yuvarlak dikdörtgen biçimler (daire, hap) ve dış hatlı şekiller (kalp, kurabiye, GenericShape; SDL'de yol FreeType'la taranıp aynı bulanıklıktan geçer; başka yerlerde, GPU renderer'ında da, Compose'un çizdiği gibi: şeklin altında dış hattı doldurulup yayılmanın iki katı genişlikte çizilir, ikisi ayrı ayrı bulanıklaşıp üst üste biner; içinde, yayılma kadar aşınıp kaydırılmış deliğin bulanığının olmadığı yerde renk — GraphicsContext::drawShadowPath'in varsayılanı, effect katmanlarıyla). brush (gölgenin kapladığı yere yayılır), alpha ve blendMode (Compose 1.9'unkiler; SDL yapabildiği blend modlarını çizer, fırçalı bir gölgeyi de maskesini fırçayla boyayarak); Compose'daki gibi bir dış gölge bitmap'inin bittiği yerde biter (şeklin yarıçapı ve yayılması kadar ötesi, kaydırılmış) |
scale, rotate kısayol modifier'ları | ✅ graphicsLayer kısayolları |
Modifier.zIndex | ✅ kardeşler arasında çizim ve dokunma sırası (eşitler kompozisyon sırasında kalır); özel Layout'ta Placeable::place(x, y, zIndex), ikisi toplanır |
Modifier.dragAndDropSource, Modifier.dragAndDropTarget, DragAndDropTransferData, DragAndDropEvent | ✅ uygulama içinde sürükle-bırak: parmakla uzun basıp sürükleme (farede doğrudan sürükleme), kaynağın soluk kopyası işaretçiyi izler, shouldStartDragAndDrop ile katılan hedefler onStarted/onEntered/onMoved/onExited/onDrop/onEnded alır; metin + MIME türleri + localState (herhangi bir değer); Escape vazgeçer; başlarken dokunsal geri bildirim. Başka uygulamalardan gelen sürükleme de aynı hedeflere gider (masaüstü, SDL'in bırakma olayları): dosya yöneticisinden dosyalar (text/uri-list, yolları files'ta) ya da tarayıcıdan metin (text/plain); SDL ne taşındığını bırakılınca söylediği için hedefler başta ikisine göre sorulur (ComposeHost::externalDragEntered/Moved/Drop/Left). Notlar: uygulamadan dışarı sürükleme yok; Android'de başka uygulamadan sürükleme yok |
Brush (13) gradyanlar | ✅ linear/horizontal/vertical/radial/sweep, renk durakları; background(Brush), drawPath(path, brush) |
onSizeChanged (5), Layout (5) (Measurable/Placeable, layoutId), layout modifier'ı (5) | ✅ |
rememberSnapFlingBehavior, SnapPosition, LazyListOptions::flingBehavior | ✅ LazyRow(…, {.flingBehavior = rememberSnapFlingBehavior(state, SnapPosition::Center)}): sürükleme ya da fırlatma (ve tekerlek) bittiğinde, fırlatmanın varacağı yere (spline decay) en yakın öğe başa/ortaya/sona hizalanarak durur; uzaktaki öğelere de gider. Izgaralarda da: LazyVerticalGrid(…, {.flingBehavior = rememberSnapFlingBehavior(gridState, SnapPosition::Start)}) bir satırı (yatay ızgarada sütunu) hizalayarak durur. Not: pager'da yok (pager zaten sayfaya oturur) |
CenterAlignedTopAppBar, Card(onClick) / ElevatedCard(onClick) / OutlinedCard(onClick), SmallFloatingActionButton / LargeFloatingActionButton, FabPosition | ✅ ortalı başlık çubuğun tamamının ortasında, iki yandaki simgelerin arasına sığacak genişlikte (geniş taraf kadar her iki yandan); kartlar Compose 1.4'teki gibi 12 dp köşeli ve içeriklerini köşelerine kırpar (dolu: surfaceContainerHighest, gölgeli: surfaceContainerLow 1 dp, çizgili: yüzey + 1 dp outlineVariant); tıklanabilir kartların dalgası köşelerine uyar; 40 / 96 dp FAB'ler; ScaffoldSlots::floatingActionButtonPosition: End (varsayılan), Start, Center (alt çubuğun üstünde), EndOverlay (alt çubuğun üstüne binerek) |
TopAppBarSlots::subtitle (M3 Expressive alt başlık) | ✅ başlığın altında, küçük (labelMedium) ve onSurfaceVariant; TopAppBar'da başlıkla birlikte 64 dp'nin ortasında, CenterAlignedTopAppBar'da ikisi de ortada; MediumTopAppBar / LargeTopAppBar onun için 24 dp uzar (136 / 176 dp), alt başlık büyük başlığın altında (labelLarge / titleMedium), çubuk daralırken üst satırda küçük başlıkla birlikte belirir |
MediumFlexibleTopAppBar, LargeFlexibleTopAppBar, TopAppBarSlots::titleHorizontalAlignment, TwoRowsTopAppBar | ✅ M3 Expressive'in esnek çubukları: daha büyük başlık (headlineMedium / displaySmall) ve alt yazı (labelLarge / titleMedium), 112 / 120 dp (alt yazıyla 136 / 152), daralınca 64 dp; titleHorizontalAlignment iki satırlı çubuğun büyük başlığını (ve alt yazısını) başa, ortaya ya da sona koyar, ortalıyken daralmış başlık da ortada (sonda: daralmış olanı başta). TwoRowsTopAppBar(title(bool genişlemiş), slots, modifier, subtitle(bool)): başlık ve alt başlık iki kez çağrılır — büyük satır için true, daralmış üst satır için false — ve çubuğun yazı tipini değil çevredeki metin stilini alır, böylece her satırda kendi boyutunu ya da başka bir metni seçer; gerisi (simgeler, renkler, yükseklikler — varsayılan 112, alt başlıkla 136, daralmış 64 —, hizalama, kaydırma davranışı) slots'tan |
Modifier.pointerHoverIcon (masaüstü), PointerIcon | ✅ pointerHoverIcon(PointerIcon::Hand / Text / Crosshair / Default ya da Cursor::Move, ResizeHorizontal, ResizeVertical, NotAllowed, Wait, overrideDescendants): işaretçinin altındaki en içteki söz geçer (bir simge, tıklanabilirin eli, metin alanının I imleci); overrideDescendants dıştakini içindekilerin üstüne koyar; SDL'in sistem imleçleri (masaüstü, web). Checkbox/TriStateCheckbox/Switch/RadioButton interactionSource alır, RadioButton enabled da. Notlar: özel resimli imleç yok |
Modifier.selectable, toggleable, triStateToggleable, selectableGroup, matchParentSize, fillParentMaxWidth/Height/Size | ✅ selectable(seçili, onClick, SemanticsRole::RadioButton) / toggleable(değer, onValueChange, rol) / triStateToggleable(durum, onClick, rol): anlamsal bilgisiyle (seçili/işaretli, belirsiz) tıklanabilir satır; içindeki RadioButton/Checkbox/TriStateCheckbox/Switch'e geri çağırma vermeyin ({}: Compose'daki onClick = null) — tıklanabilir olmazlar, dokunuşu satır alır. selectableGroup() radyo grubunu işaretler. Box'ta matchParentSize(): diğer çocukların belirlediği boyut kadar, kutuyu büyütmeden (arka plan, örtü). Lazy liste öğesinde fillParentMaxWidth/Height/Size(kesir): listenin görünen alanının (dolgu dışı) kesri; başka yerde fillMax… gibi. selectableGroup Android erişilebilirliğine tek seçimli bir koleksiyon olarak gider (CollectionInfo: seçenek sayısı, yan yanaysa bir satır, değilse bir sütun; her seçeneğe sırası ve seçili olup olmadığı, CollectionItemInfo): TalkBack "4 öğeden 2'si" der |
Modifier.onGloballyPositioned, Modifier.onPlaced, LayoutCoordinates | ✅ düzenden sonra, yeri ya da boyu değişince söylenir (kaydırma da): size(), positionInRoot/InWindow(), positionInParent() (ebeveynin içeriğine göre, kaydırmayla değişmez), boundsInRoot/InWindow() (çevredeki kaydırıcılar ve kırpmalarla — clipToBounds, clip(şekil) — kesilmiş; görünmüyorsa boş), localToRoot, rootToLocal, localToWindow, windowToLocal; zincirdeki yerindeki boyut (padding(10).onGloballyPositioned: içerisi). onPlaced yalnızca boyutu ya da ebeveynindeki yeri değişince. Açılır pencerelerin içeriği de pencereye göre. boundsInParent(), localPositionOf(öbürü, nokta), localBoundingBoxOf(öbürü, clipBounds) (başka bir düğümün noktası/sınırları buradan), parentLayoutCoordinates()/parentCoordinates() (içinde olduğu düğüm, kökün üstü yok; ikisi aynı). Notlar: anlık görüntü (canlı nesne değil); graphicsLayer kaydırma/ölçekleri sayılmaz |
Modifier.onVisibilityChanged, onFirstVisible, LayoutBoundsHolder / Modifier.layoutBounds | ✅ Compose 1.9 gibi: düğümün tamamı (ya da minFractionVisible'dan fazlası) pencerede — ya da {.viewport = holder} ile bir listenin/kutunun alanında — minDurationMs boyunca görünür olunca true; görünmez olunca, düzenden çıkınca ya da kaldırılınca hemen false; onFirstVisible yalnızca ilk sefer (gösterim sayacı). Modifier.onLayoutRectChanged(geri çağrı, throttleMillis = 0, debounceMillis = 64) (Compose 1.8): RelativeLayoutBounds (boundsInRoot, boundsInWindow, positionInWindow(), width()/height(), fractionVisibleInRect(r), fractionVisibleInWindow()) yeri değişince — debounceMillis boyunca kıpırdamayınca bir kez (kaydırma durunca), throttleMillis ile hareket sürerken de en çok o sıklıkta, ikisi de 0'sa her değişimde hemen; düzenden çıkan düğüm bildirilmez |
SubcomposeLayout (subcompose(slotId) { … }) | ✅ ölçüm sırasında yuva istenir: ilk kez istenen (ya da dependency'si değişen) yuva aynı karede kompoze edilip düzen yeniden çalışır (o zamana kadar ölçülecek bir şeyi yoktur); başka yuvanın boyutuna bağlı yuva ya da kısıtlara göre seçilen yuva; artık istenmeyen yuva gider (durumu ve efektleriyle); ön ölçümler (intrinsic) yuvaları değiştirmez. Notlar: içerik sonra, kompozisyonda çalışır (değerle yakalayın); yuva içeriğinin lambda'sı değişince değil, dependency değişince yeniden kompoze olur |
TextStyle (24), FontWeight (26), TextAlign (16), TextOverflow (9), TextDecoration, FontStyle (4), softWrap, TextDirection, autoSize (TextAutoSize.StepBased), letterSpacing, lineHeight, TextAlign.Justify, TextIndent, brush, shadow (Shadow), drawStyle, textGeometricTransform | ✅ textGeometricTransform (TextGeometricTransform(scaleX, skewX); TextStyle ve SpanStyle): glifleri yatayda gerer (ilerlemeleri de: ölçüm, imleç ve seçim ona göre) ve eğer (taban çizgisinden y yukarıdaki nokta y·skewX sağa; SDL'de FreeType dönüşümüyle; renkli emoji olduğu gibi); drawStyle (TextStyle ve SpanStyle; ProvideTextStyle ile içeri geçer): Stroke(genişlik, miter, cap, join) glifleri doldurmak yerine dış hatlarını çizer (genişlik dp, dış hattın iki yanına yarı yarıya, 0 kıl kalınlığında: bir piksel; SDL'de FreeType'ın stroker'ıyla, birleşimi ve miter sınırı join ile miter'dan; renkli emoji olduğu gibi), Fill yeniden doldurur; yol efekti uygulanmaz. Metin gölgesi (bulanık da) dış hattı, gerilmeyi ve eğikliği izler. brush (TextStyle ve SpanStyle): metni rengi yerine boyar, degrade bütün metnin sınırlarına yayılır (SDL'de her glifin köşeleri fırçanın oradaki rengini alır; renkli emoji kendi renginde kalır; bir parçanın kendi color'ı fırçanın üstüne geçer); Shadow(color, offset, blurRadius) (dp; Compose'da piksel): gliflerin altına kaydırılmış, Skia'nın o yarıçap için sigma'sıyla (0,57735 r + 0,5) bulanık kopyası, renkli emojiye gölge yok; FontWeight Compose'daki gibi 1–1000 arası bir sayı (Thin 100 … Normal 400, Medium 500, SemiBold 600, Bold 700 … Black 900; W100…W900, FontWeight{550}): ailenin o ağırlığa CSS'in sırasıyla en yakın dosyası kullanılır (400 önce 500'ü, 500 önce 400'ü dener; hafifler hafife, ağırlar ağıra gider), 600 ve üstü için dosyası 200 ya da daha hafifse Android'deki gibi sentetik kalınlaştırılır; paketteki Noto Sans'ın 400, 500 ve 700'ü var (fonts/Medium.ttf yeni; masaüstünde KOMPOZ_FONT_MEDIUM, Application::mediumFontPath), sistem yazı tiplerinin ağırlığı OS/2 tablosundan; web'de tarayıcının çizdiği yedek metin de o ağırlıkta; italik (yoksa sentetik eğim); TextAlign.Start/End paragrafın yönünü izler, Left/Right izlemez; Justify: sarılan satırlar boşluklarından esneyip genişliği doldurur (paragrafın son satırı ve yönleri karışan satır başta kalır; imleç ve seçim kelimeleri izler); TextIndent(firstLine, restLine) (sp): her paragrafın ilk satırı ve öbür satırları baştan (sağdan solda sağdan) içeri başlar, satır kırma da daralan genişliğe göre (metin alanlarında yok); autoSize: genişliğe, yüksekliğe ve maxLines'a sığan en büyük punto (ikili aramayla, adım adım; AnnotatedString'in kendi boyutları oranında); letterSpacing (sp, SpanStyle'da da; ProvideTextStyle ile içeri geçer; metin alanlarında da): her harfin ardına eklenir, imleç ve seçim ona göre; bitişik ya da satıra asılı yazılarda (Arapça, Devanagari…) Android'deki gibi uygulanmaz; lineHeight (sp, satırdan satıra taban çizgisi): eklenen ya da alınan yeri lineHeightStyle (LineHeightStyle, Compose'daki gibi) paylaştırır — alignment Top (hepsi altta), Center (yarı yarıya), Bottom (hepsi üstte) ya da Proportional (satırın ascent/descent oranında; fontun satır aralığı descent sayılır), trim Both/FirstLineTop/LastLineBottom/None (ilk satırın üstü, son satırın altı fontunki kalsın mı), mode Fixed (her satır tam o kadar) ya da Minimum (fontunkinden kısa olmaz; Tight yok); varsayılanı Compose'unki gibi Proportional + Both (tek satırlı metin aynı kalır); metin alanlarında satırlar o yükseklikte, glifler ortada (lineHeightStyle orada sayılmaz). fontFeatureSettings (TextStyle ve SpanStyle; ProvideTextStyle ile içeri geçer): CSS'in font-feature-settings sözdizimiyle OpenType özellikleri ("smcp", "frac", "tnum", "\"liga\" 0"…), SDL arka ucunda HarfBuzz'a gider (yazı tipinde olanlar etkili; HarfBuzz'sız derlemede ve tarayıcının çizdiği yedek metinde yok); Font::features bir numara (FontFeatures::id/settings); lineBreak (LineBreak, Compose'daki gibi; Unspecified = Simple): Simple her satırı sırayla doldurur, Heading (Strategy::Balanced) satır sayısını artırmadan en dar genişliği bulup satırları eşitler (sonuncusu dahil), Paragraph (Strategy::HighQuality) son satır dışındaki satır sonlarında kalan boşlukların karelerinin toplamını en aza indirir (boşluklardaki bütün kırılma yolları içinden; satırdan uzun kelime varsa eski yol); Strictness ve WordBreak (Çince/Japonca/Korece kuralları) tutulur ama bir şey değiştirmez, tireleme (Hyphens) yok; metin alanlarında yok. fontSize, letterSpacing, lineHeight (TextStyle; SpanStyle'da ilk ikisi) bir TextUnit: düz sayı sp, 1.5_em / TextUnit::em(1.5f) bir yazı boyutunun payı (Compose'un .em'i) — yazı boyutu em'de çevresindekinin (span'ın, metnin, LocalTextStyle'ın) payı, harf aralığı ve satır yüksekliği em'de kendi yazı boyutunun payı; 16_sp de yazılabilir. Not: metin stilindeki em harf aralığı metnin boyutuna göre çözülür, boyutunu değiştiren bir span'da yeniden ölçeklenmez. Material tipografisi (Typography) Material 3'ün tip ölçeğindeki satır yüksekliklerini ve harf aralıklarını taşır (bodyLarge 16/24 sp, 0,5 sp; labelLarge 14/20 sp, 0,1 sp…; LineHeightStyle(Center, Trim.None)): tek satırlık bir Text Compose'daki gibi satır yüksekliği kadar uzun, glifler ortada; Compose'daki gibi fontSize büyütülünce satır yüksekliği kendiliğinden büyümez (lineHeight de verin ya da mode = Minimum). Ağırlıklar Material 3'ünkiler: başlık (title*) ve etiketler (label*) Medium, gerisi Regular; gezinme çubuğu ve rayının etiketleri seçili olsun olmasın labelMedium (seçili olanı rengi ayırır) |
Modifier.basicMarquee (MarqueeAnimationMode, MarqueeSpacing, MarqueeDefaults) | ✅ sığmayan içerik (genişlik sınırı olmadan ölçülür) yerinde kayar, spacing arkasından kopyası gelir; iterations (MarqueeDefaults::Forever), repeatDelayMillis, initialDelayMillis, velocity (eksi: öbür yöne), sağdan solda başlangıcı sağda; WhileFocused yalnızca odaktayken (focusable()'dan önce). Yalnızca çizim kayar (yerleşim ve dokunma yerinde kalır; Compose'daki gibi), kayarken düzen yeniden yapılmaz |
rememberTextMeasurer, TextMeasurer.measure, DrawScope.drawText(TextLayoutResult), Text(onTextLayout = …), TextLayoutResult | ✅ rememberTextMeasurer() bestenin metin stilini ve içerik rengini varsayılan alır; measure(metin ya da AnnotatedString, TextStyle, maxWidth, maxHeight) (satır sayısı, taşma, sarma, hizalama, yön stilden; autoSize hariç). Sonuç: size() (sarılan metin verilen genişlik kadar, değilse en geniş satır), lineCount, hasVisualOverflow/didOverflowWidth/didOverflowHeight (maxLines ya da yükseklik), getLineStart/End/Top/Bottom/Baseline/Left/Right, isLineEllipsized, first/lastBaseline, getLineForOffset, getLineForVerticalPosition, getOffsetForPosition, getBoundingBox, getCursorRect, getSelectionRects. Compose'daki gibi d.drawText(sonuç, renk ya da fırça, solÜst, alpha, shadow, textDecoration, drawStyle, blendMode) (renk ya da fırça metnin kendi stilinin boyadığını boyar, span'ler ve linkler kendilerininkini korur; gölge, süsleme ve çizim stili hiçbir span'in vermediği yere gider), d.drawText(measurer, metin ya da AnnotatedString, solÜst, stil, overflow, softWrap, maxLines, size, blendMode) (bir boyutta: satırlar onun genişliğinde hizalanır). Text(…, stil, onTextLayout) düzen her farklı çıktığında söyler (genişlik düğümünki; "devamını oku"). Notlar: ofsetler UTF-8 bayt; getPathForRange yerine dikdörtgenler |
AnnotatedString/SpanStyle (6/3), LinkAnnotation (Url, Clickable), TextLinkStyles, BaselineShift, minLines, TextOverflow.StartEllipsis/MiddleEllipsis, InlineTextContent, appendInlineContent, AnnotatedString.fromHtml | ✅ buildAnnotatedString, iç içe withStyle; ParagraphStyle (withStyle(ParagraphStyle{…}, …), addStyle, pushStyle; textAlign, textDirection, lineHeight, lineHeightStyle, textIndent, lineBreak): aralığı kendi paragrafı olur (önünde ve ardında satır kırılır), ayarları metninkinin yerine geçer, iç içe olanlarda içteki kazanır, satır yüksekliği kırpması her bloğun kendi ilk ve son satırında; Compose'un pushStyle/pop()/pop(index) (açık kalanlar metnin sonunda kapanır) ve dize açıklamaları (addStringAnnotation, pushStringAnnotation, withAnnotation; getStringAnnotations(etiket, başlangıç, son) — bir konum çevresindekileri bulur, ucundakini değil — ve hasStringAnnotations); tıklanabilir withLink(onClick) ve withLink(LinkAnnotation): Url dinleyici yoksa platformda açılır (uriHandler), Clickable dinleyicisini etiketle çağırır; altı çizili ve ana renkte, üstüne TextLinkStyles'ın style'ı, fare üzerindeyken hoveredStyle, basılıyken pressedStyle (fare üzerindeyken el imleci), odaktayken focusedStyle: her bağlantının ilk satırının üstünde kendi düğümü var (Compose'un TextLinkScope'u gibi) — Tab bağlantıdan bağlantıya geçer, Shift+Tab geri, Enter açar; erişilebilirlik servislerine bağlantı metniyle tıklanabilir ayrı bir düğüm olarak görünür ve onların tıklaması açar; birden çok satıra yayılan bağlantının öbür satırlarına dokunmak da açar (o satırlar metnin kendisinde). SpanStyle.baselineShift (BaselineShift::Superscript/Subscript = yükseltisinin yarısı yukarı/aşağı) satırı o yana büyütür. minLines: metin en az o kadar satır (boşları stilin satır yüksekliğinde). StartEllipsis/MiddleEllipsis tek satırda (maxLines = 1 ya da softWrap = false) başını ya da ortasını keser, çok satırda kırpar (Android'deki gibi). Metin içi bileşenler: b.appendInlineContent(id, yedekMetin) (yedek varsayılan U+FFFD) ve Text(metin, modifier, stil, {{id, InlineTextContent{Placeholder{genişlik, yükseklik, hiza}, [](const std::string& yedek) {…}}}}): metin her biri için Placeholder boyutunda yer ayırır (sp, ya da em — oradaki yazı boyutunun payı; sp'ler sistem yazı ölçeğiyle büyür), bileşen o yere tam o boyutta yerleşir ve yedek metni alır (yedek metin çizilmez; haritada olmayan kimliğin yedek metni görünür); PlaceholderVerticalAlign: AboveBaseline (altı taban çizgisinde), TextTop/TextBottom (üstü/altı metninkiyle), TextCenter (metnin ortasında); Top/Bottom/Center burada Text* gibi; satır yer gerektirdiği kadar büyür (en az metnin kendisi kadar; Compose'daki gibi lineHeight Fixed modda büyümez), yer hiç bölünmez (satırdan genişse de, yedek metnindeki boşlukta da, iki yönlü satırda da); maxLines'ı aşan yerdeki bileşen yerleşmez. AnnotatedString::fromHtml(html, linkStyles, dinleyici) (Compose 1.7; Android'in Html'inin kompakt kipindeki etiketler): <b>/<strong>, <i>/<em>, <u>, <s>/<del>, <sup>/<sub>, <big>/<small>, <tt>/<code> (eş aralıklı), <h1>–<h6> (kalın, 1,5–1 em), <font color>, <span style> (color, background-color, font-weight, font-style, text-decoration), <a href> (LinkAnnotation::Url, linkStyles ile), <br>; <p>, <div>, <ul>/<li> (•), <blockquote>, <pre> (boşluklar korunur) kendi satırlarında; varlıklar (&, ü, ç, ©…); boşluklar HTML'deki gibi tek boşluğa iner; tanımadığı etiketler atlanır, metinleri kalır; geç kapanan etiket içindekileri de kapatır |
FontFamily (17), FontVariation | ✅ Default/SansSerif/Serif/Monospace (sistem fontları) + FontFamily::fromFiles; eksik kalınlık/italik sentezlenir. Değişken yazı tipleri: FontFile'ın variationSettings'i (FontVariation::weight(650), width, slant, italic, grade, opticalSizing, {"XXXX", değer} ile yazı tipinin kendi ekseni; FontVariation::settings(ağırlık, stil, ...) wght ve ital'i ağırlıktan ve stilden) o örneği seçer: aynı dosya ailede birkaç ağırlık olarak gelebilir (SDL'de her örnek ayrı bir FreeType yüzü, FT_Set_Var_Design_Coordinates ile; HarfBuzz da onu şekillendirir) |
| Yedek fontlar (semboller, emoji, CJK) | ✅ eksik glifler sistem yedek zincirinden; renkli emoji: CBDT (FreeType), COLRv0 (FreeType), Android COLRv1 (Android metin yığını) |
| Emoji dizileri (ZWJ, bayraklar, ten rengi, keycap, etiket dizileri) | ✅ tek glif (fontun kendi ligatürü; Android'de renkli emoji fontları platformun metin yığınıyla); imleç, silme ve satır kırma bütün grafem kümesini birlikte taşır |
| Metin şekillendirme (shaping) ve sağdan sola yazı | ✅ bütün metin HarfBuzz ile (masaüstü ve Android): kerning, ligatürler, Arapça harf birleşmesi, Hint yazıları (Devanagari…); basitleştirilmiş Unicode bidi (UAX #9; yalıtımlar ve parantez çiftleri var, gömme/zorlama yok): parantez çifti ((), [], {}, 〈〉, 「」… Unicode'un eşli parantezleri; BD16'daki gibi 63'lük yığınla, kapanan parantez içinde açık kalanları da kapatır) içindeki metin seviyenin yönündeyse o yöne, yalnızca öbür yöndeyse ve çiftten önceki metin de o yöndeyse öbür yöne gider (N0; sayılar sağdan sola sayılır) — Türkçe cümlede Arapçadan sonra parantez içindeki Arapça kelimenin kapanan parantezi dışarıda kalmaz; yalıtım (LRI U+2066, RLI U+2067, FSI U+2068 … PDI U+2069) içinde kendi yönünde (FSI içindeki ilk güçlü harfe göre) bir üst seviyede çözülür, dışarıda tek bir nötr sayılır — Türkçe cümledeki Arapça isimden sonraki sayı isme katılmaz; kapanmayan yalıtım satır sonuna dek sürer, iç içe olabilir, paragrafın yönünü yalıtımın içi belirlemez; paragrafın yönü ilk güçlü harften (TextDirection.Content), satır içi yön koşuları, Arapçadan sonra rakamlar; imleç, dokunma, seçim ve metin alanları sağdan sola metinde doğru yerde. Biçimi değişen parçalar (AnnotatedString'in kalın kelimesi, bağlantısı…) satırla birlikte sıralanır: satırın tek yönlü kesimlerinde bölünüp ekran sırasına konur, her biri kendi kesiminin yönünde çizilir; imleç, seçim ve dokunma onları izler. Çok satırlı metin alanında her paragraf kendi ilk harfine göre yönlenir (Türkçe paragraf soldan, Arapça sağdan; hizası, imleç, dokunma ve seçim de); tek satırlı alan tümüyle tek yönlü |
sp (41), LocalDensity (16) | ✅ Android sistem yazı boyutu (çalışırken değişince de) |
onKeyEvent/onPreviewKeyEvent (3/6) | ✅ KeyEvent (KeyDown/KeyUp, Ctrl/Shift/Alt); sıra: preview dıştan içe → metin alanı → onKeyEvent içten dışa |
semantics (9) ve erişilebilirlik | ✅ Modifier.semantics({contentDescription, role, checked, stateDescription, heading}), tıklanabilir düğümler içeriklerini birleştirir; {.mergeDescendants = true} (bir satırın ikonu ve metinleri tek parça okunur, içindeki düğmeler ayrı kalır), clearAndSetSemantics({...}) (içindekiler hiç okunmaz — düğmeleri de —, düğüm yalnızca verileni söyler: beş yıldız → "Puan: 4 / 5"), hideFromAccessibility() (kendisi de içindekiler de ağaçtan çıkar); bir düğümdeki birden çok semantics birleşir (toggleable'ın rolü/durumu + sonradan verilen açıklama). Android'de AccessibilityNodeProvider (TalkBack, UI Automator), tıklama/odak/kaydırma eylemleri. Linux'ta, masaüstünün erişilebilirliği açıkken ya da KOMPOZ_ATSPI=1 ile AT-SPI (Orca, Accerciser): roller, adlar, durumlar, konumlar, eylemler (tıklama, kaydırma, özel eylemler), değerler (kaydırıcınınki, ayarlanabilir), metin (metin alanınınki, ayarlanabilir; parolanınki nokta olarak) ve odak, durum, ad, yazılan metin, değer, çocuk ve canlı bölge (duyuru) olayları. Windows'ta UI Automation (Ekran Okuyucusu, NVDA): denetim türleri, adlar, durumlar, sınır dikdörtgenleri, Invoke, Toggle, SelectionItem, Value, RangeValue ve Scroll desenleri, odak ve odak, özellik, yapı ve canlı bölge olayları (özel eylemler yok: UI Automation'da yoklar). progressBarRangeInfo (ProgressBarRangeInfo{current, rangeStart, rangeEnd, steps}, ::Indeterminate; Slider ve ilerleme göstergeleri — dalgalılar dahil — verir) ve setProgress (kaydırıcının değerini erişilebilirlik servisi ayarlar, adımlarına oturur; Android'de RangeInfo ve ACTION_SET_PROGRESS: TalkBack yüzde söyler, ses tuşlarıyla değiştirir), liveRegion (LiveRegionMode::Polite/Assertive: metni değişince odak kaymadan okunur), customActions ({"Arşivle", [] { …; return true; }}: TalkBack'in eylemler menüsünde), traversalIndex (anlamsal ebeveyninin düğümleri arasında küçük önce okunur) Modifier.progressSemantics(değer, başlangıç, bitiş, adım) (değer aralığa sıkıştırılır) ve progressSemantics() (belirsiz) |
ui.test (41) | ✅ ComposeTestRule: onNodeWithText/Tag/ContentDescription, onAllNodesWith… + assertCountEquals; assertExists/DoesNotExist/IsDisplayed/TextEquals/TextContains/HasClickAction/IsEnabled/IsSelected/IsOn…; performClick/TextInput/Key/ScrollTo; başarısızlıkta AssertionError |
Yapılan sıra
- Akıllı recomposition +
recomposeHighlighter✅ LazyColumn/LazyRow+items✅Icon+IconButtonve 35 Material ikonu ✅- Coroutine'ler,
Animatable,tween/spring, ilerleme göstergeleri ✅ Scaffold+TopAppBar+NavigationBar+FloatingActionButton+Snackbar✅Image+ContentScale,Shape+clip,alpha✅AnimatedVisibility/AnimatedContent/Crossfade✅derivedStateOf,mutableStateListOf,rememberUpdatedState,produceState✅Canvas/drawBehind/drawWithContent,aspectRatio,wrapContentSize,requiredSize,graphicsLayer+scaleIn/scaleOut,pointerInput+detectTapGestures/detectDragGestures,combinedClickable✅Brushgradyanları,Path(dolgu/çizgi),drawWithCache✅- Material bileşenleri:
ListItem, chip'ler,RadioButton,Slider,SegmentedButton, sekmeler,Badge, buton/kart çeşitleri,BottomAppBar✅ Popup,Dialog/AlertDialog,DropdownMenu,ModalBottomSheet,BackHandler(Android geri tuşu dahil) ✅LazyVerticalGrid,HorizontalPager,BoxWithConstraints,onSizeChanged,animateContentSize✅- Odak ve metin girişi:
FocusRequester,FocusManager,onFocusChanged,KeyboardOptions/KeyboardActions, filled/outlinedTextField✅ ModalNavigationDrawer,NavigationRail,LocalWindowSize✅Layout,Modifier.layout,layoutId,IntrinsicSize,FlowRow/FlowColumn,updateTransition✅AnnotatedString/SpanStyle/link, italik,TextOverflow/softWrap,LocalDensity+ sistem yazı ölçeği ✅FontFamily+ glif yedekleme (semboller, renkli emoji, CJK) ✅animateItem,SwipeToDismissBox,draggable✅- Erişilebilirlik: semantik ağaç + Android AccessibilityNodeProvider ✅
nestedScroll,VerticalPager,TopAppBarkaydırma davranışları,MediumTopAppBar/LargeTopAppBar✅- Dinamik renk (Material You):
dynamicLightColorScheme/dynamicDarkColorScheme;Switch/Checkboxenabled✅ WindowInsetstürleri,windowInsetsPadding/imePadding/consumeWindowInsets,SystemBarsAppearance✅- Klavye ve odak:
focusable,onKeyEvent/onPreviewKeyEvent, yönlü odak, bring-into-view (klavye açılınca da) ✅ - Çok satırlı
TextField/OutlinedTextFieldverememberTextFieldState✅ - Çoklu dokunma:
detectTransformGestures,transformable✅ PullToRefreshBox✅stickyHeader✅SearchBar,BasicTextField✅DatePicker,DatePickerDialog✅TimePicker,TimeInput,TimePickerDialog✅DateRangePicker✅DockedSearchBar✅TooltipBox,PlainTooltip,RichTooltip✅ExposedDropdownMenuBox✅RangeSlider✅SecondaryTabRow,PrimaryScrollableTabRow,SecondaryScrollableTabRow✅LazyHorizontalGrid,LazyVerticalStaggeredGrid✅Modifier.scrollable,scale/rotate,mutableIntStateOfve benzerleri ✅PermanentNavigationDrawer,DismissibleNavigationDrawer✅snapshotFlow✅- Dokunmatik metin seçimi (tutamaçlar, araç çubuğu) ✅
sizeIn,defaultMinSize✅- Test doğrulamaları (
assertIsDisplayed,assertTextEquals,onAllNodesWithText,performScrollTo…) ✅ - İmleç tutamacı, parmak/fare ayrımı, fareyle çift tıklayınca kelime seçimi ✅
SelectionContainer✅- Emoji dizileri: grafem kümeleri, HarfBuzz ✅
- Metinler arası seçim, fareyle seçim,
DisableSelection✅ StateFlow,MutableStateFlow,collectAsState✅- Bütün metinde HarfBuzz shaping, sağdan sola metin (bidi),
TextDirection✅ SharedTransitionLayout,sharedElement,sharedBounds✅- Overscroll esnemesi ✅
- Web (Emscripten) ve Windows (MinGW) derlemeleri ✅
- Web'de yedek fontlar: eksik karakterleri tarayıcı çizer ✅
- Android'de akıcılık: ekran dışı katmanlar çizilmez, katman dokuları ve yollar her karede yeniden yaratılmaz, debug APK'da da optimize native kod,
KOMPOZ_PROFILE✅ - Fare/touchpad ile yakınlaştırma, kaydırmadan sıkıştırmaya geçiş ✅
- Navigation:
NavHost,NavController, rotalar ve argümanlar,rememberSaveable✅ viewModel()(gezinme girdisine ya da uygulamaya bağlı), LazyColumn öğelerinderememberSaveable✅- İç içe gezinme grafikleri (
navigation()), grafiğe bağlı ViewModel'ler ✅ - Yalnızca değişen bölgeyi yeniden çizme (
DisplayList: kareler kaydedilir, düğüm düğüm karşılaştırılır; ekranda değişiklik yoksa kare gösterilmez),KOMPOZ_DAMAGE_SHOW/KOMPOZ_DAMAGE_CHECK/KOMPOZ_FULL_REDRAW✅ - Derin bağlantılar (
navDeepLink; masaüstü komut satırı, web#adresi, Android intent'i) ✅ - Tür güvenli rotalar (
KOMPOZ_ROUTE,composable<T>,navigate(T{…}),toRoute<T>()) ✅ - Soğuk
Flowve operatörleri (map,filter,take,debounce,flatMapLatest,combine,stateIn…) ✅ animateItem: çıkarılan öğe yerinde solar (fadeOutSpec,Composer::keepGroup) ✅AsyncImage: JPEG/WebP ve ağdan resim, her platformun kendi çözücüsüyle; bellek önbelleği ✅rememberSaveablesüreç ölümünden sonra da (Saver,SavedValue, Android'de saved instance state,KOMPOZ_STATE_FILE) ✅SharedFlow/MutableSharedFlow,shareIn,SharingStarted(WhileSubscribed) ✅- Resimler için disk önbelleği ve yerleşim boyutunda çözme (
DiskCache,ImageRequestSize,imageSampleSize) ✅ - Platform servisleri:
uriHandler,softwareKeyboardController,hapticFeedback,clipboardManager✅ reverseLayout,animateScrollToItem,ScrollState::animateScrollTo✅Modifier.zIndex(vePlaceable::place(x, y, zIndex)) ✅BottomSheetScaffold✅- Sürükle-bırak (
dragAndDropSource/dragAndDropTarget) ✅ - Uygulama dışından sürükle-bırak: dosya ve metin bırakma (masaüstü) ✅
- Uyarlanabilir düzen:
WindowSizeClass,currentWindowAdaptiveInfo,NavigationSuiteScaffold✅ SavedStateHandle: ViewModel durumu süreç ölümünden sonra da ✅Carousel(çoklu göz atma ve sınırsız) ✅TriStateCheckbox, metinautoSize✅SubcomposeLayout✅- Lifecycle:
LocalLifecycleOwner, yaşam döngüsü efektleri,collectAsStateWithLifecycle, gezinme girdilerinin yaşam döngüsü ✅ InteractionSource: basma/hover/odak/sürükleme etkileşimleri,hoverable,indication = null✅anchoredDraggable,AnchoredDraggableState,DraggableAnchors✅- Ripple:
ripple(),Indication,LocalIndication✅ LazyListState.layoutInfo(visibleItemsInfo),contentType✅rememberTextMeasurer,TextLayoutResult,drawText,onTextLayout✅- Hızlı animasyonlar:
animateDecay, başlangıç hızlı yay,updateBounds,VelocityTracker, sürüklemenin bırakış hızı ✅ keyframes, durumlara bağlıtransitionSpec,SizeTransform✅onGloballyPositioned,onPlaced,LayoutCoordinates✅selectable,toggleable,triStateToggleable,selectableGroup,matchParentSize,fillParentMax*✅SnackbarResult: beklenebilirshowSnackbarAsync, kapatma düğmesi ✅rememberModalBottomSheetState: yarı açık sayfa,show/hide/expand/partialExpand✅pointerHoverIcon, seçim kontrollerineinteractionSource✅CenterAlignedTopAppBar, tıklanabilir kartlar, küçük/büyük FAB,FabPosition✅rememberSnapFlingBehavior(öğeye oturan listeler) ✅Modifier.indication(source, indication)✅IconToggleButtonailesi,OutlinedIconButton✅Slider/RangeSliderinteractionSource✅TextFieldprefix/suffix✅AnimatedContentcontentAlignment,contentKey✅Modifier.animateEnterExit,EnterTransition::None/ExitTransition::None✅semantics(mergeDescendants),clearAndSetSemantics,hideFromAccessibility✅TextFieldStateseçimi veedit { }(TextFieldBuffer),InputTransformation(maxLength,allCaps,byValue,then) ✅OutputTransformation(gösterim biçimlendirme, imleç eşlemesi) ✅TextFieldState.undoState(geri al/yinele, Ctrl+Z) ✅Modifier.focusProperties(canFocus,next/previous/up/down/left/right,FocusRequester::cancel()) ✅LocalLayoutDirection(sağdan sola yerleşim),absoluteOffset,absolutePadding✅- RTL'de
Slider/RangeSlider/Switchaynalama,Icons::AutoMirrored✅ - Sistem dilinden RTL (
ComposeHost::setLayoutDirection,isRtlLanguage), açılır menü RTL hizası ✅ LazyGridState(öğe dizinli konum,scrollToItem,layoutInfosatır/sütun) ✅ProvideTextStyle; yönü olmayan metin (rakamlar) düzen yönünü izler ✅MultiChoiceSegmentedButtonRow,SegmentedButton(checked, onCheckedChange),SegmentedButtonOptions✅LazyStaggeredGridState(öğe dizinli konum,scrollToItem,layoutInfoşeritleri) ✅ListDetailPaneScaffold(tek/iki bölme, gezgin, geri tuşu) ✅LinearWavyProgressIndicator/CircularWavyProgressIndicator(dalgalı ilerleme) ✅ToggleButtonailesi veButtonShapes(dönüşen köşeler),RoundedCornerShapePercent,lerp(Shape)✅ButtonGroup(basılan genişler, komşular sıkışır), esneyen düğme iç boşluğu ✅- Köşeleri kendine ait şekiller (
RoundedCornerShape(4 köşe),CornerSize,CornerRadii), RTL'de aynalanır ✅ - Bağlı düğme grubu şekilleri (
ButtonGroupDefaults::connected…ButtonShapes), köşe köşe dönüşüm ✅ SplitButtonLayoutveSplitButtonDefaultsdüğmeleri (bölünmüş düğme) ✅ToggleFloatingActionButtonveFloatingActionButtonMenu(FAB menüsü) ✅HorizontalFloatingToolbar/VerticalFloatingToolbar(yüzen araç çubuğu, kaydırınca çekilir) ✅LoadingIndicator/ContainedLoadingIndicator(dönen ve biçim değiştiren yükleme göstergesi) ✅ShortNavigationBar/ShortNavigationBarItem(eşit paylaşım ya da ortada, yatay öğeler) ✅WideNavigationRail/WideNavigationRailItem(açılıp kapanan geniş ray) ✅SupportingPaneScaffold(ana + destek bölmesi, gezgin) ✅HorizontalCenteredHeroCarousel(ortada büyük öğeli karusel) ✅ModalWideNavigationRail(içeriğin üstünde açılan geniş ray) ✅- M3 Expressive FAB boyları:
MediumFloatingActionButton,Small/Medium/LargeExtendedFloatingActionButton(expandedile daralır) ✅ - Üst uygulama çubuklarında alt başlık (
TopAppBarSlots::subtitle) ✅ FlexibleBottomAppBarve alt çubuklarınexitAlwaysScrollBehavior'ı ✅VerticalSlider✅CarouselItemScope/carouselItemInfo(öğe boyunu çizerken okuma) ✅ButtonGroupöğelerden, sığmayanlar ⋮ menüsüne ✅Switchbaşparmağında simge (thumbContent), basılıyken büyüyen başparmak ✅- İpucu oku (
PlainTooltip/RichTooltipcaretSize): çapaya bakan, kenarda da onu gösteren üçgen ✅ SecureTextField/OutlinedSecureTextField(TextObfuscationMode: son yazılanı bir an gösteren, gizli, görünür) ✅ElevatedAssistChip/ElevatedSuggestionChip/ElevatedFilterChip,LeadingIconTab✅- Bölme genişliğini sürükleme:
PaneExpansionState/PaneExpansionAnchor,paneExpansionDraggable,VerticalDragHandle✅ - M3 Expressive menüler:
DropdownMenuPopup,DropdownMenuGroup,MenuDefaults::groupShape/itemShape, işaretli/seçiliDropdownMenuItem,supportingText✅ SearchBarState(rememberSearchBarState,animateToExpanded/Collapsed,snapTo),InputField(state, TextFieldState),SearchBar(state),ExpandedFullScreenSearchBar,ExpandedDockedSearchBar✅AppBarWithSearch(üst çubukta arama, gezinme simgesi ve eylemler) veSearchBarDefaults::enterAlwaysSearchBarScrollBehavior✅- Her biçimde şekil:
ShapeOutline/OutlineShape(arka plan, çerçeve, gölge, kırpma, graphicsLayer kırpması, dalga) ✅ MaterialShapes(35 şekil),roundedPolygon/roundedStar,Morph(şekilden şekle geçiş) ✅- Masaüstü kaydırma çubukları:
VerticalScrollbar/HorizontalScrollbar,rememberScrollbarAdapter(ScrollState,LazyListState),LocalScrollbarStyle✅ - Sağ tık menüleri:
ContextMenuArea, metin alanlarında Kes/Kopyala/Yapıştır/Tümünü seç (ComposeHost::secondaryClick) ✅ - Pencere menü çubuğu ve kısayollar:
MenuBar,KeyShortcut,ComposeHost::addKeyHandler✅ Modifier.basicMarquee(kayan yazı);DrawScope.translateiçindekidrawContent()'i de kaydırır (katmansız öteleme:GraphicsContext::pushTranslation) ✅TextStyle.letterSpacing/SpanStyle.letterSpacing,TextStyle.lineHeight✅TextAlign.Justify(iki yana yaslama),TextStyle.textIndent(TextIndent) ✅- Degrade metin (
TextStyle.brush,SpanStyle.brush) ve metin gölgesi (Shadow, bulanık) ✅ PathEffect(kesikli ve köşeleri yuvarlak çizgiler),drawPoints,PathMeasure✅- Masaüstü fare:
Modifier.onPointerEvent,Modifier.onClick(tuş ve klavye eşleme),TooltipArea✅ ColorFilter(tintveBlendMode,colorMatrix,lighting) veColorMatrix; resimlerde gri ton, sepya, renklendirme ✅Modifier.dropShadow/Modifier.innerShadow(gerçek bulanıklık, yayılma, kaydırma, renk) ✅LinkAnnotation(Url,Clickable) veTextLinkStyles(üzerinde/basılıyken), üst/alt simge (BaselineShift),minLines,TextOverflow.StartEllipsis/MiddleEllipsis✅Sliderbaşparmak ve iz yuvaları, hazır başparmaklar (daire, M3 çubuk, biçim, simge, değer), Material 3 izi,SliderState,SliderColors✅RangeSliderbaşparmak ve iz yuvaları,RangeSliderState(rememberRangeSliderState), aralık için Material 3 izi ✅Modifier.animateBoundsveLookaheadScope(yeri ve boyutu değişen öğe kayarak gider) ✅- Değer balonu (
Label,SliderDefaults::Label) ve 48 dp dokunma alanı (minimumInteractiveComponentSize) ✅ Modifier.pullToRefresh,PullToRefreshDefaults.IndicatorBox, oklu yay göstergesi ✅IconButton,Checkbox,RadioButton,Switchiçin 48 dp dokunma alanı; sınırsız dalganın üzerine gelme/odak katmanı daire ✅Button,ToggleButton,SplitButton, çipler veSmallFloatingActionButtoniçin 48 dp dokunma alanı ✅SegmentedButtonsatırına 48 dp dokunma alanı ✅- Üst çubuk renkleri (
navigationIconContentColor,titleContentColor,actionIconContentColor,subtitleContentColor),expandedHeight/collapsedHeight,windowInsets✅ BasicAlertDialog,AlertDialogrenkleri/şekli/modifier'ı ve sarılan butonları,DialogProperties::usePlatformDefaultWidth✅Channel(rendezvous/tamponlu/conflated, taşma politikaları),produce,consumeEach,receiveAsFlow✅PathEffect.stampedPathEffect(Translate/Rotate/Morph) ✅TextStyle.lineBreak(LineBreak::Simple/Heading(dengeli) /Paragraph(en az dengesiz satır sonları)) ✅- Bağlantılar klavye odağı ve erişilebilirlik tıklaması alır (
TextLinkStyles.focusedStyle) ✅ fontFeatureSettings(OpenType özellikleri HarfBuzz'a) ✅TextUnit:embirimiyle yazı boyutu, harf aralığı ve satır yüksekliği ✅PointerEventPass(awaitPointerEvent(Initial / Main / Final)) ✅Path.op(PathOperation: birleşim, kesişim, fark, ters fark, xor),Path::contains✅movableContentOf(MovableContent): durumu, düğümleri ve efektleriyle yer değiştiren içerik ✅- Çizimde
BlendMode(drawRect/drawRoundRect/drawCircle/drawPath'inblendMode'u),CompositingStrategy.Offscreen✅ Modifier.blur(BlurredEdgeTreatment.Rectangle/Unbounded) ✅- Çift yönlü metinde yalıtımlar (LRI, RLI, FSI … PDI) ✅
- Dış hatlı şekillerin gölgeleri (
dropShadow/innerShadowkalp, kurabiye,GenericShapeiçin) ✅ - Material tip ölçeğinde satır yükseklikleri ve harf aralıkları,
LineHeightStyle(hizalama, kırpma,Minimum), metin alanlarında satır yüksekliği ✅ - Sayısal
FontWeight(100–900, CSS'in en yakın dosya seçimi, Android'in sentetik kalınlığı), paketli Noto Sans Medium, Material 3 ağırlıkları ✅ - Çift yönlü metinde parantez çiftleri (UAX #9 BD16 + N0) ✅
- Biçimli çift yönlü metin satırla birlikte sıralanır (parçalar yön kesimlerinde bölünür, ekran sırasında çizilir) ✅
LazyHorizontalStaggeredGrid✅Painter(BitmapPainter,VectorPainter,ColorPainter,BrushPainter, özel),Modifier.paint,Image(painter),Icon(painter),painterResource✅Modifier.draggable2D,Draggable2DState✅Modifier.focusGroup(ok tuşları önce grubun içinde, dışarıdan grup tek hedef) ✅Modifier.scrollable2D,Scrollable2DState✅- Büyüteç: metin tutamaçlarında Android'in metin büyüteci,
Modifier.magnifier✅ ContentTransform::targetContentZIndex, NavHost'ta ileri/geri z sırası ✅LayoutCoordinates:parentLayoutCoordinates,localPositionOf,localBoundingBoxOf,boundsInParent✅- Izgaralarda snap fling (
rememberSnapFlingBehavior(LazyGridState)) ✅ rememberGraphicsLayer(record,drawLayer,toImageBitmap) ✅MediumFlexibleTopAppBar,LargeFlexibleTopAppBar,titleHorizontalAlignment✅rememberAsyncImagePainter(Painter olarak) ✅LocalOverscrollFactory(esnemeyi kapatmak) ✅- Çok satırlı metin alanında paragraf başına yön ✅
sharedBoundsiçinSharedResizeMode(scaleToBounds, remeasureToBounds) ✅- AnnotatedString.Builder:
pushStyle/pop, dize açıklamaları (getStringAnnotations) ✅ ParagraphStyle(paragraf başına hiza, yön, girinti, satır yüksekliği, satır kırma) ✅BasicText,BasicSecureTextField✅TextFieldColors(TextFieldOptions::colors),TextSelectionColors/LocalTextSelectionColors✅TextField(enabled = false), devre dışıTextFieldColors✅TextFieldshape(dolgulu alanın varsayılanı yalnızca üst köşeler) ✅KeyboardOptions::showKeyboardOnFocus✅- Hizalama çizgileri:
alignByBaseline,alignBy,paddingFromBaseline,placeable[FirstBaseline]✅ Snackbarcomposable'ları (actionOnNewLine, renkler),SnackbarHostözel snackbar,SnackbarData::performAction/dismiss✅TextFieldLabelPosition(Attached(alwaysMinimize),Above(hizalama)) ✅BringIntoViewRequester✅windowInsetsTopHeight/BottomHeight/StartWidth/EndWidth✅Modifier.focusRestorer,focusTarget✅onVisibilityChanged,onFirstVisible,layoutBounds✅DatePickergiriş modu (DisplayMode,DateInput) ✅DateRangePickergiriş modu (DateRangeInput) ✅AppBarRow(taşma menüsü) ✅- Etkileşimli
ListItem(tıklanır/seçilir/işaretlenir, şekil biçim değiştirir),SegmentedListItem✅ AppBarColumn✅- Gerçek
width(IntrinsicSize::Min)(en geniş kelime) ✅ InlineTextContent,appendInlineContent(metin içi bileşenler) ✅- Pager:
PageSize,snapPosition,PagerSnapDistance,settledPage/targetPage,getOffsetDistanceInPages, çapraz hizalama ✅ MutableTransitionState,rememberTransition,AnimatedVisibility(visibleState)✅TextFieldLineLimits,BasicTextFielddecorator(decorationBox) ✅compositionLocalOf/staticCompositionLocalOf(tembel varsayılan),providesDefault,CompositionLocalContext✅MotionScheme(standard/expressive),MaterialExpressiveTheme✅- Pager
reverseLayoutve sayfakey'i ✅ TwoRowsTopAppBar✅mutableStateMapOf✅- Android'in fırlatma eğrisi (spline decay) ✅
- Gözlenebilir
ScrollState.value,canScrollForward/Backward,isScrollInProgress(kaydırma ve tembel durumlar) ✅ userScrollEnabled,verticalScroll(enabled, reverseScrolling)✅- Tembel listelerde
Arrangement(verticalArrangement/horizontalArrangement) ✅ Path.arcTo/addArc/addPath/translate,DrawScope.drawOval/clipPath/withTransform✅BorderStroke(fırçalı kenarlık), renkli ve kırpanshadow✅Clipboard/ClipEntry(LocalClipboard) ✅AnnotatedString.fromHtml✅detectDragGesturesAfterLongPress✅TaskOf<T>(değer döndüren eşyordamlar),withBackground(arka plan iş parçacığı) ✅awaitEachGesture,awaitFirstDown,waitForUpOrCancellation✅LocalWindowInfo(isWindowFocused,containerSize) ✅SwipeToDismissBoxfırlatmayla kapanma, sayfaların bırakış hızıyla oturması ✅PredictiveBackHandler,BackEventCompat; Android 13+OnBackInvokedCallback(14+ hareket adımları, sistemin ana ekrana dön animasyonu) ✅- Popup'ların kendi geri kapsamı (içindeki
BackHandler'lar önce),ModalBottomSheetgeri hareketi (M3: küçülür, bitince gizlenir ya da yarıya iner) ✅ - Drawer'ların geri hareketi (M3:
ModalDrawerSheet/DismissibleDrawerSheetgenişler ya da daralır, alçalır, bitince kapanır) ✅ NavHostgeri hareketi (alttaki ekran pop geçişiyle hareket kadar görünür;AnimatedContentOptions::seekState/seekFraction, Compose'unSeekableTransitionState.seekTo'su) ✅ExpandedFullScreenSearchBarçubuktan büyüyerek açılır (M3) ve geri hareketini izler ✅LocalViewConfiguration(Android'in kendi eşikleri;PointerInputScope::viewConfiguration()) ✅- Semantik:
progressBarRangeInfo/setProgress,liveRegion,customActions,traversalIndex(Android köprüsüyle) ✅ Modifier.onLayoutRectChanged(RelativeLayoutBounds, throttle/debounce) ✅TooltipAnchorPosition,TooltipPositionProvider(rememberTooltipPositionProvider), yan oklar ✅Modifier.systemGestureExclusion(Android'in kenar hareketlerinden ayrılan alanlar) ✅- En küçük dokunma hedefi: küçük hedefler yakınlarındaki dokunuşları alır (
extendedTouchPadding) ✅ - Degradelerde
TileMode(Clamp, Repeated, Mirror, Decal) ✅ TopSearchBar,rememberBottomAppBarState/exitAlwaysScrollBehavior(state)(M3 1.4'ün son eksikleri) ✅Modifier.keepScreenOn(ve ekranın varsayılan olarak kararabilmesi) ✅Modifier.onFocusEvent,Modifier.progressSemantics✅- Kaydırılan kaplar yalnızca kaydırma ekseninde kırpar, çapraz eksende 30 dp pay bırakır (Compose'un
clipScrollableContainer'ı: kart gölgeleri görünür) ✅ Modifier.sensitiveContent(Android 15+ ekran paylaşımında gizleme), herkese açıkModifier.clipScrollableContainer✅OverscrollEffect,rememberOverscrollEffect,Modifier.overscroll, kaydırma kaplarınınoverscrollEffectparametreleri (esneme artık bir efekt) ✅- Autofill:
ContentType,autofillManager()(commit/cancel), AndroidAutofillManagerköprüsü,SemanticsAction::SetText(veACTION_SET_TEXT) ✅ - Klavye kayarken IME boşlukları onu izler (Android 11+
WindowInsetsAnimation),imeAnimationSource/imeAnimationTarget,isImeVisible✅ CustomSaver,listSaver,mapSaver,rememberSaveable(kaydedici, init)(vestateSavergibiMutableState) ✅- Material durumları süreç bitince geri gelir: üst çubuk, çekmece, yüzen araç çubuğu, modal sayfa, arama çubuğu, kaydırıp silme, saat/tarih seçiciler, geniş ray, bölme genişliği ✅
BringIntoViewSpec,LocalBringIntoViewSpec(odaktakini görünür alana getirirken nereye) ✅- Özel göstergeler:
IndicationNodeFactory,IndicationNode✅ TextToolbar,LocalTextToolbar(seçim çubuğunu kendi çubuğunla değiştirmek) ✅- Paylaşılan geçiş katmanı:
renderInSharedTransitionScopeOverlay,zIndexInOverlay,renderInOverlayDuringTransition✅ Modifier.skipToLookaheadSize()(canlanan boyutta içeriği gideceği boyutta dizmek) ✅- Renkli vektörler:
ImageVector::Builder,VectorPath; Compose'un vektör modeli (VectorGroupağacı,PathNode'lar,PathParser,PathBuilder, adlar,tintColor/tintBlendMode), Compose'unVectorPainter'ı gibi bir bitmap'ten çizim (tek renkte Alpha8) ✅ - Yol verisinde yaylar (
A/a) ✅ vectorResource: Android vector drawable XML ✅- Vector drawable degradeleri; duraklı
Brush::radialGradient/sweepGradient✅ - ImageVector grupları (
addGroup/clearGroup/group,clipPathData),<clip-path>✅ - Vektör yollarında
trimPathStart/End/Offset; composable içeriklirememberVectorPainter(vector::Group,vector::Path,vector::RenderVectorGroup,VectorConfig/VectorProperty) ✅ AnimatedImageVector,<animated-vector>,animatedVectorResource,rememberAnimatedVectorPainter✅- Dış hatlı metin:
TextStyle.drawStyle,SpanStyle.drawStyle(Stroke) ✅ TextGeometricTransform(scaleX,skewX) ✅- Metin gölgeleri (bulanık da) dış hattı, gerilmeyi ve eğikliği izler ✅
FontVariation: değişken yazı tiplerinin eksenleri (FontFile::variationSettings) ✅Modifier.scrollableArea✅requiredWidthIn,requiredHeightIn,requiredSizeIn✅WindowInsets.captionBar,mandatorySystemGestures,tappableElement,waterfall,safeGesturesve dolguları ✅Modifier.onConsumedWindowInsetsChanged✅Modifier.imeNestedScroll✅Modifier.approachLayout,DeferredTargetAnimation✅Modifier.preferredFrameRate(Hz ya daFrameRateCategory) ✅- Parametreli
movableContentOfvemovableContentWithReceiverOf✅ selectableGroupAndroid erişilebilirliğinde (CollectionInfo) ✅- Kaydırılabilir içinde basma göstergesi dokunma zaman aşımından sonra ✅
BrushPainterrenk süzgeci (ColorFilter::apply(Brush)) ✅- Carousel
maskClip/maskBorder✅ - Dalgalı göstergenin genliği Compose'un eğrileriyle (artarken standard, azalırken emphasized accelerate) ✅
Circular/LinearProgressIndicatorCompose 1.4'ün çizimi ve hareketiyle ✅SwitchCompose 1.4'ün renkleri (kapalı iz surfaceContainerHighest, devre dışı yüzeyin üstüne soluk) ve hızlı uzamsal yayıyla, basınca anında 28 dp ✅Checkbox/TriStateCheckboxCompose 1.4'ün çizimi ve hareketiyle (20 dp kutu, tik yolu çizilip çizgiye bükülür, devre dışı onSurface %38) ✅DrawScopedrawRect/drawRoundRect/drawCircleStrokeile Compose'daki gibi çizginin ortası şeklin kenarında (önceden içe çiziliyordu) ✅RadioButtonCompose 1.4'ün renkleri ve hareketiyle (devre dışı onSurface %38 anında, nokta hızlı uzamsal yayla, renk varsayılan efekt yayıyla) ✅- Kartlar Compose 1.4'ün token'larıyla (12 dp köşe, içerik kırpılır, dolu kart surfaceContainerHighest, gölgeli kart 1 dp) ✅
- Butonlar Compose 1.4'ün ölçüleri ve yükseltileriyle (8 dp dikey dolgu, en az 58 dp,
contentPadding,ButtonDefaults, outlineVariant çerçeve, üzerine gelince yükselme) ✅ - Çipler Compose 1.4'ün renkleri ve ölçüleriyle (öneri/giriş etiketi onSurfaceVariant, filtre baş simgesi primary, devre dışı onSurface %12, giriş çipi uçta 4 dp +
ChipOptions::avatar), seçilebilir çiplerde simge genişleyip solarak gelir, alanı daralarak gider; filtre/giriş çipi onay kutusu olarak okunur ✅ - FAB'ler Compose 1.4'teki gibi üzerine gelince 8 dp yükselir (basılıyken 6);
ExtendedFloatingActionButtonsimgeden önce 16, sonra 12, etiketten sonra 20 dp, en az 80 dp ✅ NavigationBarItemCompose 1.4'teki gibi: gösterge 12 dp aşağıda ortadan genişleyip solarak gelir (hızlı uzamsal + efekt yayı), ikon 16 dp, etiket 48 dp aşağıda, seçili etiket secondary, renkler yumuşak geçer, dalga yalnız göstergede ve parmağın değdiği yerden başlar; sekme olarak okunur ✅NavigationRail/NavigationRailItemCompose 1.4'teki gibi: en az 80 dp, öğeler arası ve uçlarda 4 dp, başlık altında 8 dp; 80 × 56 öğe, gösterge üstte ortadan genişleyerek, etiket 36 dp aşağıda ve seçiliyken secondary, dalga göstergede parmaktan başlar ✅ShortNavigationBarItemdalgası göstergede parmağın değdiği yerden başlar ✅NavigationDrawerItemCompose 1.4'teki gibi: en az 56 dp (uzun etiketle uzar), seçili zemin anında, etiket çevredeki metin stilinde, sekme olarak okunur ✅Tab/LeadingIconTabCompose 1.4'teki gibi: renkler satırın içerik renginden (birincilde primary, ikincilde onSurface) ve seçilmemiş sekme de varsayılan olarak aynı renkte (TabOptions::unselectedContentColorile ayrılır), renk geçişi efekt yaylarıyla, dalga seçili renkte; simgeli sekme 72 dp, metin taban çizgisi alttan 17 dp, simge 20 dp üstünde; gösterge varsayılan uzamsal yayla kayar; sekme olarak okunur ✅ListItemCompose 1.4'ün yerleşimiyle: iki yanda 16 dp, birden çok satıra taşan alt metin de üç satırlık sayılır (12 dp, yanlar üstte), öğe tek erişilebilirlik düğümü ✅BadgedBoxCompose 1.4'teki gibi: sayılı rozet sondan 12 dp içeride, alt kenarı üstten 14 dp aşağıda ✅- İkon butonları Compose 1.4'ün renkleriyle: tonlu secondaryContainer, devre dışı zemin onSurface %10, çizgili çerçeve çevredeki içerik renginde (devre dışı %38); toggle'larda dolu kapalıyken surfaceContainer/onSurfaceVariant, tonlu kapalı secondaryContainer açık secondary, devre dışı çizgili açıkken de zemin yok ✅
SegmentedButtonCompose 1.4'teki gibi: zemin anında, tik solarak ve sol alt köşeden büyüyerek gelir (bırakılınca anında gider), etiket simge alanının yarısından kayarak yer açar ✅- Alt sayfalar Compose 1.4'ün hareketiyle: açılış ve sürükleme sonrası varsayılan uzamsal yay, kapanış hızlı efekt yayı, karartma efekt yayıyla; tutamak soluk değil onSurfaceVariant (
AnchoredDraggableState::animateTo(değer, spec)eklendi) ✅ - Tooltip'ler Compose 1.4'teki gibi %80'den büyüyerek ve solarak gelir, aynı şekilde solarak gider; zengin tooltip 3 dp gölgeli, başlık taban çizgisi 28 dp, metin 24 dp altında, eylem en az 36 dp; düz tooltip en az 40 dp ✅
BottomAppBarCompose 1.4'ün dolgusuyla: başta, sonda ve üstte 4 dp (eylemler 2 dp aşağıda ortalı), FAB üstten 12, sondan 16 dp ✅- Menü öğeleri Compose'daki gibi metinde labelLarge, destek metninde bodyMedium ✅
- Betikli ekran görüntüsü çizilen kareden alınır (ekran dışı OpenGL penceresi büyüyünce kesiliyordu) ✅
SecondaryTabRowgöstergesi Compose 1.4'teki gibi 3 dp ✅ColorSchemeCompose 1.4'ün bütün renkleriyle (errorContainer, surfaceVariant, surfaceBright/Dim, surfaceContainerLowest, scrim, surfaceTint, primary/secondary/tertiary fixed renkler; dinamik renkte de),contentColorFor; karartmalar şemanın scrim rengiyle ✅CutCornerShape(köşeler düz kesik; tek boy, yüzde ya da her köşe ayrı),AbsoluteCutCornerShape,AbsoluteRoundedCornerShape(sağdan solaya aynalanmaz) ✅BasicTooltipBox,BasicTooltipState,rememberBasicTooltipState(foundation: konumu verilen yerde, animasyonsuz,focusable,enableUserInput; varsayılan kalıcı); aynı anda tek tooltip görünür (biri açılınca diğeri kapanır, Compose'un ortak MutatorMutex'i gibi) ✅mediaQuery,derivedMediaQuery,UiMediaScope(Compose 1.12, deneysel): pencere boyu, en hassas işaretçi (fare/kalem, dokunmatik, kumanda), klavye (fiziksel, ekranda, yok), mikrofon, kamera, görüş mesafesi (TV uzak, araba/yuvada orta), duruş; Android'de InputManager/PackageManager ve yuva olayıyla, masaüstünde SDL ile (mikrofon/kamera ilk kareden sonra yoklanır). Not: katlanabilir duruşu androidx.window gerektirdiği için hep Flat ✅FlexBox,FlexBoxConfig,Modifier.flex(FlexConfig)(Compose 1.12, deneysel; CSS flexbox): yön (Row/Column ve tersleri), sarma (Wrap/WrapReverse), justifyContent, alignItems (Baseline dahil), alignContent, satır/sütun boşlukları; çocukta grow, shrink (taban boyuna göre, en küçüğünde donar), basis (doğal/dp/yüzde), alignSelf, order; kısıtlara göre config. Not: Compose'un ters sarmada boşlukları hesaba katmayan hatası düzeltilmiş olarak ✅Grid,GridConfig,GridTrackSize,GridArea,GridFlow,Modifier.gridItem(Compose 1.12, deneysel; CSS grid): sütun/satır izleri (Fixed dp, boşluklardan sonra kalan yerin yüzdesi, Flex fr en küçük içerikten, MinMax, MinContent, MaxContent, Auto en küçükten en büyük içeriğe), satır/sütun boşlukları, Row/Column akışı; çocukta 1 tabanlı satır/sütun (negatif: sondan), yayılma, aralık ({1, 2}), adlı alan, hücre içi hizalama; boş hücrelere otomatik yerleşim (imleçle), gerektikçe Auto örtük izler, yayılan öğe için büyüyebilen izleri genişletme; kısıtlara göre config ✅- Artımlı yerleşim (Compose gibi): son ölçüldüğü kısıtlarla yeniden ölçülen, içinde ya da altında bir şey değişmeyen düğüm boyunu ve çocuklarının yerini korur; yeniden ölçülenler: kompoze edilenler, ölçerken okudukları state değişenler, yerleşim animasyonunun sıradaki karesi, pencere/yoğunluk/inset ve kökten yeniden kompozisyon (hepsi).
KOMPOZ_LAYOUT_CHECK(testlerde hep açık) her yerleşimi baştan ölçülmüşüyle karşılaştırır,KOMPOZ_FULL_LAYOUTeski davranış. Redmi'de Bileşenler kaydırması 42 → ~58 fps ✅ - Yerleşimden sonraki ağaç dolaşmaları kısaldı: yerinden oynamayan ve yeniden ölçülmeyen alt ağacın mutlak konumu yeniden hesaplanmaz; konum bildirimi, ilgilendiği öğelerden hiçbiri olmayan düğümlerde (değiştiricisi değişene kadar) yalnız kırpmaya bakar; kaydırma (ScrollState, lazy listeler, iç içe kaydırma, bringIntoView, erişilebilirlik) yalnız kaydırılan düğümü yeniden ölçtürür; ripple yalnız yeniden çizim ister. Modal çekmecenin ofseti ölçülen genişliğini state olarak okur. Redmi'de kaydırırken kare başına iş: Liste ~10 → ~3 ms, Bileşenler ~13 → ~7.5 ms ✅
- Hiçbir düğümü yeniden ölçmeyen ve yerinden oynatmayan bir yerleşim ağacı dolaşmaz: popup'lar bir önceki listeden yeniden konumlanır, konum bildirimi (
reportPositions) atlanır ✅ - Belirsiz ilerleme göstergeleri (Circular/Linear, Wavy, LoadingIndicator, ContainedLoadingIndicator) ve wavy dalga kayması animasyonu Compose gibi çizim aşamasında okur: dönerken yeniden kompoze edilmez, ölçülmez, yalnız yeniden çizilir; çizilmezken (ekran dışında) kare istemez.
animateBounds'ın konum animasyonu da yalnız yeniden çizim ister ✅ - Metin alanında Compose'un donanım klavyesi eşlemesi (macOS dışı): Ctrl+←/→ kelime kelime (Shift ile seçerek), Ctrl+↑/↓ paragraf başı/sonu, Ctrl+Backspace/Delete kelime siler (seçim varsa seçimi), Alt+Delete satır sonuna kadar siler, Ctrl+H geri siler; değeri uygulamada tutulan (
String) alanlar da Ctrl+Z / Ctrl+Shift+Z / Ctrl+Y ile geri alır ve yineler (kendi geçmişleriyle; seçim de geri gelir, uygulamanın reddettiği geri alma imleci bozmaz) ✅ - Metin alanında fareyle seçim (Compose gibi): basış alanı odaklar ve imleci koyar, sürükleme seçer; çift tık kelimeyi, üçlü tık paragrafı alır ve sürükleme o birimle (geriye de) genişletir; Shift+tık seçimi başladığı yerden uzatır; tıklar basıştan basışa
doubleTapTimeoutiçinde sayılır; odaklı alana tık kapatılan klavyeyi geri getirir ✅ SelectionContainer'da fare Compose gibi: çift tık kelime, üçlü tık paragraf alır ve sürükleme o birimle (metinler arası, geriye de) genişletir; Shift+tık seçimi (ya da son tıklanan yeri) uzatır; tıklar basıştan basışadoubleTapTimeoutiçinde sayılır.pointerInputolayları artık basılı tuşları (keyboardModifiers), fareden gelip gelmediğini ve basılan düğmeyi taşır ✅- Fare imleci: I-çubuğu yalnız metin alanlarında ve
SelectionContaineriçindeki seçilebilir metinde (Compose'untextPointerIcon'u); sıradan birfocusable()kutu ve kabın boş yerleri varsayılan imleçte kalır; alt satıra taşan bir bağlantının her satırında el ✅ NavigationSuiteScaffoldCompose 1.4'teki gibi: yeni türler (ShortNavigationBarCompact/Medium,WideNavigationRailCollapsed/Expanded) ve varsayılanı seçennavigationSuiteType(); uygulamanın kendi kompoze ettiği öğelerle yeni aşırı yükleme (NavigationSuiteItem, birincil eylem içeriği: çubukta ucun üstünde, ray/çekmecede tepede; öğelerin dikey dizilimi);NavigationSuiteScaffoldState(Visible/Hidden, hide/show/toggle/snapTo: çubuk aşağı, ray başa kayar, içerik yerini alır);NavigationSuite,NavigationSuiteScaffoldLayout;WindowAdaptiveInfo.windowPosture(masa üstü duruşunda çubuk);NavigationRailItem'ın composable simge/etiketli aşırı yüklemesi,WideNavigationRail'de öğe dizilimi. Vitrin yeni varsayılanı kullanıyor ✅InfiniteTransition::animateFloatState/animateColorState→InfiniteState<T>(Compose'un State döndürenanimateFloat'ı): değer kompozisyonda okunursa okuyan her kare yeniden kompoze olur; çizimde (graphicsLayer {},drawBehind, Canvas) okunursa yalnız yeniden çizilir, yerleşimde (offset {}) okunursa yalnız yeniden yerleşir ✅- Klavye odağı Compose Material 3 gibi yalnız %10 durum katmanıyla görünür; Kompoz'un eklediği 2 dp halka kaldırıldı (Compose'un odak göstergesi belirteçleri hiçbir bileşende kullanılmıyor) ✅
- Fare tekerleği Compose gibi yumuşak kaydırır: çentik başına 64 dp; ilk 6 dp hemen, kalanı ms başına 1 dp (en çok 100 ms); animasyon sürerken gelen çentikler hedefe eklenir; hassas tekerlek/dokunmatik yüzey (kesirli) anında; basış durdurur; sayfa kaydırıcı (pager) bitince en yakın sayfaya yaslanır ✅
MaterialThemekaydırma çubuklarına şemanınonSurfacerengini (%12 / üzerine gelince %50) verir (Compose Multiplatform'un Material teması gibi): koyu temada da görünür ✅ShortNavigationBaralt inset'i iki kez ekliyordu (64 + 2 × inset); artık Compose gibi 64 dp + inset, öğeler 64 dp ✅Scaffold,BottomSheetScaffoldveNavigationSuiteScaffoldLayoutgövdeyi, carousel öğesi içeriğini (birBoxiçinde) Compose gibi alt sınırsız ölçer: doldurmayan içerik kendi boyunda kalır (önceden alanı doldurmaya zorlanıyordu); tam ekranPopupiçeriğine pencere boyunu vermeye devam eder (Compose'un platform genişliksizDialog'u gibi) ✅- Önizleme (Compose'un
@Preview'u):KOMPOZ_PREVIEW(ad, .width, .height, .darkTheme, .background) { ... }uygulamanın kaynağında bir bileşeni kaydeder; uygulamaKOMPOZ_PREVIEW=adile açılınca penceresi yalnız onu o boyutta gösterir,*ile hepsini alt alta (adı ve boyutuyla);scripts/dev.shher kayıtta yeniden derleyip yeniden başlatır (ekran, kaydırma verememberSaveabledurumuKOMPOZ_STATE_FILEile korunur) ✅ Hct(Material Color Utilities'in renk uzayı: CAM16 renk özü ve doygunluğu, L* ton) veTonalPalette::fromSeed(renk): tek renkten Android 13+'ın "tonal spot" paletleri; Linux'ta masaüstünün vurgu rengi (XDG portalınınorg.freedesktop.appearance/accent-color'u) okunur ve değiştikçe izlenir,dynamicLightColorScheme()/dynamicDarkColorScheme()onunla çalışır (koyu/açık modu SDL zaten portaldan izliyor); vitrin sistem temasını, düğmeye basılana kadar canlı izler ✅- Kütüphanenin kendi metinleri (Compose'un string kaynakları):
Strings(include/kompoz/strings.hpp) bileşenlerin gösterdiği ya da erişilebilirlik servislerine söylediği metinleri tutar (metin alanının bağlam menüsü ve araç çubuğu, "Seçili"/"İşaretli" açıklamaları, "Diğer seçenekler", açılır menünün ve bölünmüş butonun okları, snackbar'ın kapatma düğmesi, alt sayfanın sürükleme tutamacı, yenilemek için çekme etiketi, tarih ve saat seçicilerin metinleri),LocalStringsbunları verir. VarsayılanStrings::english(), ötekiStrings::turkish(); host kökte sistemin tercih ettiği dilinStrings::forLanguage(...)'ını verir (ComposeHost::setStrings; SDL arka ucu masaüstünde, Android'de ve web'de okur,KOMPOZ_LANGUAGE=tr|enile zorlanır). Uygulama kendininkini verebilir (CompositionLocalProvider({LocalStrings.provides(benimki)}, …)); verilmişseDatePickerOptions::stringsveTimePickerOptions'ın etiketleri yine önce gelir. Şimdiye dek bu metinler Türkçeydi (tarih seçicilerinki İngilizce) ✅ - Resimden ve duvar kağıdının kendisinden renkler:
quantizeColors(Android'in ve Material Color Utilities'in Celebi nicemleyicisi: L*a*b*'de k-means ile iyileştirilen Wu nicemleyicisi),seedColors(Android System UI'ın duvar kağıdı tohumlarını sıraladığı gibi: monet'ninColorScheme.getSeedColors'ı) ve bir resme Android'in duvar kağıdına yaptığını yapanTonalPalette::fromImage(WallpaperColors.fromBitmap'in 112 × 112 alana filtresiz küçültmesi, nicemleyici, tohum); duvar kağıdının kendisindenwallpaperLightColorScheme()/wallpaperDarkColorScheme()/isWallpaperColorAvailable()(LocalWallpaperTonalPalette): Linux'ta (KDE Plasma; GNOME, Cinnamon, MATE; Xfce), Windows'ta ve Android 8.1+'da (sistemin WallpaperColors'ı: System UI'ın nüfusları göremediğinde yaptığı gibi gri olmayan ilk ana rengi) bulunur ve değiştikçe izlenir. Sistemin paletinin (dynamicLightColorScheme()) ve uygulamanın şemasının yanında ayrı bir kaynak: kütüphane aralarında seçim yapmaz; uygulama ya da kullanıcısı seçer (vitrin soruyor). Betiğinsleep mskomutu başka iş parçacıklarının işini gerçek zamanda bekler ✅ Offset==ile karşılaştırılır, böylece onlardan oluşan bir durum (bir çizimin noktaları)set()alır; Windows'un vurgu rengi (Ayarlar > Kişiselleştirme > Renkler, DWM'nin kayıt defteri değeri, değiştikçe izlenir) orada sistemin paletidir (dynamicLightColorScheme()), Linux'ta XDG portalınınki gibi ✅- Compose'unki gibi 64 bitlik
Color, renk uzaylarıyla (ColorSpace,ColorSpaces,Rgb, connector'lar, adaptasyon), Oklab'dalerpve Compose'unColor.VectorConverter'ı gibi canlandırılan renkler ✅ - Skia'nınki gibi
PathEffectvePathMeasure: kesikler, köşeler, damgalar ve zincirler Skia'nın yaptığı gibi, bir yol çizildiği yerde piksellerinde uygulanır; uzunluklar, konumlar ve eğri parçalarıSkContourMeasure'ın ölçüp kestiği gibi ✅
Sıradakiler
- iOS (bir Xcode projesi ya da CMake kurulumu gerekiyor); macOS'u CI derliyor, test ediyor ve çalıştırıyor ama henüz elle kullanılmadı.
- macOS'un erişilebilirlik API'si (NSAccessibility); Android'de TalkBack, Linux'ta AT-SPI, Windows'ta UI Automation çalışıyor.
- Lazy listelerde
contentTypeile öğe yeniden kullanımı (Compose'un SubcomposeLayout havuzu): ölçüldü, şimdilik gerek yok (10.000 satırlık listede kare başına 0,06–0,13 ms). - Kotlin
bydelegasyonunun karşılığı yok: durum.get()/.set()ile okunup yazılır.