Kaydırma değiştiricileri
verticalScroll
ve horizontalScroll
değiştiricileri, bir öğenin sınırları maksimum boyut sınırlamalarından daha büyük olduğunda kullanıcının öğeyi kaydırmasına izin vermenin en basit yolunu sunar. verticalScroll
ve horizontalScroll
değiştiricileriyle içerikleri çevirmeniz veya uzaklaştırmanız gerekmez.
@Composable private fun ScrollBoxes() { Column( modifier = Modifier .background(Color.LightGray) .size(100.dp) .verticalScroll(rememberScrollState()) ) { repeat(10) { Text("Item $it", modifier = Modifier.padding(2.dp)) } } }
ScrollState
, kaydırma konumunu değiştirmenize veya mevcut durumunu almanıza olanak tanır. Varsayılan parametrelerle oluşturmak için rememberScrollState()
değerini kullanın.
@Composable private fun ScrollBoxesSmooth() { // Smoothly scroll 100px on first composition val state = rememberScrollState() LaunchedEffect(Unit) { state.animateScrollTo(100) } Column( modifier = Modifier .background(Color.LightGray) .size(100.dp) .padding(horizontal = 8.dp) .verticalScroll(state) ) { repeat(10) { Text("Item $it", modifier = Modifier.padding(2.dp)) } } }
Kaydırılabilir değiştirici
scrollable
değiştiricisinin, scrollable
kaydırma hareketlerini algılaması ve deltaları yakalaması ancak içeriklerini otomatik olarak dengelememesi açısından kaydırma değiştiricilerinden farkı vardır. Bunun yerine, bu değiştiricinin düzgün çalışması için gerekli olan ScrollableState
üzerinden kullanıcıya yetki verilir.
ScrollableState
oluştururken her kaydırma adımında (hareket girişi, yumuşak kaydırma veya hızlıca kaydırma) delta (piksel cinsinden) ile çağrılacak bir consumeScrollDelta
işlevi sağlamanız gerekir. Bu işlev, scrollable
değiştiriciye sahip iç içe yerleştirilmiş öğelerin bulunduğu durumlarda etkinliğin doğru şekilde yayılmasını sağlamak için tüketilen kaydırma mesafesi miktarını döndürmelidir.
Aşağıdaki snippet, hareketleri algılar ve bir ofset için sayısal bir değer görüntüler, ancak herhangi bir öğeyi dengelemez:
@Composable private fun ScrollableSample() { // actual composable state var offset by remember { mutableStateOf(0f) } Box( Modifier .size(150.dp) .scrollable( orientation = Orientation.Vertical, // Scrollable state: describes how to consume // scrolling delta and update offset state = rememberScrollableState { delta -> offset += delta delta } ) .background(Color.LightGray), contentAlignment = Alignment.Center ) { Text(offset.toString()) } }
İç içe kaydırma
İç içe kaydırma, birbirine bağlı olan birden fazla kaydırma bileşeninin tek bir kaydırma hareketine tepki vererek ve onların kaydırma deltalarını (değişiklikler) bildirerek birlikte çalıştığı bir sistemdir.
İç içe kaydırma sistemi, kaydırılabilen ve hiyerarşi olarak bağlantılı (çoğunlukla aynı üst öğenin paylaşılması yoluyla) bileşenler arasında koordinasyon sağlar. Bu sistem, kayan kapsayıcıları bağlar ve dağıtılan ve bunlar arasında paylaşılan kaydırma deltalarıyla etkileşime olanak tanır.
Oluştur, composable'lar arasında iç içe kaydırmayı ele almak için çeşitli yöntemler sunar. İç içe kaydırmaya ilişkin tipik bir örnek, başka bir liste içindeki bir listedir. Daha karmaşık bir durum ise daraltılabilen bir araç çubuğudur.
Otomatik iç içe kaydırma
Basit iç içe kaydırma işlemi sizin herhangi bir işlem yapmanıza gerek yoktur. Kaydırma işlemi başlatan hareketler, alt yayıncılardan üst öğelere otomatik olarak yayılır. Böylece çocuk daha fazla kaydırma yapamadığında hareket, kendi üst öğesi tarafından işlenir.
Otomatik olarak iç içe yerleştirilmiş kaydırma, Compose'un bazı bileşenleri ve değiştiricileri tarafından desteklenir ve kullanıma hazır şekilde sağlanır:
verticalScroll
,
horizontalScroll
,
scrollable
,
Lazy
API'ler ve TextField
. Diğer bir deyişle, kullanıcı, iç içe yerleştirilmiş bileşenlerin iç alt öğesini kaydırdığında önceki değiştiriciler, kaydırma deltalarını iç içe kaydırma desteği olan üst öğelere yayar.
Aşağıdaki örnekte, kendilerine verticalScroll
değiştirici uygulanmış bir kapsayıcının içinde kendilerine verticalScroll
değiştirici uygulanmış öğeler gösterilmektedir.
@Composable private fun AutomaticNestedScroll() { val gradient = Brush.verticalGradient(0f to Color.Gray, 1000f to Color.White) Box( modifier = Modifier .background(Color.LightGray) .verticalScroll(rememberScrollState()) .padding(32.dp) ) { Column { repeat(6) { Box( modifier = Modifier .height(128.dp) .verticalScroll(rememberScrollState()) ) { Text( "Scroll here", modifier = Modifier .border(12.dp, Color.DarkGray) .background(brush = gradient) .padding(24.dp) .height(150.dp) ) } } } } }
nestedScroll
değiştiriciyi kullanma
Birden fazla öğe arasında gelişmiş bir koordine kaydırma oluşturmanız gerekiyorsa nestedScroll
değiştirici, iç içe yerleştirilmiş bir kaydırma hiyerarşisi tanımlayarak size daha fazla esneklik sağlar. Önceki bölümde belirtildiği gibi, bazı bileşenlerde yerleşik iç içe kaydırma desteği bulunur. Bununla birlikte, Box
veya Column
gibi otomatik olarak kaydırılamayan composable'lar için bu tür bileşenlerdeki kaydırma deltaları, iç içe yerleştirilmiş kaydırma sisteminde yayılmaz ve deltalar NestedScrollConnection
veya üst bileşene ulaşmaz. Bu sorunu çözmek için nestedScroll
kullanarak bu tür desteği özel bileşenler de dahil olmak üzere diğer bileşenlere sağlayabilirsiniz.
İç içe kaydırma döngüsü
İç içe kaydırma döngüsü, iç içe yerleştirilmiş kaydırma sisteminin parçası olan tüm bileşenler (veya düğümler) aracılığıyla hiyerarşi ağacında yukarı ve aşağı dağıtılan kaydırma deltalarının akışıdır. Örneğin, kaydırılabilir bileşenler ve değiştiriciler ya da nestedScroll
kullanılarak bu döngüden yararlanılır.
İç içe kaydırma döngüsünün aşamaları
Kaydırılabilir bir bileşen, bir tetikleyici etkinliği (örneğin, hareket) algıladığında, gerçek kaydırma işlemi daha tetiklenmeden, oluşturulan deltalar iç içe yerleştirilmiş kaydırma sistemine gönderilir ve üç aşamadan geçer: kaydırma öncesi, düğüm tüketimi ve kaydırma sonrası.
Kaydırma öncesi aşamada, tetikleyici etkinlik deltalarını alan bileşen, bu etkinlikleri hiyerarşi ağacı aracılığıyla en üstteki üst öğeye gönderir. Daha sonra delta etkinlikleri baloncuk olarak aşağı açılır. Yani deltalar, kökten en üst düzeydeki üst öğeden aşağı doğru, iç içe yerleştirilmiş kaydırma döngüsünü başlatan alt öğeye yayılır.
Bu, iç içe yerleştirilmiş kaydırma üst öğelerine (nestedScroll
veya kaydırılabilir değiştiricileri kullanan composable'lar), düğümün kendisi tüketilmeden önce deltayla bir şey yapma fırsatı verir.
Düğüm tüketim aşamasında, düğümün kendisi üst öğeleri tarafından kullanılmayan deltayı kullanır. Bu, kaydırma hareketinin gerçekleşip görünür olduğu aşamadır.
Bu aşamada çocuk, kalan kaydırmanın tamamını veya bir kısmını tüketmeyi seçebilir. Kalan her şey, kaydırma sonrası aşamasına geçmek üzere geri gönderilir.
Son olarak, kaydırma sonrası aşamada, düğümün kendisinin tüketmediği her şey tüketilmek üzere tekrar üst öğelerine gönderilir.
Kaydırma sonrası aşaması, ebeveynlerin herhangi bir içeriği tüketmeyi veya kullanmamayı seçebileceği kaydırma öncesi aşamaya benzer şekilde çalışır.
Benzer şekilde, kaydırmaya benzer şekilde, sürükleme hareketi tamamlandığında kullanıcının amacı, kaydırılabilir kapsayıcıyı sallamak (animasyon kullanarak kaydırma) için kullanılan bir hıza dönüştürülebilir. Hızlı kaydırma da iç içe yerleştirilmiş kaydırma döngüsünün bir parçasıdır ve sürükleme etkinliği tarafından oluşturulan hızlar benzer aşamalardan geçer: kaydırma öncesi, düğüm tüketimi ve kaydırma sonrası. Hızlıca kaydırma animasyonunun yalnızca dokunma hareketiyle ilişkilendirildiğini ve a11y veya donanım kaydırma gibi diğer etkinlikler tarafından tetiklenmediğini unutmayın.
İç içe kaydırma döngüsüne katılın
Döngüye katılmak, hiyerarşi boyunca deltaların tüketimine müdahale etmek, bunları tüketmek ve raporlamak anlamına gelir. Oluştur, iç içe yerleştirilmiş kaydırma sisteminin çalışma şeklini ve sistemle doğrudan nasıl etkileşimde bulunulacağını (örneğin, kaydırılabilir bir bileşen daha kaydırmaya başlamadan önce kaydırma deltalarıyla bir şey yapmanız gerektiğinde) etkilemek için bir dizi araç sunar.
İç içe kaydırma döngüsü, bir düğüm zinciri üzerinde işlem yapan bir sistemse nestedScroll
değiştiricisi, bu değişikliklere müdahale edip bu değişikliklere eklemenin ve zincirde dağıtılan verileri (kaydırma deltaları) etkilemenin bir yoludur. Bu değiştirici, hiyerarşide herhangi bir yere yerleştirilebilir ve ağacın üst kısmındaki iç içe yerleştirilmiş kaydırma değiştirici örnekleriyle iletişim kurarak bu kanal üzerinden bilgi paylaşabilir. Bu değiştiricinin yapı taşları NestedScrollConnection
ve NestedScrollDispatcher
'dır.
NestedScrollConnection
, iç içe yerleştirilmiş kaydırma döngüsünün aşamalarına yanıt vermek ve iç içe yerleştirilmiş kaydırma sistemini etkilemek için bir yöntem sunar. Her biri tüketim aşamalarından birini temsil eden dört geri çağırma yönteminden oluşur: öncesi/sonrası ve öncesi/sonrası:
val nestedScrollConnection = object : NestedScrollConnection { override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset { println("Received onPreScroll callback.") return Offset.Zero } override fun onPostScroll( consumed: Offset, available: Offset, source: NestedScrollSource ): Offset { println("Received onPostScroll callback.") return Offset.Zero } }
Her geri çağırma, dağıtılan delta hakkında da bilgi verir: söz konusu aşama için available
delta ve önceki aşamalarda tüketilen consumed
delta. Herhangi bir noktada hiyerarşide deltaların yayılmasını durdurmak isterseniz bunu yapmak için iç içe yerleştirilmiş kaydırma bağlantısını kullanabilirsiniz:
val disabledNestedScrollConnection = remember { object : NestedScrollConnection { override fun onPostScroll( consumed: Offset, available: Offset, source: NestedScrollSource ): Offset { return if (source == NestedScrollSource.SideEffect) { available } else { Offset.Zero } } } }
Tüm geri çağırmalar, NestedScrollSource
türüyle ilgili bilgi sağlar.
NestedScrollDispatcher
, iç içe yerleştirilmiş kaydırma döngüsünü başlatır. Bir sevk görevlisi kullanmak ve onu çağırmak
döngüyü tetikler. Kaydırılabilir kapsayıcılarda, hareketler sırasında yakalanan deltaları sisteme gönderen yerleşik bir görev dağıtıcı bulunur. Bu nedenle, iç içe yerleştirilmiş kaydırmayı özelleştirmenin çoğu kullanım alanında, yeni deltalar göndermek yerine mevcut deltalara tepki vermek için bir sevk görevlisi yerine NestedScrollConnection
kullanılır.
Diğer kullanım alanları için NestedScrollDispatcherSample
sayfasını inceleyin.
İç içe kaydırma birlikte çalışabilirliği
Kaydırılabilir View
öğelerini, kaydırılabilir composable'lara iç içe yerleştirmeye çalıştığınızda (veya tam tersi) sorunlarla karşılaşabilirsiniz. En çok dikkat çekenler, alt öğeyi kaydırıp başlangıç veya bitiş sınırlarına ulaştığınızda ve ebeveynin kaydırmayı kaydırmasını beklediğinizde gerçekleşir. Ancak, bu beklenen davranış gerçekleşmeyebilir veya
beklendiği gibi çalışmayabilir.
Bu sorun, kaydırılabilir composable'ların yerleşik beklentilerinden kaynaklanmaktadır.
Kaydırılabilir composable'ların "iç içe yerleştirilmiş-scroll-by-default" kuralı vardır. Yani, kaydırılabilir tüm kapsayıcılar iç içe yerleştirilmiş kaydırma zincirine hem NestedScrollConnection
üzerinden üst öğe olarak hem de NestedScrollDispatcher
aracılığıyla alt öğe olarak katılmalıdır.
Alt öğe sınırda olduğunda üst öğe için iç içe yerleştirilmiş bir kaydırma kullanır. Örneğin, bu kural Oluştur Pager
ve Oluştur LazyRow
öğelerinin birlikte iyi çalışmasını sağlar. Bununla birlikte, NestedScrollingParent3
uygulanmadığı için ViewPager2
veya RecyclerView
ile birlikte çalışabilirlik kaydırması yapıldığında, alt öğeden üst öğeye sürekli kaydırma yapılamaz.
Kaydırılabilir View
öğeleri ve kaydırılabilir composable'lar arasında iç içe yerleştirilmiş kaydırma birlikte çalışabilirlik API'sini, her iki yönde iç içe yerleştirilmiş şekilde etkinleştirmek için aşağıdaki senaryolarda bu sorunları azaltmak üzere iç içe yerleştirilmiş kayan birlikte çalışabilirlik API'sini kullanabilirsiniz.
İşbirliği yapan ebeveyn View
ve içinde ComposeView
çocuk var
Birlikte çalışan bir üst View
, halihazırda NestedScrollingParent3
özelliğini uygulayan ve bu nedenle birlikte çalışan iç içe yerleştirilmiş bir alt composable'dan kaydırma deltaları alabilen bir üst öğedir. ComposeView
bu durumda bir alt öğe olarak hareket eder ve NestedScrollingChild3
yöntemini (dolaylı olarak) uygulaması gerekir.
androidx.coordinatorlayout.widget.CoordinatorLayout
, işbirliği yapan üst işletmelere örnek olarak verilebilir.
Kaydırılabilir View
üst kapsayıcıları ile iç içe yerleştirilmiş kaydırılabilir alt composable'lar arasında iç içe yerleştirilmiş kaydırma birlikte çalışabilirliğine ihtiyacınız varsa rememberNestedScrollInteropConnection()
kullanabilirsiniz.
rememberNestedScrollInteropConnection()
, NestedScrollingParent3
uygulayan bir View
üst öğesi ile Compose alt öğesi arasında iç içe yerleştirilmiş kaydırma birlikte çalışabilirliğine olanak tanıyan NestedScrollConnection
öğesine izin verir ve bu NestedScrollConnection
öğesini hatırlar. Bu, bir nestedScroll
değiştiriciyle birlikte kullanılmalıdır. İç içe kaydırma, Oluşturma tarafında varsayılan olarak etkinleştirildiğinden, bu bağlantıyı kullanarak hem View
tarafında iç içe yerleştirilmiş kaydırmayı etkinleştirebilir hem de Views
ile composable'lar arasına gerekli birleştirici mantığını ekleyebilirsiniz.
CoordinatorLayout
, CollapsingToolbarLayout
ve bir alt composable, bu örnekte gösterilmiştir:
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.material.appbar.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="100dp" android:fitsSystemWindows="true"> <com.google.android.material.appbar.CollapsingToolbarLayout android:id="@+id/collapsing_toolbar_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" app:layout_scrollFlags="scroll|exitUntilCollapsed"> <!--...--> </com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.AppBarLayout> <androidx.compose.ui.platform.ComposeView android:id="@+id/compose_view" app:layout_behavior="@string/appbar_scrolling_view_behavior" android:layout_width="match_parent" android:layout_height="match_parent"/> </androidx.coordinatorlayout.widget.CoordinatorLayout>
Etkinliğinizde veya Parçanızda, çocuğunuz için composable'ı ve gerekli olan NestedScrollConnection
'ı ayarlamanız gerekir:
open class MainActivity : ComponentActivity() { @OptIn(ExperimentalComposeUiApi::class) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) findViewById<ComposeView>(R.id.compose_view).apply { setContent { val nestedScrollInterop = rememberNestedScrollInteropConnection() // Add the nested scroll connection to your top level @Composable element // using the nestedScroll modifier. LazyColumn(modifier = Modifier.nestedScroll(nestedScrollInterop)) { items(20) { item -> Box( modifier = Modifier .padding(16.dp) .height(56.dp) .fillMaxWidth() .background(Color.Gray), contentAlignment = Alignment.Center ) { Text(item.toString()) } } } } } } }
Alt AndroidView
içeren bir ebeveyn composable
Bu senaryoda, bir alt AndroidView
içeren üst composable'ınız olduğunda Compose tarafında iç içe yerleştirilmiş kaydırma birlikte çalışabilirlik API'sinin uygulanması ele alınmaktadır. AndroidView
, Compose kaydırma üst öğesinin alt öğesi olarak hareket ettiği için NestedScrollDispatcher
'yi ve View
kaydıran alt öğesine üst öğe işlevi gördüğü için NestedScrollingParent3
'i uygular. Böylece üst öğe oluşturduğunuzda, iç içe yerleştirilmiş kaydırılabilir bir alt öğeden (View
) iç içe yerleştirilmiş kaydırma deltaları alınabilir.
Aşağıdaki örnekte, Daraltma Oluştur araç çubuğuyla birlikte bu senaryoda iç içe kaydırma birlikte çalışabilirliği nasıl sağlayabileceğiniz gösterilmektedir:
@Composable
private fun NestedScrollInteropComposeParentWithAndroidChildExample() {
val toolbarHeightPx = with(LocalDensity.current) { ToolbarHeight.roundToPx().toFloat() }
val toolbarOffsetHeightPx = remember { mutableStateOf(0f) }
// Sets up the nested scroll connection between the Box composable parent
// and the child AndroidView containing the RecyclerView
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
// Updates the toolbar offset based on the scroll to enable
// collapsible behaviour
val delta = available.y
val newOffset = toolbarOffsetHeightPx.value + delta
toolbarOffsetHeightPx.value = newOffset.coerceIn(-toolbarHeightPx, 0f)
return Offset.Zero
}
}
}
Box(
Modifier
.fillMaxSize()
.nestedScroll(nestedScrollConnection)
) {
TopAppBar(
modifier = Modifier
.height(ToolbarHeight)
.offset { IntOffset(x = 0, y = toolbarOffsetHeightPx.value.roundToInt()) }
)
AndroidView(
{ context ->
LayoutInflater.from(context)
.inflate(R.layout.view_in_compose_nested_scroll_interop, null).apply {
with(findViewById<RecyclerView>(R.id.main_list)) {
layoutManager = LinearLayoutManager(context, VERTICAL, false)
adapter = NestedScrollInteropAdapter()
}
}.also {
// Nested scrolling interop is enabled when
// nested scroll is enabled for the root View
ViewCompat.setNestedScrollingEnabled(it, true)
}
},
// ...
)
}
}
private class NestedScrollInteropAdapter :
Adapter<NestedScrollInteropAdapter.NestedScrollInteropViewHolder>() {
val items = (1..10).map { it.toString() }
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): NestedScrollInteropViewHolder {
return NestedScrollInteropViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.list_item, parent, false)
)
}
override fun onBindViewHolder(holder: NestedScrollInteropViewHolder, position: Int) {
// ...
}
class NestedScrollInteropViewHolder(view: View) : ViewHolder(view) {
fun bind(item: String) {
// ...
}
}
// ...
}
Bu örnekte, API'yi bir scrollable
değiştiriciyle nasıl kullanabileceğiniz gösterilmektedir:
@Composable
fun ViewInComposeNestedScrollInteropExample() {
Box(
Modifier
.fillMaxSize()
.scrollable(rememberScrollableState {
// View component deltas should be reflected in Compose
// components that participate in nested scrolling
it
}, Orientation.Vertical)
) {
AndroidView(
{ context ->
LayoutInflater.from(context)
.inflate(android.R.layout.list_item, null)
.apply {
// Nested scrolling interop is enabled when
// nested scroll is enabled for the root View
ViewCompat.setNestedScrollingEnabled(this, true)
}
}
)
}
}
Son olarak bu örnekte, başarılı bir sürükle ve kapatma davranışı elde etmek için iç içe yerleştirilmiş kaydırma birlikte çalışabilirlik API'sinin BottomSheetDialogFragment
ile nasıl kullanıldığı gösterilmektedir:
class BottomSheetFragment : BottomSheetDialogFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val rootView: View = inflater.inflate(R.layout.fragment_bottom_sheet, container, false)
rootView.findViewById<ComposeView>(R.id.compose_view).apply {
setContent {
val nestedScrollInterop = rememberNestedScrollInteropConnection()
LazyColumn(
Modifier
.nestedScroll(nestedScrollInterop)
.fillMaxSize()
) {
item {
Text(text = "Bottom sheet title")
}
items(10) {
Text(
text = "List item number $it",
modifier = Modifier.fillMaxWidth()
)
}
}
}
return rootView
}
}
}
rememberNestedScrollInteropConnection()
etiketinin, eklediğiniz öğeye bir NestedScrollConnection
yükleyeceğini unutmayın. NestedScrollConnection
, Compose düzeyindeki deltaların View
düzeyine aktarılmasından sorumludur. Bu, öğenin iç içe yerleştirilmiş kaydırmaya katılmasını sağlar ancak öğelerin otomatik olarak kaydırılmasını etkinleştirmez. Box
veya Column
gibi otomatik olarak kaydırılamayan composable'lar için bu tür bileşenlerdeki kaydırma deltaları, iç içe yerleştirilmiş kaydırma sisteminde yayılmaz ve deltalar, rememberNestedScrollInteropConnection()
tarafından sağlanan NestedScrollConnection
değerine ulaşmaz. Dolayısıyla, bu deltalar üst View
bileşenine ulaşmaz. Bu sorunu çözmek için kaydırılabilir değiştiricileri bu tür iç içe yerleştirilmiş composable'lara da ayarladığınızdan emin olun. Daha ayrıntılı bilgi için bir önceki İç içe yerleştirilmiş kaydırma bölümüne bakabilirsiniz.
İşbirliği yapmayan ebeveyn View
çocuk ComposeView
içeriyor
Ortak çalışmayan görünüm, View
tarafında gerekli NestedScrolling
arayüzlerini uygulamayan görünümdür. Bu durumda, bu Views
ile iç içe yerleştirilmiş kaydırma birlikte çalışabilirliği kullanıma hazır değildir. Uyumlu olmayan Views
kullanıcıları: RecyclerView
ve ViewPager2
.
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Hareketleri anlama
CoordinatorLayout
e-posta adresini Compose'a taşı- Compose'da Görünümleri kullanma