অনেক কম্পোজেবলে ট্যাপ বা ক্লিকের জন্য বিল্ট-ইন সাপোর্ট আছে এবং এতে একটি
onClick ল্যাম্বডা অন্তর্ভুক্ত আছে। যেমন, আপনি ক্লিক করা যায় এমন Surface তৈরি করতে পারেন যা
সারফেসের সাথে ইন্টার্যাকশনের জন্য উপযুক্ত সব মেটেরিয়াল ডিজাইন আচরণ অন্তর্ভুক্ত করে:
Surface(onClick = { /* handle click */ }) { Text("Click me!", Modifier.padding(24.dp)) }
তবে, ক্লিক করা ছাড়াও ব্যবহারকারী অন্য উপায়ে কম্পোজেবলের সাথে ইন্টার্যাক্ট করতে পারেন। এই পৃষ্ঠাটি এমন জেসচারের উপর ফোকাস করে যাতে একটি মাত্র পয়েন্টার থাকে, যেখানে সেই পয়েন্টারের অবস্থান সেই ইভেন্ট ম্যানেজ করার জন্য গুরুত্বপূর্ণ নয়। নিচের সারণীতে এই ধরনের জেসচারের তালিকা দেওয়া হল:
জেসচার |
বিবরণ |
ট্যাপ (বা ক্লিক) করুন |
পয়েন্টার নিচে এবং তারপর উপরে যায় |
ডবল ট্যাপ |
পয়েন্টার নিচে, উপরে, নিচে, উপরে যায় |
দীর্ঘ সময় ধরে চাপুন |
পয়েন্টার নিচে যায় এবং আরও বেশি সময় ধরে থাকে |
প্রেস |
পয়েন্টার নিচের দিকে যায় |
ট্যাপ বা ক্লিকে সাড়া দিন
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, যা ডিফল্ট হিসেবে রিপল এফেক্ট দেখায় যখন ব্যবহারকারী কম্পোজ করার উপযুক্ত আইটেমে ট্যাপ করেন। ব্যবহারকারীর ইন্টার্যাকশন ম্যানেজ করা পৃষ্ঠা থেকে কীভাবে এগুলি কাস্টমাইজ করবেন তা জানুন।- সেম্যান্টিক্স তথ্য সেট করার মাধ্যমে অ্যাক্সেসিবিলিটি পরিষেবাকে এলিমেন্টের সাথে ইন্টার্যাক্ট করার অনুমতি দেয়।
- ইন্টার্যাক্ট করার জন্য ফোকাস ও প্রেস করার অনুমতি দিয়ে কীবোর্ড বা জয়স্টিক ইন্টার্যাকশনকে সাপোর্ট করে
Enterবা ডি-প্যাডের কেন্দ্র ইন্টার্যাক্ট করার জন্য। - এলিমেন্টটি হোভার করার উপযুক্ত করুন, যাতে এটি মাউস বা স্টাইলাস হোভার করার সময় প্রতিক্রিয়া জানায়।
প্রাসঙ্গিক কনটেক্সট মেনু দেখতে বেশিক্ষণ প্রেস করে রাখুন
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 আচরণ মানিয়ে নেওয়ার চেষ্টা করার পরিবর্তে, আপনি
নিম্নতর অ্যাবস্ট্রাকশন লেভেলে নেমে আসতে পারেন এবং detectTapGestures পদ্ধতির সাথে
pointerInput মডিফায়ার সরাসরি ব্যবহার করতে পারেন:
@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 ল্যাম্বডা পাস করেন। এটি
ল্যাম্বডাকে অটোমেটিক আবার এক্সিকিউট করে, যাতে ব্যবহারকারী স্ক্রিমে ট্যাপ করলে
সঠিক কলব্যাক কল করা হয়।
জুম করতে ডবল-ট্যাপ করুন
কখনও কখনও clickable এবং combinedClickable-এ সঠিক উপায়ে ইন্টার্যাকশনের উত্তর দেওয়ার জন্য
পর্যাপ্ত তথ্য থাকে না। যেমন, কম্পোজেবল বাউন্ডের মধ্যে যেখানে ইন্টার্যাকশন হয়েছে, কম্পোজেবলকে সেই পজিশন অ্যাক্সেস করতে হতে পারে।
আসুন, ছবির বিবরণ সংক্রান্ত স্ক্রিনটি আবার দেখা যাক। ডবল ট্যাপ করে ছবিতে জুম করার সুবিধা দেওয়া একটি ভালো পদ্ধতি:
ভিডিওতে যেমন দেখতে পাচ্ছেন, ট্যাপ ইভেন্টের পজিশনের চারপাশে জুম ইন
হয়। ছবির বাঁদিকের অংশ বড় করলে যে ফলাফল পাওয়া যায়, ডানদিকের অংশ বড় করলে
তার থেকে আলাদা ফলাফল পাওয়া যায়। আমরা detectTapGestures-এর সাথে pointerInput মডিফায়ার ব্যবহার করে
ট্যাপ করার পজিশন আমাদের গণনার মধ্যে
অন্তর্ভুক্ত করতে পারি:
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 } )
আপনার জন্য সাজেস্ট করা হয়েছে
- মনে রাখবেন: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট দেখানো হয়
- জেসচার সম্পর্কে বোঝা
- Compose-এ Material Design 2
- Jetpack Compose-এর জন্য Kotlin