پیمایش تودرتو سیستمی است که در آن چندین عنصر پیمایش که در داخل یکدیگر قرار دارند با واکنش به یک اشاره پیمایش و انتقال تغییرات پیمایش خود با یکدیگر کار میکنند.
سیستم پیمایش تودرتو امکان هماهنگی بین مؤلفههایی را فراهم میکند که پیمایشپذیر هستند و بهصورت سلسلهمراتبی پیوند داده شدهاند (اغلب با همرسانی کردن یک والد یکسان). این سیستم ظرفهای پیمایشی را پیوند میدهد و امکان تعامل با دلتاهای پیمایشی را که بین آنها منتشر و همرسانی میشود فراهم میکند.
«ترکیبکننده» روشهای متعددی برای مدیریت پیمایش تودرتو بین عناصر ترکیبی ارائه میدهد. نمونه معمول پیمایش تودرتو، فهرستی درون فهرستی دیگر است و نمونه پیچیدهتر آن نوارابزار جمعشونده است.
پیمایش خودکار تودرتو
پیمایش تودرتوی ساده نیازی به اقدام ازسوی شما ندارد. اشارههایی که کنش پیمایش را آغاز میکنند بهطور خودکار از فرزندان به والدین منتقل میشوند، بهطوریکه وقتی فرزند دیگر نمیتواند پیمایش کند، اشاره توسط عنصر والد آن مدیریت میشود.
پیمایش تودرتوی خودکار توسط برخیاز
عناصر و اصلاحکنندههای Compose پشتیبانی میشود و بهصورت پیشفرض ارائه میشود:
verticalScroll،
horizontalScroll،
scrollable،
واسطهای برنامهسازی کاربردی Lazy و TextField. این یعنی وقتی کاربر فرزند داخلی
عناصر تودرتو را پیمایش میکند، اصلاحکنندههای قبلی
تغییرات پیمایش را به والدین دارای پشتیبانی از پیمایش تودرتو منتقل میکنند.
مثال زیر عناصری را نشان میدهد که
verticalScroll
اصلاحکننده در داخل محتوی که verticalScroll
اصلاحکننده نیز به آن اعمال شده است به آنها اعمال شده است.
@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
اگر نیاز دارید پیمایش هماهنگ پیشرفتهای بین چند عنصر ایجاد کنید،
اصلاحکننده
nestedScroll
با تعریف سلسلهمراتب پیمایش تودرتو، انعطافپذیری بیشتری به شما میدهد. همانطور که در بخش قبلی ذکر شد، برخیاز عناصر از پیمایش تودرتو داخلی
پشتیبانی میکنند. بااینحال، برای عناصر ترکیبی که بهطور خودکار پیمایشپذیر نیستند، مثل
Box یا Column، دلتاهای پیمایش در چنین عناصری در
سیستم پیمایش تودرتو منتشر نمیشود و دلتاها به NestedScrollConnection یا
عنصر والد نمیرسد. برای رفع این مشکل، میتوانید از nestedScroll برای اعطای چنین
پشتیبانی به دیگر عناصر، ازجمله عناصر سفارشی، استفاده کنید.
چرخه پیمایش تودرتو
چرخه پیمایش تودرتو عبارت است از جریان تغییرات پیمایش که ازطریق همه عناصر (یا گرههایی) که بخشی از سیستم پیمایش تودرتو هستند، در درخت سلسلهمراتب به بالا و پایین ارسال میشوند، برای مثال بااستفاده از عناصر و اصلاحکنندههای پیمایشپذیر، یا nestedScroll.
مراحل چرخه پیمایش تودرتو
وقتی رویداد راهاندازی (برای مثال، اشاره) توسط عنصر پیمایشپذیر تشخیص داده میشود، قبلاز اینکه کنش پیمایش واقعی راهاندازی شود، دلتاهای تولیدشده به سیستم پیمایش تودرتو ارسال میشوند و سه مرحله را طی میکنند: پیشاز پیمایش، مصرف گره، و پساز پیمایش.
در مرحله اول، پیشاز پیمایش، مؤلفهای که رویداد محرک دلتاها را دریافت کرده است، آن رویدادها را ازطریق درخت سلسلهمراتب به والد بالایی ارسال میکند. رویدادهای دلتا سپس به پایین منتقل میشوند، به این معنی که دلتاها از والد ریشهای به سمت فرزندی که چرخه پیمایش تودرتو را شروع کرده است، منتشر میشوند.
این کار به والدین پیمایش تودرتو (ترکیبپذیرهایی که از nestedScroll یا
اصلاحکنندههای پیمایشپذیر استفاده میکنند) فرصت میدهد تا قبلاز اینکه گره بتواند آن را مصرف کند، کاری با دلتا انجام دهند.
در مرحله مصرف گره، خود گره از هرگونه دلتایی که توسط والدینش استفاده نشده باشد استفاده خواهد کرد. این زمانی است که حرکت پیمایش واقعاً انجام میشود و قابلمشاهده است.
در این مرحله، کودک میتواند انتخاب کند که تمام یا بخشی از پیمایش باقیمانده را مصرف کند. هر چیزی که باقی بماند به بالا فرستاده میشود تا مرحله پساز پیمایش را طی کند.
درنهایت، در مرحله پساز پیمایش، هر چیزی که خود گره مصرف نکرده باشد دوباره برای مصرف به اجدادش ارسال خواهد شد.
فاز پساز پیمایش به روشی مشابه با فاز پیشاز پیمایش عمل میکند، جایی که هریک از والدین میتوانند انتخاب کنند که محتوا را مصرف کنند یا نه.
مشابه پیمایش، وقتی اشاره کشیدن تمام میشود، ممکن است قصد کاربر به سرعتی ترجمه شود که برای پرتاب کردن (پیمایش بااستفاده از پویانمایی) محتوی پیمایشپذیر استفاده میشود. پرتاب نیز بخشی از چرخه پیمایش تودرتو است و سرعتهای تولیدشده توسط رویداد کشیدن مراحل مشابهی را طی میکنند: پیشپرتاب، مصرف گره، و پسپرتاب. توجه داشته باشید که پویانمایی پرتاب فقط با اشاره لمسی مرتبط است و با رویدادهای دیگر، مثل پیمایش سختافزاری یا دسترسپذیری، راهاندازی نمیشود.
در چرخه پیمایش تودرتو شرکت کنید
مشارکت در این چرخه به معنای رهگیری، مصرف، و گزارش مصرف دلتاها در طول سلسله مراتب است. Compose مجموعهای از ابزارها را برای تأثیرگذاری بر نحوه عملکرد سیستم پیمایش تودرتو و نحوه تعامل مستقیم با آن ارائه میدهد، برای مثال زمانی که باید قبلاز اینکه مؤلفه پیمایشپذیر شروع به پیمایش کند، کاری با تغییرات پیمایش انجام دهید.
اگر چرخه پیمایش تودرتو سیستمی باشد که روی زنجیرهای از گرهها عمل میکند،
nestedScroll
اصلاحکننده روشی برای رهگیری و درج در این تغییرات و
تأثیرگذاری بر دادههایی (تغییرات پیمایش) است که در زنجیره منتشر میشوند. این
اصلاحگر میتواند در هر جایی از سلسلهمراتب قرار گیرد و با
نمونههای اصلاحگر پیمایش تودرتو در درخت ارتباط برقرار میکند تا بتواند اطلاعات را ازطریق
این کانال همرسانی کند. واحد سازنده این اصلاحکننده NestedScrollConnection
و NestedScrollDispatcher است.
NestedScrollConnection
روشی برای پاسخ دادن به مراحل چرخه پیمایش تودرتو و تأثیرگذاری
بر سیستم پیمایش تودرتو ارائه میدهد. این عنصر از چهار روش بازخوانی تشکیل شده است که هرکدام نشاندهنده یکی از مراحل مصرف هستند: پیش/پساز پیمایش و پیش/پساز پرتاب:
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 } }
هر تماس برگشتی اطلاعاتی درباره دلتای درحال انتشار نیز ارائه میدهد:
available دلتا برای آن مرحله خاص، و consumed دلتا مصرفشده در
مراحل قبلی. اگر در هر زمانی خواستید انتشار دلتاها را در سلسله مراتب متوقف کنید، میتوانید از اتصال پیمایش تودرتو برای انجام این کار استفاده کنید:
val disabledNestedScrollConnection = remember { object : NestedScrollConnection { override fun onPostScroll( consumed: Offset, available: Offset, source: NestedScrollSource ): Offset { return if (source == NestedScrollSource.SideEffect) { available } else { Offset.Zero } } } }
همه تماسهای برگشتی اطلاعاتی درباره
NestedScrollSource
نوع ارائه میدهند.
NestedScrollDispatcherچرخه پیمایش تودرتو را مقداردهی اولیه میکند. استفاده از توزیعکننده و فراخوانی روشهای آن باعث شروع چرخه میشود. ظرفهای پیمایشپذیر دارای توزیعکننده داخلی هستند که
تغییرات ثبتشده درطول اشارهها را به سیستم ارسال میکند. به همین دلیل، بیشتر موارد استفاده از سفارشیسازی پیمایش تودرتو شامل استفاده از NestedScrollConnection بهجای توزیعکننده است تا به دلتاهای ازقبل موجود واکنش نشان دهد نه اینکه دلتاهای جدید ارسال کند.
برای موارد استفاده بیشتر،
NestedScrollDispatcherSample
را ببینید.
تغییر اندازه تصویر درحین پیمایش
با پیمایش کاربر، میتوانید جلوه دیداری پویایی ایجاد کنید که در آن تصویر براساس موقعیت پیمایش تغییر اندازه میدهد.
تغییر اندازه تصویر براساس موقعیت پیمایش
این گلچین نشان میدهد که چگونه تصویر درون LazyColumn براساس
موقعیت پیمایش عمودی تغییر اندازه میدهد. تصویر با پیمایش کاربر به پایین کوچک میشود و با پیمایش به بالا بزرگ میشود و در محدوده حداقل و حداکثر اندازه تعریفشده باقی میماند:
@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 } ) } }
نکات کلیدی درباره کد
- این کد از
NestedScrollConnectionبرای رهگیری رویدادهای پیمایش استفاده میکند. onPreScrollتغییر اندازه تصویر را براساس پیمایش دلتا محاسبه میکند.- متغیر حالت
currentImageSizeاندازه فعلی تصویر را ذخیره میکند، که بینminImageSizeوmaxImageSize. imageScaleمحدود شده است و ازcurrentImageSizeمشتق میشود. -
LazyColumnبراساسcurrentImageSizeجبران میشود. Imageاز اصلاحکنندهgraphicsLayerبرای اعمال کردن مقیاس محاسبهشده استفاده میکند.translationYدرونgraphicsLayerتضمین میکند که تصویر با مقیاسبندی بهصورت عمودی در مرکز باقی بماند.
نتیجه
تکهکد قبلی منجر به جلوه تصویر مقیاسبندی در پیمایش میشود:
تعامل پیمایش تودرتو
وقتی تلاش میکنید عناصر View پیمایشپذیر را در عناصر ترکیبی پیمایشپذیر تودرتو کنید، یا برعکس، ممکن است با مشکلاتی مواجه شوید. آشکارترین آنها زمانی اتفاق میافتد که کودک را پیمایش میکنید و به مرزهای شروع یا پایان آن میرسید و انتظار دارید ولی پیمایش را ادامه دهد. بااینحال، این رفتار موردانتظار ممکن است اتفاق نیفتد یا ممکن است آنطور که انتظار میرود کار نکند.
این مشکل نتیجه انتظاراتی است که در عناصر ترکیبی پیمایشپذیر ایجاد شده است.
ترکیبهای پیمایشپذیر قانون «پیمایش تودرتو بهطور پیشفرض» را دارند، به این معنی که
هر ظرف پیمایشپذیر باید در زنجیره پیمایش تودرتو شرکت کند، هم بهعنوان
والد ازطریق
NestedScrollConnection،
و هم بهعنوان فرزند ازطریق
NestedScrollDispatcher.
وقتی کودک در مرز باشد، پیمایش تودرتویی را برای ولی هدایت میکند. برای مثال، این قانون به «نوشتن Pager» و «نوشتن LazyRow» اجازه میدهد
با هم خوب کار کنند. بااینحال، وقتی پیمایش میانکنشپذیری با ViewPager2 یا RecyclerView انجام میشود، ازآنجاییکه اینها NestedScrollingParent3 را پیادهسازی نمیکنند، پیمایش پیوسته از فرزند به ولی امکانپذیر نیست.
برای فعال کردن میانای برنامهسازی کاربردی تعاملپذیری پیمایش تودرتو بین عناصر پیمایشپذیر View و
ترکیبپذیرهای پیمایشپذیر، تودرتو در هر دو جهت، میتوانید از میانای برنامهسازی کاربردی تعاملپذیری پیمایش تودرتو برای کاهش این مشکلات در سناریوهای زیر استفاده کنید.
والد همکاریکننده View حاوی کودک ComposeView
والد همکاریکننده View والدی است که ازقبل
NestedScrollingParent3
را پیادهسازی کرده است و بنابراین میتواند تغییرات پیمایشی را از عنصر ترکیبی فرزند تو در تو همکاریکننده دریافت کند. ComposeView در این مورد نقش کودک را ایفا میکند و باید (بهطور غیرمستقیم) NestedScrollingChild3 را پیادهسازی کند.
یک نمونه از ولی همکاریکننده androidx.coordinatorlayout.widget.CoordinatorLayout است.
اگر به قابلیت تعامل پیمایش تودرتو بین پیمایشپذیر View والد
و عناصر ترکیبی پیمایشپذیر تودرتو نیاز دارید، میتوانید از
rememberNestedScrollInteropConnection() استفاده کنید.
rememberNestedScrollInteropConnection()
امکانپذیر میکند و
NestedScrollConnection
را که قابلیت تعامل پیمایش تودرتو را بین والد View که
NestedScrollingParent3
را پیادهسازی میکند و فرزند Compose فعال میکند بهخاطر میسپارد. این باید همراه با
nestedScroll
اصلاحکننده استفاده شود. ازآنجاییکه پیمایش تودرتو بهطور پیشفرض در سمت Compose فعال است، میتوانید از این اتصال برای فعال کردن پیمایش تودرتو در سمت View و افزودن منطق چسب لازم بین Views و عناصر ترکیبی استفاده کنید.
یکی از موارد استفاده رایج استفاده از CoordinatorLayout، CollapsingToolbarLayout، و
ترکیبپذیر فرزند است که در این مثال نشان داده شده است:
<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>
در «فعالیت» یا «تکه»، باید عنصر ترکیبی فرزندتان و
NestedScrollConnection
الزامی را راهاندازی کنید:
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()) } } } } } } }
ترکیبپذیر والد حاوی فرزند AndroidView
این سناریو شامل پیادهسازی API تعامل پیمایش تودرتو در سمت
Compose است - زمانی که یک عنصر ترکیبی والد دارید که حاوی عنصر ترکیبی فرزند
AndroidView است. AndroidView
NestedScrollDispatcher را پیادهسازی میکند،
زیرا بهعنوان فرزند یک والد پیمایشکننده «ترکیب» عمل میکند، و همچنین
NestedScrollingParent3
را پیادهسازی میکند، زیرا بهعنوان والد یک فرزند پیمایشکننده View عمل میکند. والد ترکیبکننده
سپس میتواند دلتاهای پیمایش تودرتو را از فرزند پیمایشپذیر تودرتو دریافت کند
View.
مثال زیر نشان میدهد که چگونه میتوانید در این سناریو، همراه با نوارابزار جمعشونده Compose، به قابلیت تعامل پیمایش تودرتو دست یابید:
@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) {
// ...
}
}
// ...
}
این مثال نشان میدهد که چگونه میتوانید از API با یک اصلاحگر scrollable استفاده کنید:
@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)
}
}
)
}
}
و درنهایت، این مثال نشان میدهد که چگونه از میانای برنامهسازی کاربردی تعامل پیمایش تودرتو با
BottomSheetDialogFragment
برای دستیابی به عملکرد موفق کشیدن و بستن استفاده میشود:
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()
یک
NestedScrollConnection
در عنصری که به آن پیوست میکنید نصب خواهد کرد. NestedScrollConnection مسئول انتقال دلتاها از سطح «نوشتن» به سطح View است. این کار باعث میشود عنصر در پیمایش تودرتو شرکت کند، اما پیمایش عناصر را بهطور خودکار فعال نمیکند. برای عناصر ترکیبی که بهطور خودکار پیمایشپذیر نیستند، مثل Box یا Column، تغییرات پیمایش در چنین عناصری در سیستم پیمایش تودرتو منتشر نمیشود و تغییرات به NestedScrollConnection ارائهشده توسط rememberNestedScrollInteropConnection() نمیرسد، بنابراین این تغییرات به عنصر View والد نمیرسد. برای حل کردن این مشکل،
مطمئن شوید که اصلاحکنندههای پیمایشپذیر را نیز برای این انواع عناصر
ترکیبی تودرتو تنظیم کنید. برای کسب اطلاعات دقیقتر میتوانید به بخش قبلی درباره پیمایش تودرتو مراجعه کنید.
ولی غیرهمکار View که کودکی را دربردارد ComposeView
«نمای» غیرهمکار نمایی است که رابطهای NestedScrolling لازم را در سمت View پیادهسازی نمیکند. توجه داشته باشید که این یعنی
قابلیت همکاری پیمایش تودرتو با این Views بهطور پیشفرض کار نمیکند. Views غیرهمکار عبارتاند از RecyclerView و ViewPager2.
منابع بیشتر
توصیهشده برای شما
- توجه: نوشتار پیوند وقتی جاوا اسکریپت خاموش است نمایش داده میشود
- آشنایی با اشارهها
- انتقال
CoordinatorLayoutبه «نگارش» - استفاده از «نماها» در «نوشتن»