بسیاری از composable ها دارای پشتیبانی داخلی برای ضربه زدن یا کلیک هستند و شامل onClick
lambda هستند. به عنوان مثال، می توانید یک Surface
قابل کلیک ایجاد کنید که شامل تمام رفتارهای طراحی متریال مناسب برای تعامل با سطوح باشد:
Surface(onClick = { /* handle click */ }) { Text("Click me!", Modifier.padding(24.dp)) }
اما کلیک ها تنها راهی نیستند که کاربر می تواند با composable ها تعامل داشته باشد. این صفحه روی حرکاتی متمرکز است که شامل یک اشاره گر هستند، جایی که موقعیت آن اشاره گر برای مدیریت آن رویداد مهم نیست. جدول زیر این نوع حرکات را فهرست می کند:
ژست | توضیحات |
ضربه بزنید (یا کلیک کنید) | اشاره گر پایین و سپس بالا می رود |
دو ضربه سریع بزنید | اشاره گر پایین، بالا، پایین، بالا می رود |
فشار طولانی | اشاره گر پایین می آید و برای مدت طولانی تری نگه داشته می شود |
را فشار دهید | اشاره گر پایین می رود |
به ضربه زدن یا کلیک کردن پاسخ دهید
clickable
یک اصلاح کننده متداول است که باعث می شود یک ترکیب کننده به ضربه ها یا کلیک ها واکنش نشان دهد. این اصلاحکننده همچنین ویژگیهای دیگری مانند پشتیبانی از فوکوس، شناور شدن ماوس و قلم، و یک نشانه بصری قابل تنظیم هنگام فشار دادن را اضافه میکند. اصلاحکننده به «کلیکها» در وسیعترین معنای کلمه پاسخ میدهد - نه تنها با ماوس یا انگشت، بلکه رویدادهای کلیک را از طریق ورودی صفحهکلید یا هنگام استفاده از سرویسهای دسترسپذیری نیز انجام میدهد.
شبکهای از تصاویر را تصور کنید، جایی که وقتی کاربر روی آن کلیک میکند، تصویری تمام صفحه نشان داده میشود:
برای اجرای این رفتار می توانید اصلاح کننده clickable
را به هر مورد در شبکه اضافه کنید:
@Composable private fun ImageGrid(photos: List<Photo>) { var activePhotoId by rememberSaveable { mutableStateOf<Int?>(null) } LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 128.dp)) { items(photos, { it.id }) { photo -> ImageItem( photo, Modifier.clickable { activePhotoId = photo.id } ) } } if (activePhotoId != null) { FullScreenImage( photo = photos.first { it.id == activePhotoId }, onDismiss = { activePhotoId = null } ) } }
اصلاح کننده clickable
نیز رفتار اضافی را اضافه می کند:
-
interactionSource
وindication
، که به طور پیشفرض هنگامی که کاربر روی composable ضربه میزند، یک موج میکشد. نحوه سفارشی کردن این موارد را در صفحه مدیریت تعاملات کاربر بیاموزید. - به سرویسهای دسترسپذیری اجازه میدهد با تنظیم اطلاعات معنایی با عنصر تعامل داشته باشند.
- از تعامل صفحه کلید یا جوی استیک با اجازه دادن به فوکوس و فشار دادن
Enter
یا مرکز d-pad برای تعامل پشتیبانی می کند. - عنصر را قابل شناور سازید، بنابراین به شناور شدن ماوس یا قلم روی آن پاسخ دهد.
برای نمایش منوی زمینه متنی، فشار طولانی دهید
combinedClickable
به شما امکان می دهد تا رفتار دوبار ضربه یا فشار طولانی را علاوه بر رفتار کلیک معمولی اضافه کنید. وقتی کاربر تصویر شبکه ای را لمس می کند و نگه می دارد، می توانید از combinedClickable
برای نشان دادن منوی زمینه استفاده کنید:
var contextMenuPhotoId by rememberSaveable { mutableStateOf<Int?>(null) } val haptics = LocalHapticFeedback.current LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 128.dp)) { items(photos, { it.id }) { photo -> ImageItem( photo, Modifier .combinedClickable( onClick = { activePhotoId = photo.id }, onLongClick = { haptics.performHapticFeedback(HapticFeedbackType.LongPress) contextMenuPhotoId = photo.id }, onLongClickLabel = stringResource(R.string.open_context_menu) ) ) } } if (contextMenuPhotoId != null) { PhotoActionsSheet( photo = photos.first { it.id == contextMenuPhotoId }, onDismissSheet = { contextMenuPhotoId = null } ) }
به عنوان بهترین روش، زمانی که کاربر عناصر را به مدت طولانی فشار می دهد، باید بازخورد لمسی را وارد کنید، به همین دلیل است که قطعه شامل فراخوان performHapticFeedback
است.
با ضربه زدن روی یک اسکریم، یک قابل ترکیب را رد کنید
در مثالهای بالا، clickable
و combinedClickable
قابلیتهای مفیدی را به فایلهای ترکیبی شما اضافه میکنند. آنها یک نشانه بصری در تعامل نشان می دهند، به شناور شدن پاسخ می دهند و شامل فوکوس، صفحه کلید و پشتیبانی دسترسی هستند. اما این رفتار اضافی همیشه مطلوب نیست.
بیایید به صفحه جزئیات تصویر نگاه کنیم. پسزمینه باید نیمه شفاف باشد و کاربر باید بتواند روی آن پسزمینه ضربه بزند تا صفحه جزئیات را نادیده بگیرد:
در این مورد، آن پسزمینه نباید هیچ نشانه بصری در مورد تعامل داشته باشد، نباید به شناور بودن پاسخ دهد، نباید قابل فوکوس باشد و پاسخ آن به رویدادهای صفحهکلید و دسترسی متفاوت از یک ترکیب معمولی است. به جای تلاش برای تطبیق رفتار clickable
، می توانید به سطح انتزاعی پایین تری رها کنید و مستقیماً از اصلاح کننده pointerInput
در ترکیب با متد detectTapGestures
استفاده کنید:
@Composable private fun Scrim(onClose: () -> Unit, modifier: Modifier = Modifier) { val strClose = stringResource(R.string.close) Box( modifier // handle pointer input .pointerInput(onClose) { detectTapGestures { onClose() } } // handle accessibility services .semantics(mergeDescendants = true) { contentDescription = strClose onClick { onClose() true } } // handle physical keyboard input .onKeyEvent { if (it.key == Key.Escape) { onClose() true } else { false } } // draw scrim .background(Color.DarkGray.copy(alpha = 0.75f)) ) }
به عنوان کلید تغییر دهنده pointerInput
لامبدا onClose
را ارسال می کنید. این به طور خودکار لامبدا را مجدداً اجرا میکند، و مطمئن میشود که وقتی کاربر روی scrim ضربه میزند، تماس صحیح فراخوانی میشود.
برای بزرگنمایی دو ضربه سریع بزنید
گاهی اوقات clickable
و combinedClickable
دارای اطلاعات کافی برای پاسخگویی صحیح به تعامل نیستند. به عنوان مثال، کامپوزیشنها ممکن است نیاز به دسترسی به موقعیتی در محدودههای ترکیبپذیر داشته باشند که در آن تعامل صورت گرفته است.
بیایید دوباره به صفحه جزئیات تصویر نگاه کنیم. بهترین روش این است که با دو ضربه زدن روی تصویر بزرگنمایی کنید:
همانطور که در ویدیو می بینید، بزرگنمایی در اطراف موقعیت رویداد ضربه زدن انجام می شود. نتیجه زمانی متفاوت است که روی قسمت چپ تصویر در مقابل قسمت سمت راست بزرگنمایی کنیم. میتوانیم از اصلاحکننده pointerInput
در ترکیب با detectTapGestures
استفاده کنیم تا موقعیت ضربه را در محاسبات خود بگنجانیم:
var zoomed by remember { mutableStateOf(false) } var zoomOffset by remember { mutableStateOf(Offset.Zero) } Image( painter = rememberAsyncImagePainter(model = photo.highResUrl), contentDescription = null, modifier = modifier .pointerInput(Unit) { detectTapGestures( onDoubleTap = { tapOffset -> zoomOffset = if (zoomed) Offset.Zero else calculateOffset(tapOffset, size) zoomed = !zoomed } ) } .graphicsLayer { scaleX = if (zoomed) 2f else 1f scaleY = if (zoomed) 2f else 1f translationX = zoomOffset.x translationY = zoomOffset.y } )
برای شما توصیه می شود
- توجه: وقتی جاوا اسکریپت خاموش است، متن پیوند نمایش داده می شود
- ژست ها را درک کنید
- Material Design 2 در Compose
- Kotlin برای Jetpack Compose