Kaydırma değiştiricileri
verticalScroll
ve
horizontalScroll
değiştiricileri, içeriğinin sınırları maksimum boyut kısıtlamalarından daha büyük olduğunda kullanıcının bir öğeyi kaydırmasına izin vermenin en basit yolunu sağlar. verticalScroll
ve horizontalScroll
değiştiricileriyle içerikleri çevirmeniz veya kaydı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()
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ştiricisi, scrollable
kaydırma hareketlerini algılayıp deltaları yakalaması ancak içeriklerini otomatik olarak kaydırmaması bakımından kaydırma değiştiricilerinden farklıdır. Bunun yerine, bu değiştiricinin doğru çalışması için gerekli olan ScrollableState
aracılığıyla kullanıcıya yetki verilir.
ScrollableState
oluştururken her kaydırma adımında (jest girişi, sorunsuz kaydırma veya hızlı kaydırma ile) piksel cinsinden delta ile çağrılacak bir consumeScrollDelta
işlevi sağlamanız gerekir. Bu işlev, scrollable
değiştiricisine sahip iç içe yerleştirilmiş öğelerin bulunduğu durumlarda etkinliğin düzgün şekilde yayılmasını sağlamak için kullanılan kaydırma mesafesini döndürmelidir.
Aşağıdaki snippet, hareketleri algılar ve bir ofset için sayısal değer gösterir ancak herhangi bir öğeyi ofsetlemez:
@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, birbirini içeren birden fazla kaydırma bileşeninin tek bir kaydırma hareketine tepki vererek ve kaydırma farklarını (değişikliklerini) ileterek birlikte çalıştığı bir sistemdir.
İç içe kaydırma sistemi, kaydırılabilir ve hiyerarşik olarak bağlı (çoğu zaman aynı üst öğeyi paylaşarak) bileşenler arasında koordinasyon sağlar. Bu sistem, kaydırma kapsayıcılarını bağlar ve aralarında yayılan ve paylaşılan kaydırma farklarıyla etkileşime izin verir.
Compose, composable'lar arasında iç içe kaydırmayı işlemek için birden fazla yöntem sunar. İç içe kaydırmaya tipik bir örnek, başka bir listenin içindeki listedir. Daha karmaşık bir örnek ise daraltılabilir araç çubuğudur.
Otomatik iç içe kaydırma
Basit iç içe kaydırma için herhangi bir işlem yapmanız gerekmez. Kaydırma işlemini başlatan hareketler, alt öğelerden üst öğelere otomatik olarak yayılır. Bu nedenle, alt öğe daha fazla kaydıramadığında hareket, üst öğesi tarafından işlenir.
Otomatik iç içe kaydırma, Compose'un bazı bileşenleri ve değiştiricileri tarafından kutudan çıkar çıkmaz desteklenir ve sağlanır: verticalScroll
, horizontalScroll
, scrollable
, Lazy
API'leri ve TextField
. Bu, kullanıcı iç içe yerleştirilmiş bileşenlerin iç içe yerleştirilmiş bir alt öğesini kaydırdığında önceki değiştiricilerin kaydırma deltalarını iç içe yerleştirilmiş kaydırma desteği olan üst öğelere yaydığı anlamına gelir.
Aşağıdaki örnekte, verticalScroll
değiştiricisi uygulanmış bir kapsayıcı içinde verticalScroll
değiştiricisi 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ştiricisini kullanma
Birden fazla öğe arasında gelişmiş bir koordineli kaydırma oluşturmanız gerekiyorsa nestedScroll
değiştiricisi, iç içe yerleştirilmiş bir kaydırma hiyerarşisi tanımlayarak 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. Ancak Box
veya Column
gibi otomatik olarak kaydırılamayan composable'lar için bu tür bileşenlerdeki kaydırma farkları iç içe yerleştirilmiş kaydırma sisteminde yayılmaz ve farklar NestedScrollConnection
'a veya üst bileşene ulaşmaz. Bu sorunu çözmek için nestedScroll
kullanarak özel bileşenler de dahil olmak üzere diğer bileşenlere bu tür bir destek sağlayabilirsiniz.
İç içe yerleştirilmiş kaydırma döngüsü
İç içe yerleştirilmiş 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ğı gönderilen kaydırma farklarının akışıdır. Örneğin, kaydırılabilir bileşenler ve değiştiriciler veya nestedScroll
kullanılarak oluşturulur.
İç içe kaydırma döngüsünün aşamaları
Kaydırılabilir bir bileşen tarafından bir tetikleyici etkinlik (ör. hareket) algılandığında, gerçek kaydırma işlemi tetiklenmeden önce oluşturulan delta değerleri 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ırmadan önceki ilk aşamada, tetikleyici etkinlik deltalarını alan bileşen, bu etkinlikleri hiyerarşi ağacı üzerinden en üstteki üst öğeye gönderir. Deltalar daha sonra aşağıya doğru yayılır. Yani deltalar, en kökteki üst öğeden iç içe yerleştirilmiş kaydırma döngüsünü başlatan alt öğeye doğru yayılır.
Bu, iç içe yerleştirilmiş kaydırma üst öğelerine (nestedScroll
veya kaydırılabilir değiştiriciler kullanan composable'lar) delta ile ilgili bir işlem yapma fırsatı verir. Bu işlem, düğümün kendisi deltayı kullanmadan önce gerçekleşir.
Düğüm tüketimi aşamasında, düğümün kendisi, üst öğeleri tarafından kullanılmayan tüm deltaları kullanır. Bu, kaydırma hareketinin gerçekten yapıldığı ve görünür olduğu zamandır.
Bu aşamada çocuk, kalan kaydırmanın tamamını veya bir kısmını izlemeyi seçebilir. Kalan her şey, kaydırma sonrası aşamadan geçmek üzere geri gönderilir.
Son olarak, kaydırma sonrası aşamada, düğümün kendisi tarafından kullanılmayan her şey, kullanılmak üzere tekrar üst öğelerine gönderilir.
Kaydırma sonrası aşama, kaydırma öncesi aşamaya benzer şekilde çalışır. Bu aşamada üst öğelerden herhangi biri içeriği kullanmayı veya kullanmamayı seçebilir.
Kaydırma işlemine benzer şekilde, sürükleme hareketi tamamlandığında kullanıcının amacı, kaydırılabilir kapsayıcıyı fırlatmak (animasyon kullanarak kaydırmak) için kullanılan bir hıza dönüştürülebilir. Fırlatma işlemi de iç içe 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: fırlatma öncesi, düğüm tüketimi ve fırlatma sonrası. Fling animasyonunun yalnızca dokunma hareketiyle ilişkili olduğunu ve diğer etkinlikler (ör. erişilebilirlik veya donanım kaydırma) tarafından tetiklenmeyeceğini unutmayın.
İç içe kaydırma döngüsüne katılma
Döngüye katılım, hiyerarşi boyunca deltaların tüketimini yakalamak, tüketmek ve tüketimle ilgili rapor oluşturmak anlamına gelir. Compose, iç içe kaydırma sisteminin nasıl çalıştığını etkilemek ve doğrudan bu sistemle etkileşim kurmak için bir dizi araç sunar. Örneğin, kaydırılabilir bir bileşen kaydırmaya başlamadan önce kaydırma farklarıyla ilgili bir işlem yapmanız gerektiğinde bu araçları kullanabilirsiniz.
İç içe kaydırma döngüsü, bir düğüm zincirinde işlem yapan bir sistemse nestedScroll
değiştiricisi, bu değişiklikleri yakalamanın, bunlara ekleme yapmanın ve zincirde yayılan verileri (kaydırma farkları) etkilemenin bir yoludur. Bu değiştirici, hiyerarşinin herhangi bir yerine yerleştirilebilir ve ağaçta yukarı doğru 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
'dir.
NestedScrollConnection
iç içe kaydırma döngüsünün aşamalarına yanıt vermenin ve iç içe kaydırma sistemini etkilemenin
bir yolunu sunar. Her biri tüketim aşamalarından birini temsil eden dört geri çağırma yönteminden oluşur: kaydırma öncesi/sonrası ve hızlıca kaydırma ö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, yaygınlaştırılan delta hakkında da bilgi verir:
available
söz konusu aşamaya ait delta ve consumed
önceki aşamalarda kullanılan delta. Deltaların hiyerarşide yukarı doğru yayılmasını durdurmak isterseniz bunu yapmak için iç içe 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 aramalar, NestedScrollSource
türü hakkında bilgi sağlar.
NestedScrollDispatcher
iç içe kaydırma döngüsünü başlatır. Bir dağıtıcı kullanmak ve yöntemlerini çağırmak döngüyü tetikler. Kaydırılabilir kapsayıcılarda, hareketler sırasında yakalanan deltaları sisteme gönderen yerleşik bir dağıtıcı bulunur. Bu nedenle, iç içe kaydırmayı özelleştirmenin çoğu kullanım alanında, yeni delta göndermek yerine mevcut deltalara tepki vermek için gönderici yerine NestedScrollConnection
kullanılır.
Diğer kullanım alanları için
NestedScrollDispatcherSample
sayfasına bakın.
Kaydırma sırasında resmi yeniden boyutlandırma
Kullanıcı kaydırdıkça, resmin kaydırma konumuna göre boyutunun değiştiği dinamik bir görsel efekt oluşturabilirsiniz.
Kaydırma konumuna göre resmi yeniden boyutlandırma
Bu snippet, dikey kaydırma konumuna göre bir LazyColumn
içindeki bir resmi yeniden boyutlandırmayı gösterir. Kullanıcı aşağı kaydırdıkça resim küçülür, yukarı kaydırdıkça büyür ve tanımlanan minimum ve maksimum boyut sınırları içinde kalır:
@Composable fun ImageResizeOnScrollExample( modifier: Modifier = Modifier, maxImageSize: Dp = 300.dp, minImageSize: Dp = 100.dp ) { var currentImageSize by remember { mutableStateOf(maxImageSize) } var imageScale by remember { mutableFloatStateOf(1f) } val nestedScrollConnection = remember { object : NestedScrollConnection { override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset { // Calculate the change in image size based on scroll delta val delta = available.y val newImageSize = currentImageSize + delta.dp val previousImageSize = currentImageSize // Constrain the image size within the allowed bounds currentImageSize = newImageSize.coerceIn(minImageSize, maxImageSize) val consumed = currentImageSize - previousImageSize // Calculate the scale for the image imageScale = currentImageSize / maxImageSize // Return the consumed scroll amount return Offset(0f, consumed.value) } } } Box(Modifier.nestedScroll(nestedScrollConnection)) { LazyColumn( Modifier .fillMaxWidth() .padding(15.dp) .offset { IntOffset(0, currentImageSize.roundToPx()) } ) { // Placeholder list items items(100, key = { it }) { Text( text = "Item: $it", style = MaterialTheme.typography.bodyLarge ) } } Image( painter = ColorPainter(Color.Red), contentDescription = "Red color image", Modifier .size(maxImageSize) .align(Alignment.TopCenter) .graphicsLayer { scaleX = imageScale scaleY = imageScale // Center the image vertically as it scales translationY = -(maxImageSize.toPx() - currentImageSize.toPx()) / 2f } ) } }
Kodla ilgili önemli noktalar
- Bu kod, kaydırma etkinliklerini yakalamak için
NestedScrollConnection
kullanır. onPreScroll
, kaydırma deltasına göre görüntü boyutundaki değişikliği hesaplar.currentImageSize
durum değişkeni, resmin mevcut boyutunu depolar.minImageSize
ilemaxImageSize. imageScale
arasında sınırlandırılmış olancurrentImageSize
değerinden türetilir.LazyColumn
,currentImageSize
'e göre telafi edilir.Image
, hesaplanan ölçeği uygulamak içingraphicsLayer
değiştiricisini kullanır.graphicsLayer
içindekitranslationY
, resmin ölçeklenirken dikey olarak ortalanmış kalmasını sağlar.
Sonuç
Yukarıdaki snippet, kaydırma sırasında ölçeklendirme efektiyle sonuçlanır:
İç içe kaydırma birlikte çalışabilirliği
Kaydırılabilir View
öğelerini kaydırılabilir composable'larda veya tam tersi şekilde iç içe yerleştirmeye çalıştığınızda sorunlarla karşılaşabilirsiniz. En belirgin olanlar, alt öğeyi kaydırıp başlangıç veya bitiş sınırlarına ulaştığınızda ve kaydırma işlemini üst öğenin devralması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'larda yerleşik olarak bulunan beklentilerden kaynaklanır.
Kaydırılabilir composable'lar "nested-scroll-by-default" (varsayılan olarak iç içe kaydırma) kuralına sahiptir. Bu kural, herhangi bir kaydırılabilir kapsayıcının hem NestedScrollConnection
aracılığıyla üst öğe olarak hem de NestedScrollDispatcher
aracılığıyla alt öğe olarak iç içe kaydırma zincirine katılması gerektiği anlamına gelir.
Bu durumda, alt öğe sınıra ulaştığında üst öğe için iç içe kaydırma işlemi gerçekleştirilir. Örneğin, bu kural, Compose Pager
ve Compose LazyRow
'un birlikte iyi çalışmasına olanak tanır. Ancak, birlikte çalışabilirlik kaydırma işlemi ViewPager2
veya RecyclerView
ile yapıldığında bunlar NestedScrollingParent3
'yi uygulamadığından alt öğeden üst öğeye sürekli kaydırma mümkün değildir.
Kaydırılabilir View
öğeleri ile her iki yönde de iç içe yerleştirilmiş kaydırılabilir composable'lar arasında iç içe kaydırma birlikte çalışabilirlik API'sini etkinleştirmek için aşağıdaki senaryolarda bu sorunları azaltmak amacıyla iç içe kaydırma birlikte çalışabilirlik API'sini kullanabilirsiniz.
Bir alt öğe ComposeView
içeren bir üst öğe View
İşbirlikçi bir üst öğe View
, NestedScrollingParent3
'ı zaten uygulayan ve bu nedenle işbirlikçi bir iç içe yerleştirilmiş alt composable'dan kaydırma deltaları alabilen bir öğedir. ComposeView
bu durumda çocuk gibi davranır ve NestedScrollingChild3
'ı (dolaylı olarak) uygulaması gerekir.
İşbirliği yapan bir ebeveyn örneği: androidx.coordinatorlayout.widget.CoordinatorLayout
.
Kaydırılabilir View
üst kapsayıcılar
ve iç içe yerleştirilmiş kaydırılabilir alt composable'lar arasında iç içe kaydırma birlikte çalışabilirliğine ihtiyacınız varsa rememberNestedScrollInteropConnection()
kullanabilirsiniz.
rememberNestedScrollInteropConnection()
View
üst öğesi ile Compose alt öğesi arasında iç içe kaydırma birlikte çalışabilirliğini sağlayan NestedScrollConnection
öğesini etkinleştirir ve hatırlar.View
üst öğesi NestedScrollingParent3
öğesini uygular. Bu, nestedScroll
değiştiricisiyle birlikte kullanılmalıdır. İç içe kaydırma, Compose tarafında varsayılan olarak etkinleştirildiğinden bu bağlantıyı kullanarak hem View
tarafında iç içe kaydırmayı etkinleştirebilir hem de Views
ile composable'lar arasında gerekli yapıştırıcı mantığını ekleyebilirsiniz.
Sık karşılaşılan bir kullanım alanı, bu örnekte gösterildiği gibi CoordinatorLayout
, CollapsingToolbarLayout
ve bir alt öğe composable'ını kullanmaktır:
<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, alt composable'ınızı ve gerekli NestedScrollConnection
'ı ayarlamanız gerekir:
open class MainActivity : ComponentActivity() { 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()) } } } } } } }
Bir alt öğe AndroidView
içeren üst composable
Bu senaryo, Compose tarafında iç içe kaydırma birlikte çalışabilirlik API'sinin uygulanmasını kapsar. Bu, bir alt öğe içeren bir üst composable'ınız olduğunda geçerlidir.AndroidView
. AndroidView
, Compose'da kaydırma özelliği olan bir üst öğenin alt öğesi olarak davrandığı için NestedScrollDispatcher
, kaydırma özelliği olan bir alt öğenin üst öğesi olarak davrandığı için de NestedScrollingParent3
arayüzünü uygular.View
Böylece üst öğe, iç içe yerleştirilmiş kaydırılabilir bir alt öğeden iç içe yerleştirilmiş kaydırma farklarını alabilir View
.
Aşağıdaki örnekte, bu senaryoda iç içe kaydırma birlikte çalışabilirliğinin nasıl sağlanabileceği ve Compose'da daraltılabilir bir araç çubuğunun nasıl kullanılacağı 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 scrollable
değiştiricisiyle 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, iç içe kaydırma birlikte çalışabilirlik API'sinin BottomSheetDialogFragment
ile nasıl kullanıldığı gösterilmektedir. Bu sayede, başarılı bir sürükleme ve kapatma davranışı elde edilir:
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()
öğesinin, eklendiği öğeye
NestedScrollConnection
yükleyeceğini unutmayın. NestedScrollConnection
, Compose düzeyindeki değişiklikleri View
düzeyine iletmekten sorumludur. Bu, öğenin iç içe kaydırmaya katılmasına olanak tanır ancak öğelerin otomatik olarak kaydırılmasını sağlamaz. Box
veya Column
gibi otomatik olarak kaydırılamayan composable'larda, bu tür bileşenlerdeki kaydırma farkları iç içe yerleştirilmiş kaydırma sisteminde yayılmaz ve farklar rememberNestedScrollInteropConnection()
tarafından sağlanan NestedScrollConnection
'a ulaşmaz. Bu nedenle, bu farklar ü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 iç içe yerleştirilmiş kaydırma ile ilgili önceki bölüme bakabilirsiniz.
Çocuk ComposeView
içeren işbirliği yapmayan bir ebeveyn View
İşbirliği yapmayan bir görünüm, NestedScrolling
tarafında gerekli View
arayüzlerini uygulamayan görünümdür. Bu nedenle, bu Views
ile iç içe kaydırma birlikte çalışabilirliğinin kullanıma hazır olarak çalışmadığını unutmayın. İş birliği yapmayan Views
, RecyclerView
ve ViewPager2
'dir.
Ek kaynaklar
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir.
- Hareketleri anlama
CoordinatorLayout
'i Oluştur'a taşıma- Oluşturma penceresinde görünümleri kullanma