স্ক্রোল মডিফায়ার

verticalScroll এবং horizontalScroll মডিফায়ারগুলো ব্যবহারকারীকে কোনো এলিমেন্ট স্ক্রল করার সবচেয়ে সহজ উপায় প্রদান করে, যখন এর কন্টেন্টের সীমানা তার সর্বোচ্চ আকারের সীমাবদ্ধতার চেয়ে বড় হয়। verticalScroll এবং horizontalScroll মডিফায়ারগুলো ব্যবহার করলে কন্টেন্টকে ট্রান্সলেট বা অফসেট করার প্রয়োজন হয় না।

@Composable
private fun ScrollBoxes() {
    Column(
        modifier = Modifier
            .background(Color.LightGray)
            .size(100.dp)
            .verticalScroll(rememberScrollState())
    ) {
        repeat(10) {
            Text("Item $it", modifier = Modifier.padding(2.dp))
        }
    }
}

স্ক্রোল অঙ্গভঙ্গিতে সাড়া দেয় এমন একটি সাধারণ উল্লম্ব তালিকা
চিত্র ১. স্ক্রল অঙ্গভঙ্গিতে সাড়া দেয় এমন একটি সাধারণ উল্লম্ব তালিকা।

ScrollState আপনাকে স্ক্রোল অবস্থান পরিবর্তন করতে বা এর বর্তমান অবস্থা জানতে সাহায্য করে। ডিফল্ট প্যারামিটার সহ এটি তৈরি করতে, rememberScrollState() ব্যবহার করুন।

@Composable
private fun ScrollBoxesSmooth() {
    // Smoothly scroll 100px on first composition
    val state = rememberScrollState()
    LaunchedEffect(Unit) { state.animateScrollTo(100) }

    Column(
        modifier = Modifier
            .background(Color.LightGray)
            .size(100.dp)
            .padding(horizontal = 8.dp)
            .verticalScroll(state)
    ) {
        repeat(10) {
            Text("Item $it", modifier = Modifier.padding(2.dp))
        }
    }
}

স্ক্রোলযোগ্য এলাকা সংশোধক

কাস্টম স্ক্রোলেবল কন্টেইনার তৈরির জন্য scrollableArea মডিফায়ার একটি মৌলিক ভিত্তি। এটি scrollable মডিফায়ারের উপর একটি উচ্চ-স্তরের অ্যাবস্ট্রাকশন প্রদান করে এবং জেসচার ডেল্টা ইন্টারপ্রিটেশন, কন্টেন্ট ক্লিপিং ও ওভারস্ক্রোল ইফেক্টের মতো সাধারণ প্রয়োজনীয়তাগুলো সামাল দেয়।

যদিও কাস্টম ইমপ্লিমেন্টেশনের জন্য scrollableArea ব্যবহৃত হয়, সাধারণ স্ক্রলিং লিস্টের জন্য আপনার সাধারণত verticalScroll , horizontalScroll মতো তৈরি সমাধান অথবা LazyColumn মতো কম্পোজেবল কম্পোনেন্ট ব্যবহার করা উচিত। এই উচ্চ-স্তরের কম্পোনেন্টগুলো সাধারণ ব্যবহারের ক্ষেত্রে সহজতর এবং এগুলো নিজেরাই scrollableArea ব্যবহার করে তৈরি করা হয়।

scrollableArea এবং scrollable মডিফায়ারের মধ্যে পার্থক্য

scrollableArea এবং scrollable মধ্যে প্রধান পার্থক্যটি হলো, তারা ব্যবহারকারীর স্ক্রোল অঙ্গভঙ্গি কীভাবে ব্যাখ্যা করে:

  • scrollable (র ডেল্টা): ডেল্টা সরাসরি স্ক্রিনে ব্যবহারকারীর ইনপুটের (যেমন, পয়েন্টার ড্র্যাগ) ভৌত নড়াচড়াকে প্রতিফলিত করে।
  • scrollableArea (কন্টেন্ট-ভিত্তিক ডেল্টা): স্ক্রোল অবস্থানের নির্বাচিত পরিবর্তনকে বোঝানোর জন্য delta অর্থগতভাবে উল্টে দেওয়া হয়, যাতে ব্যবহারকারীর অঙ্গভঙ্গির সাথে কন্টেন্টটি চলমান বলে মনে হয়, যা সাধারণত পয়েন্টারের নড়াচড়ার বিপরীত।

বিষয়টি এভাবে ভাবুন: scrollable আপনাকে বলে দেয় পয়েন্টারটি কীভাবে সরেছে, অন্যদিকে scrollableArea সেই পয়েন্টারের নড়াচড়াকে একটি সাধারণ স্ক্রলেবল ভিউয়ের মধ্যে কন্টেন্ট কীভাবে সরবে তাতে রূপান্তরিত করে। এই বিপরীতমুখীতার কারণেই একটি স্ট্যান্ডার্ড স্ক্রলেবল কন্টেইনার ইমপ্লিমেন্ট করার সময় scrollableArea বেশি স্বাভাবিক মনে হয়।

নিম্নলিখিত সারণিতে সাধারণ পরিস্থিতিগুলির জন্য ডেল্টা চিহ্নগুলির সারসংক্ষেপ দেওয়া হলো:

ব্যবহারকারীর অঙ্গভঙ্গি

scrollable দ্বারা dispatchRawDelta তে ডেল্টা রিপোর্ট করা হয়েছে

scrollableArea * দ্বারা dispatchRawDelta তে রিপোর্ট করা ডেল্টা

পয়েন্টার উপরের দিকে সরে যায়

নেতিবাচক

ইতিবাচক

পয়েন্টারটি নিচের দিকে নামে।

ইতিবাচক

নেতিবাচক

পয়েন্টারটি বাম দিকে সরে যায়

নেতিবাচক

ইতিবাচক (আরটিএল-এর জন্য নেতিবাচক )

পয়েন্টারটি ডানদিকে সরে যায়

ইতিবাচক

নেতিবাচক (আরটিএল-এর জন্য ইতিবাচক )

(*) scrollableArea ডেল্টা চিহ্ন সম্পর্কে দ্রষ্টব্য : scrollableArea থেকে প্রাপ্ত ডেল্টার চিহ্নটি কেবল একটি সাধারণ বিপরীতকরণ নয়। এটি বুদ্ধিমত্তার সাথে বিবেচনা করে:

  1. অভিমুখ : উল্লম্ব বা অনুভূমিক।
  2. LayoutDirection : বাম বা ডান (বিশেষ করে অনুভূমিক স্ক্রোলিংয়ের জন্য গুরুত্বপূর্ণ)।
  3. reverseScrolling ফ্ল্যাগ : স্ক্রোলের দিক উল্টানো হবে কিনা।

স্ক্রল ডেল্টা উল্টে দেওয়ার পাশাপাশি, scrollableArea কন্টেন্টকে লেআউটের সীমানার মধ্যে সীমাবদ্ধ রাখে এবং ওভারস্ক্রল ইফেক্টের রেন্ডারিং পরিচালনা করে। ডিফল্টরূপে, এটি LocalOverscrollFactory দ্বারা প্রদত্ত ইফেক্টটি ব্যবহার করে। আপনি OverscrollEffect প্যারামিটার গ্রহণকারী scrollableArea ওভারলোড ব্যবহার করে এটি কাস্টমাইজ বা নিষ্ক্রিয় করতে পারেন।

কখন scrollableArea মডিফায়ার ব্যবহার করবেন

যখন আপনাকে এমন একটি কাস্টম স্ক্রলিং কম্পোনেন্ট তৈরি করতে হয় যা horizontalScroll , verticalScroll মডিফায়ার বা Lazy লেআউট দ্বারা যথাযথভাবে পূরণ করা যায় না, তখন আপনার scrollableArea মডিফায়ারটি ব্যবহার করা উচিত। এর মধ্যে প্রায়শই নিম্নলিখিত ক্ষেত্রগুলি অন্তর্ভুক্ত থাকে:

  • কাস্টম লেআউট লজিক : যখন স্ক্রোল পজিশনের উপর ভিত্তি করে আইটেমগুলির বিন্যাস গতিশীলভাবে পরিবর্তিত হয়।
  • অনন্য ভিজ্যুয়াল এফেক্ট : স্ক্রল করার সময় চাইল্ড কন্টেন্টের উপর ট্রান্সফরমেশন, স্কেলিং বা অন্যান্য এফেক্ট প্রয়োগ করা।
  • সরাসরি নিয়ন্ত্রণ : verticalScroll বা Lazy লেআউটের সুবিধার বাইরে স্ক্রলিং পদ্ধতির উপর সূক্ষ্ম নিয়ন্ত্রণের প্রয়োজন।

scrollableArea ব্যবহার করে কাস্টম চাকার মতো তালিকা তৈরি করুন

নিম্নলিখিত নমুনাটি scrollableArea ব্যবহার করে একটি কাস্টম উল্লম্ব তালিকা তৈরির পদ্ধতি প্রদর্শন করে, যেখানে আইটেমগুলি কেন্দ্র থেকে দূরে সরে যাওয়ার সাথে সাথে ছোট হতে থাকে, যা একটি "চাকার মতো" ভিজ্যুয়াল প্রভাব তৈরি করে। এই ধরনের স্ক্রোল-নির্ভর রূপান্তর scrollableArea ব্যবহারের জন্য একটি আদর্শ ক্ষেত্র।

চিত্র ২. scrollableArea ব্যবহার করে তৈরি একটি কাস্টমাইজড উল্লম্ব তালিকা।

@Composable
private fun ScrollableAreaSample() {
    // ...
    Layout(
        modifier =
            Modifier
                .size(150.dp)
                .scrollableArea(scrollState, Orientation.Vertical)
                .background(Color.LightGray),
        // ...
    ) { measurables, constraints ->
        // ...
        // Update the maximum scroll value to not scroll beyond limits and stop when scroll
        // reaches the end.
        scrollState.maxValue = (totalHeight - viewportHeight).coerceAtLeast(0)

        // Position the children within the layout.
        layout(constraints.maxWidth, viewportHeight) {
            // The current vertical scroll position, in pixels.
            val scrollY = scrollState.value
            val viewportCenterY = scrollY + viewportHeight / 2

            var placeableLayoutPositionY = 0
            placeables.forEach { placeable ->
                // This sample applies a scaling effect to items based on their distance
                // from the center, creating a wheel-like effect.
                // ...
                // Place the item horizontally centered with a layer transformation for
                // scaling to achieve wheel-like effect.
                placeable.placeRelativeWithLayer(
                    x = constraints.maxWidth / 2 - placeable.width / 2,
                    // Offset y by the scroll position to make placeable visible in the viewport.
                    y = placeableLayoutPositionY - scrollY,
                ) {
                    scaleX = scaleFactor
                    scaleY = scaleFactor
                }
                // Move to the next item's vertical position.
                placeableLayoutPositionY += placeable.height
            }
        }
    }
}
// ...

স্ক্রোলযোগ্য মডিফায়ার

scrollable মডিফায়ারটি scrollable মডিফায়ারগুলো থেকে এই কারণে আলাদা যে, এটি স্ক্রোল জেসচারগুলো শনাক্ত করে এবং ডেল্টাগুলো ক্যাপচার করে, কিন্তু এর বিষয়বস্তু স্বয়ংক্রিয়ভাবে অফসেট করে না। এর পরিবর্তে, এই কাজটি ScrollableState এর মাধ্যমে ব্যবহারকারীর উপর অর্পণ করা হয়, যা এই মডিফায়ারটির সঠিকভাবে কাজ করার জন্য আবশ্যক।

ScrollableState তৈরি করার সময় আপনাকে অবশ্যই একটি consumeScrollDelta ফাংশন প্রদান করতে হবে, যা প্রতিটি স্ক্রোল ধাপে (জেসচার ইনপুট, স্মুথ স্ক্রোলিং বা ফ্লিংগিং দ্বারা) পিক্সেল-এ ডেল্টা সহ কল ​​করা হবে। এই ফাংশনটিকে অবশ্যই ব্যবহৃত স্ক্রোলিং দূরত্বের পরিমাণ রিটার্ন করতে হবে, যাতে scrollable মডিফায়ারযুক্ত নেস্টেড এলিমেন্টের ক্ষেত্রেও ইভেন্টটি সঠিকভাবে প্রোপাগেট হয়।

নিম্নলিখিত কোড স্নিপেটটি অঙ্গভঙ্গি শনাক্ত করে এবং অফসেটের জন্য একটি সাংখ্যিক মান প্রদর্শন করে, কিন্তু কোনো এলিমেন্টকে অফসেট করে না:

@Composable
private fun ScrollableSample() {
    // actual composable state
    var offset by remember { mutableFloatStateOf(0f) }
    Box(
        Modifier
            .size(150.dp)
            .scrollable(
                orientation = Orientation.Vertical,
                // Scrollable state: describes how to consume
                // scrolling delta and update offset
                state = rememberScrollableState { delta ->
                    offset += delta
                    delta
                }
            )
            .background(Color.LightGray),
        contentAlignment = Alignment.Center
    ) {
        Text(offset.toString())
    }
}

একটি UI উপাদান যা আঙুলের চাপ শনাক্ত করে এবং আঙুলের অবস্থানের সাংখ্যিক মান প্রদর্শন করে।
চিত্র ৩. একটি UI উপাদান যা আঙুলের চাপ শনাক্ত করে এবং আঙুলের অবস্থানের সাংখ্যিক মান প্রদর্শন করে।
{% হুবহু %} {% endverbatim %} {% হুবহু %} {% endverbatim %}