Swipeable থেকে AnchoredDraggable-এ স্থানান্তর করুন

Swipeable হলো একটি Compose Material API যা আপনাকে এমন কম্পোনেন্ট তৈরি করতে সাহায্য করে যেগুলোকে আলাদা আলাদা অবস্থার মধ্যে সোয়াইপ করা যায়, যেমন বটম শিট, ড্রয়ার, বা সোয়াইপ-টু-ডিসমিস। কম্পোনেন্টের আকারের উপর নির্ভরশীল অ্যাঙ্করের মতো উন্নত ব্যবহারের ক্ষেত্রগুলোকে আরও ভালোভাবে সমর্থন করার জন্য, Compose-Foundation 1.6.0-alpha01-এ এর একটি উত্তরসূরি প্রকাশিত হয়েছে: AnchoredDraggableAnchoredDraggable হলো অ্যাঙ্করযুক্ত অবস্থা (যেমন বটম শিট, ড্রয়ার, বা সোয়াইপ-টু-ডিসমিস) সহ ড্র্যাগযোগ্য কম্পোনেন্ট তৈরির জন্য একটি Foundation API।

Material-এর Swipeable API-গুলোকে Foundation-এর AnchoredDraggable জন্য অপ্রচলিত ঘোষণা করা হয়েছে এবং ভবিষ্যতের কোনো রিলিজে এগুলো সরিয়ে ফেলা হবে। এই নির্দেশিকায় Swipeable API থেকে AnchoredDraggable এ স্থানান্তরের পদ্ধতি বর্ণনা করা হয়েছে।

SwipeableState AnchoredDraggableState এ স্থানান্তর করুন

আপনার স্টেট হোল্ডারের পরিবর্তনগুলো শনাক্ত করার মাধ্যমে শুরু করুন। AnchoredDraggableState থেকে ইনহেরিট করা যায় না, এবং ইনিশিয়ালাইজ করার আগে অফসেটটি Float.NaN হিসেবে প্রদর্শিত হয়।

আপনার রাজ্য ধারক আপডেট করুন

AnchoredDraggableState একটি ফাইনাল ক্লাস, যার মানে এটি থেকে ইনহেরিট করা যায় না। যদি আপনার বিদ্যমান কম্পোনেন্টটি SwipeableState থেকে ইনহেরিট করে থাকে, তাহলে আপনার স্টেট হোল্ডারটিকে ইনহেরিট করার পরিবর্তে AnchoredDraggableState এর একটি রেফারেন্স ধারণ করার জন্য আপডেট করুন:

সোয়াইপযোগ্য

class MySwitchState: SwipeableState()

অ্যাঙ্করডড্র্যাগেবল

class MySwitchState {
    private val anchoredDraggableState = AnchoredDraggableState(...)
}

যেহেতু আপনার স্টেট হোল্ডার এখন আর SwipeableState থেকে ইনহেরিট করে না, তাই আপনাকে হয়তো নিজেই API এক্সপোজ করতে হতে পারে। আপনি যে সবচেয়ে সাধারণ API-গুলো ব্যবহার করতে পারেন সেগুলো হলো offset , progress , currentValue এবং targetValue

অফসেট অ্যাক্সেস করুন

Swipeable এর থেকে ভিন্ন, AnchoredDraggableState এর offset ইনিশিয়ালাইজ হওয়ার আগে Float.NaN থাকে। AnchoredDraggable এ, অ্যাঙ্করগুলোকে AnchoredDraggableState এর কনস্ট্রাক্টরে পাস করা যায় অথবা AnchoredDraggableState#updateAnchors এর মাধ্যমে আপডেট করা যায়। AnchoredDraggableState এর কনস্ট্রাক্টরে অ্যাঙ্করগুলো পাস করলে অফসেটটি সঙ্গে সঙ্গে ইনিশিয়ালাইজ হয়ে যায়।

যদি আপনার অ্যাঙ্করগুলো লেআউটের উপর নির্ভরশীল হয় বা পরিবর্তন হতে পারে, তাহলে অ্যাঙ্কর পরিবর্তিত হলে স্টেট পুনরায় তৈরি করা এড়াতে AnchoredDraggableState#updateAnchors ব্যবহার করুন।

আপনি যদি updateAnchors ব্যবহার করেন, তাহলে অ্যাঙ্করগুলোকে updateAnchors এ পাঠানোর আগে অফসেটটি Float.NaN হবে। কম্পোনেন্টগুলোতে ভুলবশত Float.NaN পাঠানো এড়াতে, অফসেটটি পড়ার সময় তা ইনিশিয়ালাইজড হওয়া আবশ্যক করতে AnchoredDraggableState#requireOffset ব্যবহার করুন। এটি আপনাকে অসঙ্গতি বা সম্ভাব্য বাগগুলো শুরুতেই ধরতে সাহায্য করে।

@Composable
fun AnchoredDraggableBox() {
    val state = remember { AnchoredDraggableState(...) }
    val density = LocalDensity.current
    val anchors = remember { DraggableAnchors { ... } }
    SideEffect {
        state.updateAnchors(anchors)
    }
    Box(
        Modifier.offset { IntOffset(x = state.requireOffset(), y = 0) }
    }
}

Modifier.swipeable কে Modifier.anchoredDraggable এ রূপান্তর করুন।

Modifier.anchoredDraggable() এখন Modifier.swipeable পরিবর্তে ব্যবহৃত হচ্ছে। Modifier.swipeable() এর কিছু প্যারামিটার এখন সরাসরি AnchoredDraggableState এ স্থানান্তরিত হয়েছে, যা পরবর্তী বিভাগগুলিতে বর্ণনা করা হয়েছে।

অ্যাঙ্কর সংজ্ঞায়িত করুন

DraggableAnchors বিল্ডার মেথড ব্যবহার করে অ্যাঙ্করগুলো সংজ্ঞায়িত করুন। তারপর, সেগুলোকে AnchoredDraggableState#updateAnchors অথবা AnchoredDraggableState এর কনস্ট্রাক্টরে পাস করুন:

নির্মাতা

enum class DragValue { Start, Center, End }

@Composable
fun AnchoredDraggableBox() {
    val anchors = DraggableAnchors {
        Start at -100.dp.toPx()
        Center at 0f
        End at 100.dp.toPx()
    }
    val state = remember {
        AnchoredDraggableState(anchors = anchors)
    }
    Box(
        Modifier.offset { IntOffset(x = state.requireOffset(), y = 0) }
    )
}

অ্যাঙ্কর আপডেট করুন

enum class DragValue { Start, Center, End }

@Composable
fun AnchoredDraggableBox() {
    val state = remember { AnchoredDraggableState(...) }
    val density = LocalDensity.current
    val anchors = with (density) {
        DraggableAnchors {
            Start at -100.dp.toPx()
            Center at 0f
            End at 100.dp.toPx()
        }
    }
    SideEffect {
        state.updateAnchors(anchors)
    }
    Box(
        Modifier.offset { IntOffset(x = state.requireOffset(), y = 0) }
    )
}

অ্যাঙ্করগুলো স্ট্যাটিক হলে, সেগুলোকে কনস্ট্রাক্টরে পাস করুন। যদি সেগুলো লেআউটের ওপর নির্ভরশীল হয়, বা স্ট্যাটিক না হয়, তাহলে updateAnchors ব্যবহার করুন।

অবস্থানগত থ্রেশহোল্ড সংজ্ঞায়িত করুন

thresholds প্যারামিটারের ধরন এবং নাম পরিবর্তিত হয়েছে। আলাদা ThresholdConfig ইন্টারফেস থাকার পরিবর্তে, AnchoredDraggableState একটি positionalThreshold প্যারামিটার রয়েছে যা একটি ল্যাম্বডা ফাংশন গ্রহণ করে এবং এই ফাংশনটি থ্রেশহোল্ডের অবস্থান রিটার্ন করে। উদাহরণস্বরূপ, ৫০% এর একটি পজিশনাল থ্রেশহোল্ড এভাবে প্রকাশ করা যেতে পারে:

val anchoredDraggableState = AnchoredDraggableState(
    positionalThreshold = { distance -> distance * 0.5f },
    ...
)

56dp এর একটি অবস্থানগত থ্রেশহোল্ডকে নিম্নরূপে প্রকাশ করা যেতে পারে:

val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
    positionalThreshold = { with(density) { 56.dp.toPx() } },
    ...
)

বেগের সীমা নির্ধারণ করুন

বেগের থ্রেশহোল্ডগুলিও AnchoredDraggableState এর কনস্ট্রাক্টরে পাঠানো হয়, এবং একটি ল্যাম্বডা হিসাবেও প্রকাশ করা হয়:

val density = LocalDensity.current
val anchoredDraggableState = AnchoredDraggableState(
    velocityThreshold = { with(density) { 125.dp.toPx() } },
    ...
)

এপিআই পৃষ্ঠে পরিবর্তন

নিচে এপিআই সারফেসের পরিবর্তনগুলোর একটি সংক্ষিপ্ত বিবরণ দেওয়া হলো।

AnchoredDraggableState

SwipeableState

AnchoredDraggableState

open class SwipeableState (initialValue: T, animationSpec: AnimationSpec = …, confirmStateChange: (T) -> Boolean = …)

class AnchoredDraggableState ( initialValue: T, animationSpec: AnimationSpec = …, confirmValueChange: (T) -> Boolean = …, positionalThreshold: Density.(Float) -> Float = …, velocityThreshold: Dp = …)

offset: State

offset: Float
requireOffset()

progress: SwipeProgress

progress: Float [0f..1f ]

currentValue: T

currentValue: T

targetValue: T

targetValue: T

direction: Float [-1f, 0f, 1f ]

প্রযোজ্য নয়

suspend animateTo(
targetValue: T,
anim: AnimationSpec = …)

suspend animateTo(
targetState: T,
velocity: Float =
lastVelocity)

suspend snapTo(targetValue: T)

suspend snapTo(targetValue: T)

performDrag(delta: Float)

dispatchRawDelta(delta: Float)

suspend performFling(velocity: Float)

suspend settle(velocity: Float)

isAnimationRunning: Boolean

isAnimationRunning: Boolean

lastVelocity: Float

Modifier.anchoredDraggable

Modifier.swipeable

Modifier.anchoredDraggable

state: SwipeableState

state: AnchoredDraggableState

anchors: Map

AnchoredDraggableState#updateAnchors
or

AnchoredDraggableState#constructor

orientation: Orientation

orientation: Orientation

enabled: Boolean = true

enabled: Boolean = true

reverseDirection: Boolean = false

reverseDirection: Boolean = false

interactionSource: MutableInteractionSource? = null

interactionSource: MutableInteractionSource? = null

thresholds: (from: T, to: T) -> ThresholdConfig = FixedThreshold(56.dp)

AnchoredDraggableState কনস্ট্রাক্টরে positionalThreshold হিসেবে পাস করা হয়।

resistance: ResistanceConfig? = …

এখনও সমর্থিত নয়। সর্বশেষ অবস্থার জন্য b/288084801 দেখুন।

velocityThreshold: Dp = 125.dp

AnchoredDraggable কনস্ট্রাক্টরে পাস করা হয়েছে