ব্যবহারকারীদের স্ক্রিন জুড়ে কম্পোনেন্ট শারীরিকভাবে টেনে আনার সুবিধা দেওয়া আধুনিক Android অ্যাপের জন্য মৌলিক বিষয়। আপনি কাস্টম স্লাইডার, সোয়াইপ-টু-ডিসমিস কম্পোনেন্ট বা ইন্টার্যাক্টিভ ক্যানভাস, যাই তৈরি করুন না কেন, Jetpack Compose-এ ড্র্যাগ ইভেন্ট সহজে ম্যানেজ করার জন্য API-এর একটি বিস্তৃত সেট রয়েছে।
Compose ড্র্যাগিং API, র টাচ ইভেন্টের জটিলতা থেকে দূরে থাকে।
ম্যানুয়ালি টাচ কোঅর্ডিনেট হিসেব করা এবং pointerInput-এর মাধ্যমে জেসচার
লাইফসাইকেল ম্যানেজ করার পরিবর্তে, আপনি বিল্ট-ইন মডিফায়ার ব্যবহার করতে পারেন যা
সরাসরি Compose-এর স্টেট ম্যানেজমেন্ট এবং অ্যানিমেশন সিস্টেমের সাথে যুক্ত থাকে।
এই পৃষ্ঠায় প্রতিটি ড্র্যাগিং API কীভাবে এবং কখন ব্যবহার করতে হবে তা বর্ণনা করা হয়েছে।
সঠিক ড্র্যাগিং API বেছে নিন
ড্র্যাগ করা যায় এমন কন্টেন্ট প্রয়োগ করার জন্য আপনি একাধিক API ব্যবহার করতে পারেন।
- স্ট্যান্ডার্ড মেটেরিয়াল কম্পোনেন্ট (যেমন
SwipeToDismissBoxবা নেভিগেশন ড্রয়ার) বেছে নিন যখন: আপনার ডিফল্ট মেটেরিয়াল ৩ সোয়াইপ বা ড্র্যাগ ব্যবহার প্রয়োজন (যেমন, ইমেল মুছে ফেলা, টাস্ক আর্কাইভ করা বা সাইড মেনু / স্ক্রিনের নিচে অ্যাটাচ করা শিট খোলা)। কাস্টম স্টেট বা লেআউট ম্যানেজমেন্টের প্রয়োজন ছাড়াই এগুলি বিল্ট-ইন আচরণ প্রদান করে। - কখন
Modifier.draggableবেছে নেবেন: আপনার শুধু র' ড্র্যাগ ডেল্টা প্রয়োজন (যেমন, কাস্টম স্লাইডার ড্র্যাগ করা)। আরও তথ্যের জন্য, ড্র্যাগেবল সহ একটি অক্ষ বরাবর টেনে আনুন দেখুন।- কখন
Modifier.draggable2Dবেছে নেবেন: X ও Y অক্ষ বরাবর কোনও কম্পোনেন্টকে একটানা সরাতে হলে (যেমন, ম্যাপ প্যান করা বা ফ্লোটিং অ্যাকশন বোতাম তৈরি করা, যা ব্যবহারকারী স্ক্রিনের যেকোনও জায়গায় টেনে নিয়ে যেতে পারেন)। আরও তথ্যের জন্য,Modifier.draggable2D-এর সাহায্যে দুই ডাইমেনশনে ড্র্যাগ করুন দেখুন।
- কখন
- কখন
Modifier.anchoredDraggableবেছে নেবেন: আপনি যখন কাস্টম ইন্টার্যাক্টিভ কম্পোনেন্ট তৈরি করছেন যা দুই বা তার বেশি আলাদা পজিশনের মধ্যে স্ন্যাপ করতে হবে (যেমন, স্ক্রিনের নিচে অ্যাটাচ করা শিট, নেভিগেশন ড্রয়ার বা সোয়াইপ-টু-রিভিল অ্যাকশন)। আরও তথ্যের জন্য,anchoredDraggableব্যবহার করে অ্যাঙ্কর পয়েন্টের মধ্যে কম্পোনেন্ট টেনে আনুন দেখুন।
draggable-এর সাহায্যে একটি অক্ষ বরাবর টানুন
draggable মডিফায়ার হল একটি ওরিয়েন্টেশনে ড্র্যাগ জেসচার করার হাই-লেভেল এন্ট্রি পয়েন্ট
এবং এটি পিক্সেলে ড্র্যাগ করার দূরত্ব রিপোর্ট করে।
মনে রাখবেন যে এই মডিফায়ার scrollable-এর মতোই, কারণ এটি
শুধুমাত্র জেসচার শনাক্ত করে। আপনাকে স্টেট ধরে রাখতে হবে এবং স্ক্রিনে এটি দেখাতে হবে
যেমন, offset মডিফায়ারের মাধ্যমে এলিমেন্ট সরানোর মাধ্যমে:
@Composable private fun DraggableText() { var offsetX by remember { mutableFloatStateOf(0f) } Text( modifier = Modifier .offset { IntOffset(offsetX.roundToInt(), 0) } .draggable( orientation = Orientation.Horizontal, state = rememberDraggableState { delta -> offsetX += delta } ), text = "Drag me!" ) }
আপনি যদি পুরো ড্র্যাগিং জেসচার নিয়ন্ত্রণ করতে চান, তাহলে pointerInput মডিফায়ারের মাধ্যমে
ড্র্যাগ জেসচার ডিটেক্টর ব্যবহার করার কথা বিবেচনা করুন।
@Composable private fun DraggableTextLowLevel() { Box(modifier = Modifier.fillMaxSize()) { var offsetX by remember { mutableFloatStateOf(0f) } var offsetY by remember { mutableFloatStateOf(0f) } Box( Modifier .offset { IntOffset(offsetX.roundToInt(), offsetY.roundToInt()) } .background(Color.Blue) .size(50.dp) .pointerInput(Unit) { detectDragGestures { change, dragAmount -> change.consume() offsetX += dragAmount.x offsetY += dragAmount.y } } ) } }
anchoredDraggable-এর সাহায্যে অ্যাঙ্কর পয়েন্টের মধ্যে কম্পোনেন্ট টেনে আনুন
anchoredDraggable মডিফায়ার আপনাকে অ্যাঙ্কর পয়েন্ট নামে পরিচিত পূর্বনির্ধারিত পজিশনের সেটের মধ্যে
কোনও কম্পোনেন্ট টেনে নিয়ে যেতে দেয়। ব্যবহারকারী টেনে আনার জেসচার
ছেড়ে দিলে, কম্পোনেন্টটি সবচেয়ে কাছের অ্যাঙ্করে সেট হয়ে যায়। anchoredDraggable
কাস্টম স্ক্রিনের নিচে অ্যাটাচ করা শিট, জটিল স্লাইডার বা ড্রয়ার প্যানেলের মতো কম্পোনেন্ট
তৈরি করার জন্য উপযোগী।
API সারফেস
AnchoredDraggable API-এর মধ্যে নিম্নলিখিত প্রধান অংশগুলি রয়েছে:
- Anchors (
DraggableAnchors): একটি বিল্ডার যা আপনার কাস্টম স্টেট (যেমন,Start, Center, End-এর জন্য একটি enum ক্লাস) এবং তাদের সংশ্লিষ্ট পিক্সেল অফসেট মানের মধ্যে ম্যাপিং সংজ্ঞায়িত করে। - স্টেট (
AnchoredDraggableState<T>): একটি স্টেট হোল্ডার যা কম্পোনেন্টের বর্তমান পজিশন (অফসেট), এটি যে অ্যাঙ্করে সেট করা আছে এবং এর ড্র্যাগ প্রগ্রেস ম্যানেজ করে। কনফিগারেশন পরিবর্তন জুড়ে এর অবস্থা সংরক্ষণ করতেrememberSaveableএবংAnchoredDraggableState.Saver<T>ব্যবহার করে এটি তৈরি করা উচিত। - জেসচার মডিফায়ার (
Modifier.anchoredDraggable): এমন একটি মডিফায়ার যাOrientationবরাবর ড্র্যাগ জেসচার শনাক্ত করে, ড্র্যাগ ডেল্টার মাধ্যমে স্ট্যাটাস আপডেট করে এবং রিলিজ করার সময় কম্পোনেন্টকে নিকটতম অ্যাঙ্করে অ্যানিমেট করার জন্য ফ্লিং জেসচার ম্যানেজ করে।
উদাহরণ: কাস্টম SwipeToDismiss কম্পোনেন্ট তৈরি করুন
এই উদাহরণে দেখানো হয়েছে কীভাবে একটি কাস্টম SwipeToDismiss কম্পোনেন্ট (একটি
সাদা ব্যানার) তৈরি করা যায় যা ব্যবহারকারী খারিজ করার জন্য বাঁদিকে সোয়াইপ করতে পারেন অথবা ওভারস্ক্রল স্ট্রেচ এফেক্ট
দেখার জন্য ডানদিকে টেনে আনতে পারেন।
অ্যাঙ্কর ভ্যালু নির্ধারণ করুন। ড্র্যাগ করা যায় এমন কন্টেন্ট যে আলাদা আলাদা পজিশনে সেটেল হতে পারে সেগুলি দেখানোর জন্য একটি enum নির্ধারণ করুন:
private enum class AnchoredDraggableSwipeDismissValue { DismissedStart, Resting }
ইনস্ট্যান্টিয়েট করে
AnchoredDraggableStateসেভ করুন। অ্যাক্টিভিটি রিক্রিয়েশন এবং কনফিগারেশন পরিবর্তন (যেমন, স্ক্রিন ঘোরানো বা থিম পরিবর্তন) জুড়ে কম্পোনেন্টের বর্তমান পজিশন অপরিবর্তিত রাখতেAnchoredDraggableState.Saver()-এর সাথেrememberSaveableব্যবহার করুন:val state = rememberSaveable(saver = AnchoredDraggableState.Saver()) { AnchoredDraggableState(initialValue = AnchoredDraggableSwipeDismissValue.Resting) }
layout,offsetওdraggableমডিফায়ার প্রয়োগ করুন। কম্পোনেন্টকে ড্র্যাগেবল করতে এবং এর অ্যাঙ্কর পয়েন্ট যাতে এর সাইজের সাথে মানানসই হয় তা নিশ্চিত করতে, যে কন্টেন্টকে ভিজ্যুয়ালি সরাতে হবে তাতে নিম্নলিখিত মডিফায়ার প্রয়োগ করুন:Modifier.layout: অ্যাঙ্কর পজিশন প্রায়ই কম্পোনেন্টের সাইজের উপর নির্ভর করে, যা প্রাথমিক কম্পোজিশনের সময় জানা যায় না। কম্পোনেন্ট পরিমাপ করতেlayoutমডিফায়ার ব্যবহার করুন, এর প্রস্থের উপর ভিত্তি করে ডায়নামিক্যালিDraggableAnchorsম্যাপ হিসেব করুন এবংstate.updateAnchors()ব্যবহার করে স্ট্যাটাস আপডেট করুন।
Modifier.anchoredDraggable: স্টেটের সাথে কানেক্ট করে, নির্দিষ্ট ওরিয়েন্টেশনে ড্র্যাগ ডেল্টা ডিসপ্যাচ করে এবং রিলিজ করার সময় কম্পোনেন্টকে সবচেয়ে কাছের অ্যাঙ্করে অ্যানিমেট করার জন্য ফ্লিং জেসচার ম্যানেজ করে। এই মডিফায়ারটি সেই কম্পোনেন্টে যোগ করুন যা টেনে আনার জেসচারে সাড়া দেবে এবং এটিকেstateএবং টেনে আনারorientation(এবং, বিকল্প হিসেবে,overscrollEffect) পাস করবে।Modifier.offset: অফসেট ল্যাম্বডার মধ্যেstate.requireOffset()থেকে অফসেট পড়ে। এই ল্যাম্বডার মধ্যে অফসেট রিড করলে এটি নিশ্চিত হয় যে ভ্যালুটি শুধুমাত্র প্লেসমেন্ট ফেজের সময় রিড করা হয়, যার ফলে ড্র্যাগ করার সময় অপ্রয়োজনীয় রিকম্পোজিশন এড়ানো যায়। এই মডিফায়ারটি সেই কন্টেন্টে প্রয়োগ করুন যা ভিজ্যুয়ালি সরানো উচিত।
Box( modifier = Modifier .fillMaxWidth() // Read state.requireOffset() inside the offset lambda to defer reading to the placement phase .offset { IntOffset(state.requireOffset().roundToInt(), 0) } .layout { measurable, constraints -> val placeable = measurable.measure(constraints) val anchors = DraggableAnchors { AnchoredDraggableSwipeDismissValue.DismissedStart at -placeable.width.toFloat() AnchoredDraggableSwipeDismissValue.Resting at 0f } state.updateAnchors(anchors) layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) } } // Pass overscrollEffect to anchoredDraggable so deltas beyond the bounds (min and max anchor) are dispatched to overscrollEffect, and render the visual effect with Modifier.overscroll. .overscroll(overscrollEffect) .anchoredDraggable( state, Orientation.Horizontal, overscrollEffect = overscrollEffect ) ) { dismissContent() }
[ঐচ্ছিক] ওভারস্ক্রল ইন্টিগ্রেট করুন।
overscrollEffectAPI এমন একটি ভিজ্যুয়াল এফেক্ট প্রয়োগ করে যা স্ক্রল বা ফ্লিং করার মাধ্যমে স্ক্রলিং কন্টেনারের প্রান্তে পৌঁছালে দেখা যায়। ব্যবহারকারী ওভারস্ক্রল এফেক্ট (সাধারণত স্ট্রেচ বা গ্লো) সহ নির্দিষ্ট অ্যাঙ্কর বাউন্ডের বাইরে টেনে নিয়ে গেলে আপনি ভিজ্যুয়াল মতামত দিতে পারবেন।- ডিসপ্যাচ:
anchoredDraggableমডিফায়ারে একটিoverscrollEffectইনস্ট্যান্স পাস করুন। এটি ড্র্যাগ ডেল্টাকেAnchoredDraggableস্টেট বা ওভারস্ক্রল এফেক্টে পাঠায়, যা নির্ভর করে জেসচারটি অ্যাঙ্কর বাউন্ডের ভিতরে নাকি বাইরে আছে তার উপর। - Render: একই
OverscrollEffectইনস্ট্যান্সের সাথেModifier.overscrollকম্পোনেন্টে প্রয়োগ করুন যা এফেক্টকে ভিজ্যুয়ালি রেন্ডার করবে।
- ডিসপ্যাচ:
নিচের স্নিপেট থেকে বোঝা যাবে যে কীভাবে স্ট্যান্ডার্ড স্ট্রেচ এফেক্ট যোগ করতে হয়:
val overscrollEffect = rememberOverscrollEffect() Box( modifier.fillMaxWidth() ) { Box(Modifier.fillMaxWidth()) { background() } Box( modifier = Modifier .fillMaxWidth() // Read state.requireOffset() inside the offset lambda to defer reading to the placement phase .offset { IntOffset(state.requireOffset().roundToInt(), 0) } .layout { measurable, constraints -> val placeable = measurable.measure(constraints) val anchors = DraggableAnchors { AnchoredDraggableSwipeDismissValue.DismissedStart at -placeable.width.toFloat() AnchoredDraggableSwipeDismissValue.Resting at 0f } state.updateAnchors(anchors) layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) } } // Pass overscrollEffect to anchoredDraggable so deltas beyond the bounds (min and max anchor) are dispatched to overscrollEffect, and render the visual effect with Modifier.overscroll. .overscroll(overscrollEffect) .anchoredDraggable( state, Orientation.Horizontal, overscrollEffect = overscrollEffect ) ) { dismissContent() } }
ফলাফল
আগের কোড স্নিপেটের ফলে "বাতিল করতে আমাকে টেনে আনুন!" টেক্সট সহ একটি সাদা ব্যানার দেখা যায়, যেটি ব্যবহারকারী বাতিল করতে বাঁদিকে সোয়াইপ করতে পারেন (অথবা ওভারস্ক্রল স্ট্রেচ এফেক্ট দেখতে ডানদিকে টেনে আনতে পারেন):
উদাহরণ: কাস্টম, জেসচার-চালিত নেভিগেশন ড্রয়ার তৈরি করুন
এই উদাহরণে দেখানো হয়েছে কীভাবে কাস্টম, জেসচার-চালিত নেভিগেশন ড্রয়ার
তৈরি করতে হয়। ব্যবহারকারী অনুভূমিকভাবে টেনে আনলে, ফোরগ্রাউন্ড স্ক্রিন (ScreenContents)
ডানদিকে স্লাইড করে, 1.0f থেকে 0.8f-এ স্কেল ডাউন করে এবং এর কোণগুলি গোল করে
যাতে নিচে থাকা নেভিগেশন ড্রয়ার দেখা যায়।
অ্যাঙ্কর স্টেট ও পজিশন নির্ধারণ করুন। এই উদাহরণে, ড্রয়ারের খোলা ও বন্ধ অবস্থা হল অ্যাঙ্কর।
OpenএবংClosedঅবস্থার জন্য একটি enum নির্ধারণ করুন এবংDraggableAnchorsব্যবহার করে সেগুলিকে পিক্সেল অফসেটে ম্যাপ করুন:enum class DrawerState { Open, Closed } val anchors = DraggableAnchors { DrawerState.Open at drawerWidth DrawerState.Closed at 0f } val state = remember { AnchoredDraggableState( initialValue = DrawerState.Closed, anchors = anchors, ) }
কোনও আইটেমে ক্লিক করলে
anchoredDraggableStateঅ্যানিমেট করুন।Box-এর নিচেHomeScreenDrawerএবং উপরেScreenContentsরাখুন। ড্রয়ারটি স্থির থাকে, যখন উপরের লেয়ারটি অনুবাদ করে এবং এর উপরে স্কেল করে।ব্যবহারকারী ড্রয়ার আইটেম বেছে নিলে, অ্যাক্টিভ স্ক্রিন স্ট্যাটাস আপডেট করুন এবং
state.animateTo(DrawerState.Closed)ব্যবহার করে অটোমেটিক ড্রয়ার বন্ধ করুন:@Composable private fun AnchoredDraggableDrawerOnClickSample( modifier: Modifier = Modifier, state: AnchoredDraggableState<DrawerState>, coroutineScope: CoroutineScope ) { var screenState by remember { mutableStateOf(ScreenState.Home) } Box(modifier = modifier.fillMaxSize()) { HomeScreenDrawer( selectedScreen = screenState, onScreenSelected = { screen -> screenState = screen // Dismiss drawer when a destination is selected coroutineScope.launch { state.animateTo(DrawerState.Closed) } } ) // ScreenContents(...) } }
একাধিক ভিজ্যুয়াল প্রপার্টি পরিবর্তন করতে
state.requireOffset()ব্যবহার করুন। শুধু কন্টেন্ট অফসেট করার পরিবর্তে, আপনি ড্র্যাগ প্রগ্রেসের উপর ভিত্তি করে একই সাথে ট্রান্সলেশন, স্কেল এবং কর্নার রেডিয়াস অ্যানিমেট করতেModifier.graphicsLayer-এর সাহায্যে একাধিক প্রপার্টি পরিবর্তন করতে পারবেন:- বর্তমান ড্র্যাগ অফসেট পেতে
state.requireOffset()ব্যবহার করুন। - অফসেট ও ড্রয়ারের প্রস্থের সাপেক্ষে আনুপাতিক স্কেল (
1fথেকে0.8f) এবং কোণের ব্যাসার্ধ (0.dpথেকে32.dp) গণনা করতেlerp()(লিনিয়ার ইন্টারপোলেশন) ব্যবহার করুন। Modifier.graphicsLayerড্র ফেজে পরিবর্তনগুলি কার্যকর করে, যা ড্র্যাগ করার সময় রিকম্পোজিশন ট্রিগার না করেই উচ্চ-পারফরম্যান্স অ্যানিমেশন নিশ্চিত করে।
@Composable private fun AnchoredDraggableDrawerGraphicsLayerSample( state: AnchoredDraggableState<DrawerState>, drawerWidth: Float, selectedScreen: ScreenState, onDrawerClicked: () -> Unit ) { ScreenContents( selectedScreen = selectedScreen, onDrawerClicked = onDrawerClicked, modifier = Modifier .graphicsLayer { this.translationX = state.requireOffset() val scale = lerp(1f, 0.8f, state.requireOffset() / drawerWidth) this.scaleX = scale this.scaleY = scale val cornerRadius = lerp(0f, 32f, state.requireOffset() / drawerWidth) this.shape = RoundedCornerShape(cornerRadius.dp) this.clip = true } .anchoredDraggable(state, Orientation.Horizontal) ) }
- বর্তমান ড্র্যাগ অফসেট পেতে
animateTo-এর মাধ্যমে প্রোগ্রাম্যাটিক অ্যানিমেশন ট্রিগার করুন। ড্রয়ার কন্ট্রোল করুন প্রোগ্রাম্যাটিক্যালি (যেমন মেনু আইকনে ট্যাপ করার সময় বা ড্রয়ার আইটেম বেছে নেওয়ার সময়) একটি কোরুটিন স্কোপের মধ্যেstate.animateTo()লঞ্চ করার মাধ্যমে:fun toggleDrawerState( state: AnchoredDraggableState<DrawerState>, coroutineScope: CoroutineScope ) { coroutineScope.launch { if (state.currentValue == DrawerState.Open) { state.animateTo(DrawerState.Closed) } else { state.animateTo(DrawerState.Open) } } }
ফলাফল
Modifier.draggable2D-এর সাহায্যে দুই মাত্রায় টেনে আনুন
X এবং Y অক্ষ জুড়ে একই সাথে আলাদা আলাদা UI এলিমেন্ট সরানোর জন্য
draggable2D মডিফায়ার ব্যবহার করুন।
কম্পোজ করা যায় এমন এলিমেন্ট টেনে আনুন
এই উদাহরণে draggable2D-এর সবচেয়ে সাধারণ ব্যবহার দেখানো হয়েছে — এর মাধ্যমে ব্যবহারকারী
কোনও UI এলিমেন্ট বেছে নিয়ে পেরেন্ট কন্টেনারের মধ্যে যেকোনও জায়গায় সেটি রাখতে পারেন।
@Composable private fun DraggableComposableElement() { // 1. Track the position of the floating window var offset by remember { mutableStateOf(Offset.Zero) } Box(modifier = Modifier.fillMaxSize().background(Color(0xFFF5F5F5))) { Box( modifier = Modifier // 2. Apply the offset to the box's position .offset { IntOffset(offset.x.roundToInt(), offset.y.roundToInt()) } // ... // 3. Attach the 2D drag logic .draggable2D( state = rememberDraggable2DState { delta -> // 4. Update the position based on the movement delta offset += delta } ), contentAlignment = Alignment.Center ) { Text("Video Preview", color = Color.White, fontSize = 12.sp) } } }
আগের কোড স্নিপেটে নিম্নলিখিত বিষয়গুলি অন্তর্ভুক্ত থাকে:
offsetস্টেট ব্যবহার করে বক্সের পজিশন ট্র্যাক করে।- টেনে আনার ডেল্টার উপর ভিত্তি করে কম্পোনেন্টের পজিশন শিফট করতে
offsetমডিফায়ার ব্যবহার করে। - ফ্লিং সাপোর্ট না থাকার কারণে, ব্যবহারকারী আঙুল তুলে নিলেই বক্সটি মুভ করা বন্ধ করে দেয়।
অভিভাবকের ড্র্যাগ এরিয়ার উপর ভিত্তি করে চাইল্ড কম্পোজেবল ড্র্যাগ করুন
এই উদাহরণে দেখানো হয়েছে যে কীভাবে draggable2D ব্যবহার করে 2D ইনপুট এরিয়া তৈরি করা যায়
যেখানে একটি নির্দিষ্ট সারফেসে সিলেক্টর নব সীমাবদ্ধ থাকে। ড্র্যাগেবল এলিমেন্টের উদাহরণের মতো নয়, যা কম্পোনেন্টকে নিজেই সরায়, এই প্রয়োগ
রঙ চয়নকারী জুড়ে চাইল্ড কম্পোজেবল "সিলেক্টর" সরাতে 2D ডেল্টা ব্যবহার করে:
@Composable private fun ExampleColorSelector( // ... ) { // 1. Maintain the 2D position of the selector in state. var selectorOffset by remember { mutableStateOf(Offset.Zero) } // 2. Track the size of the background container. var containerSize by remember { mutableStateOf(IntSize.Zero) } Box( modifier = Modifier .size(300.dp, 200.dp) // Capture the actual pixel dimensions of the container when it's laid out. .onSizeChanged { containerSize = it } .clip(RoundedCornerShape(12.dp)) .background( brush = remember(hue) { // Create a simple gradient representing Saturation and Value for the given Hue. Brush.linearGradient(listOf(Color.White, Color.hsv(hue, 1f, 1f))) } ) ) { Box( modifier = Modifier .size(24.dp) .graphicsLayer { // Center the selector on the finger by subtracting half its size. translationX = selectorOffset.x - (24.dp.toPx() / 2) translationY = selectorOffset.y - (24.dp.toPx() / 2) } // ... // 3. Configure 2D touch dragging. .draggable2D( state = rememberDraggable2DState { delta -> // 4. Calculate the new position and clamp it to the container bounds val newX = (selectorOffset.x + delta.x) .coerceIn(0f, containerSize.width.toFloat()) val newY = (selectorOffset.y + delta.y) .coerceIn(0f, containerSize.height.toFloat()) selectorOffset = Offset(newX, newY) } ) ) } }
আগের স্নিপেটে নিম্নলিখিত বিষয়গুলি অন্তর্ভুক্ত আছে:
- এটি গ্রেডিয়েন্ট কন্টেনারের আসল ডাইমেনশন ক্যাপচার করতে
onSizeChangedমডিফায়ার ব্যবহার করে। সিলেক্টর সঠিকভাবে জানে যে এজ কোথায় আছে। graphicsLayer-এর মধ্যে, এটিtranslationXএবংtranslationYঅ্যাডজাস্ট করে যাতে টেনে আনার সময় সিলেক্টরটি কেন্দ্রে থাকে।
আপনার জন্য সাজেস্ট করা হয়েছে
- মনে রাখবেন: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট দেখানো হয়
- জেসচার সম্পর্কে বোঝা
- উন্নত অ্যানিমেশনের উদাহরণ: জেসচার {:#gesture-and-animation}
- ভ্যালু-ভিত্তিক অ্যানিমেশন