Jetpack Compose 12: Mastering Gestures and Touch Interactions
Teqani Blogs
Writer at Teqani
In modern UI development, touch interactions are paramount. This article delves into how Jetpack Compose simplifies handling various gestures, offering a range of APIs from simple taps to intricate zoom and pan interactions. We will explore different Modifiers that can be used to implement gesture recognition, as well as the handling of touch events, empowering developers to create truly interactive user experiences.
في تطوير واجهات المستخدم الحديثة، تعد تفاعلات اللمس ذات أهمية قصوى. تتعمق هذه المقالة في كيفية تبسيط Jetpack Compose للتعامل مع الإيماءات المختلفة، وتقدم مجموعة من واجهات برمجة التطبيقات (APIs) تتراوح من النقرات البسيطة إلى تفاعلات التكبير والتحريك المعقدة. سوف نستكشف مُعدِّلات مختلفة يمكن استخدامها لتنفيذ التعرف على الإيماءات، بالإضافة إلى التعامل مع أحداث اللمس، مما يمكّن المطورين من إنشاء تجارب مستخدم تفاعلية حقًا.
1. Modifier.pointerInput – Low-Level Gesture Detection
The Modifier.pointerInput
allows you to detect taps, long presses, drags, and other gestures using suspending gesture detectors. This provides fine-grained control over touch behavior, ideal for custom gesture implementations.
يسمح لك Modifier.pointerInput
بالكشف عن النقرات والضغطات الطويلة والسحب والإيماءات الأخرى باستخدام كاشفات الإيماءات المعلقة. يوفر هذا تحكمًا دقيقًا في سلوك اللمس، وهو مثالي لتطبيقات الإيماءات المخصصة.
Example:
@Composable
fun PointerInputExample() {
Box(
modifier = Modifier
.size(200.dp)
.background(Color.LightGray)
.pointerInput(Unit) {
detectTapGestures(
onTap = { offset ->
println("Tapped at $offset")
},
onLongPress = {
println("Long pressed!")
}
)
}
) {
Text("Tap or Long Press", modifier = Modifier.align(Alignment.Center))
}
}
2. Modifier.transformable – Pan, Zoom, Rotate
Use Modifier.transformable
for implementing scale and rotation gestures, commonly used on images or maps. This modifier simplifies the implementation of pan, zoom, and rotate functionalities.
استخدم Modifier.transformable
لتنفيذ إيماءات المقياس والتدوير، والتي يشيع استخدامها في الصور أو الخرائط. يعمل هذا المُعدِّل على تبسيط تنفيذ وظائف التحريك والتكبير والتدوير.
Example:
@Composable
fun TransformableExample() {
var scale by remember { mutableStateOf(1f) }
var rotation by remember { mutableStateOf(0f) }
var offset by remember { mutableStateOf(Offset.Zero) }
val state = rememberTransformableState { zoomChange, rotationChange, offsetChange ->
scale *= zoomChange
rotation += rotationChange
offset += offsetChange
}
Box(
modifier = Modifier
.size(250.dp)
.graphicsLayer(
scaleX = scale,
scaleY = scale,
rotationZ = rotation,
translationX = offset.x,
translationY = offset.y
)
.background(Color.Cyan)
.transformable(state)
) {
Text("Pinch, Drag, Rotate", modifier = Modifier.align(Alignment.Center))
}
}
3. Modifier.swipeable – Swipe-Based UI Control
Create swipe actions such as dismiss, toggle, or sliding panels using Modifier.swipeable
. This is suitable for implementing swipe-based controls within your UI.
أنشئ إجراءات التمرير مثل الرفض أو التبديل أو اللوحات المنزلقة باستخدام Modifier.swipeable
. هذا مناسب لتنفيذ عناصر التحكم المستندة إلى التمرير داخل واجهة المستخدم الخاصة بك.
Example:
@Composable
fun SwipeableExample() {
val width = 300f
val swipeState = rememberSwipeableState(0)
val anchors = mapOf(0f to 0, width to 1)
Box(
modifier = Modifier
.width(width.dp)
.height(100.dp)
.background(Color.LightGray)
.swipeable(
state = swipeState,
anchors = anchors,
thresholds = { _, _ -> FractionalThreshold(0.3f) },
orientation = Orientation.Horizontal
)
) {
Box(
modifier = Modifier
.offset { IntOffset(swipeState.offset.value.roundToInt(), 0) }
.fillMaxSize()
.background(Color.Green)
) {
Text("Swipe Me", modifier = Modifier.align(Alignment.Center))
}
}
}
4. Modifier.pointerInteropFilter – Handle Raw MotionEvent
When interoperability with the traditional Android touch system is required, use Modifier.pointerInteropFilter
to handle raw MotionEvent
s. This is helpful for integrating legacy views or gestures.
عندما تكون هناك حاجة إلى التشغيل البيني مع نظام اللمس التقليدي لنظام Android، استخدم Modifier.pointerInteropFilter
للتعامل مع MotionEvent
s الخام. هذا مفيد لدمج طرق العرض أو الإيماءات القديمة.
Example:
@Composable
fun PointerInteropExample() {
Box(
modifier = Modifier
.size(200.dp)
.background(Color.Yellow)
.pointerInteropFilter {
when (it.action) {
MotionEvent.ACTION_DOWN -> {
println("Finger down at: ${it.x}, ${it.y}")
true
}
MotionEvent.ACTION_UP -> {
println("Finger up!")
true
}
else -> false
}
}
) {
Text("Interop Touch", modifier = Modifier.align(Alignment.Center))
}
}
pointerInput
: Tap, drag, long press, raw gesturestransformable
: Pinch, zoom, rotate, and drag gesturesswipeable
: Swipe actions like toggle or dismisspointerInteropFilter
: Use raw MotionEvents like Android XML
All blogs are certified by our company and reviewed by our specialists
Issue Number: #a08ef291-dbbc-4b40-aeef-ac59acf88342