রচনায় পেজার

অনুভূমিকভাবে বা উল্লম্বভাবে কন্টেন্ট স্ক্রল করার জন্য, আপনি HorizontalPager এবং VerticalPager কম্পোজেবলগুলো ব্যবহার করতে পারেন। ভিউ সিস্টেমের ViewPager এর মতো এগুলোরও একই ধরনের কাজ রয়েছে। ডিফল্টভাবে, HorizontalPager স্ক্রিনের সম্পূর্ণ প্রস্থ এবং VerticalPager সম্পূর্ণ উচ্চতা জুড়ে থাকে। এছাড়াও, এই পেজারগুলো একবারে কেবল একটি পৃষ্ঠাই ফ্লিং করে। এই সমস্ত ডিফল্ট সেটিংস কনফিগার করা যায়।

হরাইজন্টালপেজার

এমন একটি পেজার তৈরি করতে যা ডানে ও বামে স্ক্রল করে, HorizontalPager ব্যবহার করুন:

চিত্র ১। HorizontalPager ডেমো

// Display 10 items
val pagerState = rememberPagerState(pageCount = {
    10
})
HorizontalPager(state = pagerState) { page ->
    // Our page content
    Text(
        text = "Page: $page",
        modifier = Modifier.fillMaxWidth()
    )
}

ভার্টিকালপেজার

উপরে ও নিচে স্ক্রল করে এমন একটি পেজার তৈরি করতে, VerticalPager ব্যবহার করুন:

চিত্র ২। VerticalPager ডেমো

// Display 10 items
val pagerState = rememberPagerState(pageCount = {
    10
})
VerticalPager(state = pagerState) { page ->
    // Our page content
    Text(
        text = "Page: $page",
        modifier = Modifier.fillMaxWidth()
    )
}

অলস সৃষ্টি

HorizontalPager এবং VerticalPager উভয়ের ক্ষেত্রেই পৃষ্ঠাগুলো প্রয়োজন অনুযায়ী লে -আউট ও বিন্যস্ত হয়। ব্যবহারকারী যখন পৃষ্ঠাগুলো স্ক্রল করতে থাকেন, তখন কম্পোজেবলটি অপ্রয়োজনীয় পৃষ্ঠাগুলো সরিয়ে দেয়।

অফস্ক্রিনে আরও পৃষ্ঠা লোড করুন

ডিফল্টরূপে, পেজারটি শুধুমাত্র স্ক্রিনে দৃশ্যমান পৃষ্ঠাগুলি লোড করে। স্ক্রিনের বাইরে আরও পৃষ্ঠা লোড করতে, beyondBoundsPageCount মান শূন্যের চেয়ে বেশি সেট করুন।

পেজারে একটি আইটেমে স্ক্রোল করুন

পেজারের কোনো নির্দিষ্ট পৃষ্ঠায় স্ক্রল করতে, rememberPagerState() ব্যবহার করে একটি PagerState অবজেক্ট তৈরি করুন এবং এটিকে state প্যারামিটার হিসেবে পেজারে পাঠান। আপনি এই স্টেটের উপর, একটি CoroutineScope ভিতরে PagerState#scrollToPage() কল করতে পারেন।

val pagerState = rememberPagerState(pageCount = {
    10
})
HorizontalPager(state = pagerState) { page ->
    // Our page content
    Text(
        text = "Page: $page",
        modifier = Modifier
            .fillMaxWidth()
            .height(100.dp)
    )
}

// scroll to page
val coroutineScope = rememberCoroutineScope()
Button(onClick = {
    coroutineScope.launch {
        // Call scroll to on pagerState
        pagerState.scrollToPage(5)
    }
}, modifier = Modifier.align(Alignment.BottomCenter)) {
    Text("Jump to Page 5")
}

যদি আপনি পৃষ্ঠায় অ্যানিমেট করতে চান, তাহলে PagerState#animateScrollToPage() ফাংশনটি ব্যবহার করুন:

val pagerState = rememberPagerState(pageCount = {
    10
})

HorizontalPager(state = pagerState) { page ->
    // Our page content
    Text(
        text = "Page: $page",
        modifier = Modifier
            .fillMaxWidth()
            .height(100.dp)
    )
}

// scroll to page
val coroutineScope = rememberCoroutineScope()
Button(onClick = {
    coroutineScope.launch {
        // Call scroll to on pagerState
        pagerState.animateScrollToPage(5)
    }
}, modifier = Modifier.align(Alignment.BottomCenter)) {
    Text("Jump to Page 5")
}

পৃষ্ঠার অবস্থার পরিবর্তন সম্পর্কে বিজ্ঞপ্তি পান

PagerState তিনটি প্রপার্টিতে পেজ সম্পর্কিত তথ্য থাকে: currentPage , settledPage , এবং targetPage

  • currentPage : স্ন্যাপ পজিশনের সবচেয়ে কাছের পৃষ্ঠা। ডিফল্টরূপে, স্ন্যাপ পজিশনটি লেআউটের শুরুতে থাকে।
  • settledPage : যখন কোনো অ্যানিমেশন বা স্ক্রলিং চলে না, তখনকার পৃষ্ঠা নম্বর। এটি currentPage প্রপার্টি থেকে ভিন্ন, কারণ পৃষ্ঠাটি স্ন্যাপ পজিশনের যথেষ্ট কাছাকাছি থাকলে currentPage সঙ্গে সঙ্গে আপডেট হয়ে যায়, কিন্তু সমস্ত অ্যানিমেশন শেষ না হওয়া পর্যন্ত settledPage একই থাকে।
  • targetPage : স্ক্রোলিং চলাচলের জন্য প্রস্তাবিত থামার অবস্থান।

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

val pagerState = rememberPagerState(pageCount = {
    10
})

LaunchedEffect(pagerState) {
    // Collect from the a snapshotFlow reading the currentPage
    snapshotFlow { pagerState.currentPage }.collect { page ->
        // Do something with each page change, for example:
        // viewModel.sendPageSelectedEvent(page)
        Log.d("Page change", "Page changed to $page")
    }
}

VerticalPager(
    state = pagerState,
) { page ->
    Text(text = "Page: $page")
}

একটি পৃষ্ঠা সূচক যোগ করুন

কোনো পৃষ্ঠায় একটি ইন্ডিকেটর যোগ করতে, একাধিক পৃষ্ঠার মধ্যে কোন পৃষ্ঠাটি নির্বাচিত হয়েছে সেই তথ্য পেতে PagerState অবজেক্টটি ব্যবহার করুন এবং আপনার নিজস্ব ইন্ডিকেটরটি অঙ্কন করুন।

উদাহরণস্বরূপ, একটি বৃত্তাকার নির্দেশক তৈরি করতে, আপনি pagerState.currentPage ব্যবহার করে বৃত্তের সংখ্যা পুনরাবৃত্তি করতে পারেন এবং পৃষ্ঠাটি নির্বাচিত কিনা তার উপর ভিত্তি করে বৃত্তের রঙ পরিবর্তন করতে পারেন:

val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    modifier = Modifier.fillMaxSize()
) { page ->
    // Our page content
    Text(
        text = "Page: $page",
    )
}
Row(
    Modifier
        .wrapContentHeight()
        .fillMaxWidth()
        .align(Alignment.BottomCenter)
        .padding(bottom = 8.dp),
    horizontalArrangement = Arrangement.Center
) {
    repeat(pagerState.pageCount) { iteration ->
        val color = if (pagerState.currentPage == iteration) Color.DarkGray else Color.LightGray
        Box(
            modifier = Modifier
                .padding(2.dp)
                .clip(CircleShape)
                .background(color)
                .size(16.dp)
        )
    }
}

পেজারে বিষয়বস্তুর নিচে একটি বৃত্তাকার নির্দেশক দেখা যাচ্ছে।
চিত্র ৩। পেজার, যেখানে বিষয়বস্তুর নিচে একটি বৃত্তাকার নির্দেশক দেখা যাচ্ছে।

কন্টেন্টে আইটেম স্ক্রোল ইফেক্ট প্রয়োগ করুন

এর একটি সাধারণ ব্যবহার হলো আপনার পেজার আইটেমগুলিতে বিভিন্ন ইফেক্ট প্রয়োগ করার জন্য স্ক্রল পজিশন ব্যবহার করা। একটি পেজ নির্বাচিত পেজ থেকে কতটা দূরে আছে তা জানতে, আপনি PagerState.currentPageOffsetFraction ব্যবহার করতে পারেন। এরপর, নির্বাচিত পেজ থেকে দূরত্বের উপর ভিত্তি করে আপনি আপনার কন্টেন্টে ট্রান্সফরমেশন ইফেক্ট প্রয়োগ করতে পারেন।

চিত্র ৪। পেজারের বিষয়বস্তুতে রূপান্তর প্রয়োগ।

উদাহরণস্বরূপ, কেন্দ্র থেকে দূরত্বের উপর ভিত্তি করে আইটেমগুলির অস্বচ্ছতা সামঞ্জস্য করতে, পেজারের ভিতরের কোনো আইটেমের উপর Modifier.graphicsLayer ব্যবহার করে alpha পরিবর্তন করুন:

val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(state = pagerState) { page ->
    Card(
        Modifier
            .size(200.dp)
            .graphicsLayer {
                // Calculate the absolute offset for the current page from the
                // scroll position. We use the absolute value which allows us to mirror
                // any effects for both directions
                val pageOffset = (
                    (pagerState.currentPage - page) + pagerState
                        .currentPageOffsetFraction
                    ).absoluteValue

                // We animate the alpha, between 50% and 100%
                alpha = lerp(
                    start = 0.5f,
                    stop = 1f,
                    fraction = 1f - pageOffset.coerceIn(0f, 1f)
                )
            }
    ) {
        // Card content
    }
}

কাস্টম পৃষ্ঠার আকার

ডিফল্টরূপে, HorizontalPager এবং VerticalPager যথাক্রমে সম্পূর্ণ প্রস্থ বা সম্পূর্ণ উচ্চতা জুড়ে থাকে। আপনি pageSize ভেরিয়েবলটিকে Fixed , Fill (ডিফল্ট) অথবা একটি কাস্টম সাইজ ক্যালকুলেশন হিসেবে সেট করতে পারেন।

উদাহরণস্বরূপ, 100.dp এর একটি নির্দিষ্ট প্রস্থের পৃষ্ঠা সেট করতে:

val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    pageSize = PageSize.Fixed(100.dp)
) { page ->
    // page content
}

ভিউপোর্ট সাইজের উপর ভিত্তি করে পেজগুলোর আকার নির্ধারণ করতে, একটি কাস্টম পেজ সাইজ ক্যালকুলেশন ব্যবহার করুন। একটি কাস্টম PageSize অবজেক্ট তৈরি করুন এবং আইটেমগুলোর মধ্যকার ব্যবধান বিবেচনা করে availableSpace কে তিন দিয়ে ভাগ করুন:

private val threePagesPerViewport = object : PageSize {
    override fun Density.calculateMainAxisPageSize(
        availableSpace: Int,
        pageSpacing: Int
    ): Int {
        return (availableSpace - 2 * pageSpacing) / 3
    }
}

বিষয়বস্তু প্যাডিং

HorizontalPager এবং VerticalPager উভয়ই কন্টেন্ট প্যাডিং পরিবর্তন সমর্থন করে, যার মাধ্যমে আপনি পেজের সর্বোচ্চ আকার এবং অ্যালাইনমেন্ট নিয়ন্ত্রণ করতে পারেন।

উদাহরণস্বরূপ, start প্যাডিং সেট করলে পৃষ্ঠাগুলো শেষের দিকে সারিবদ্ধ হয়:

শুরুতে প্যাডিং সহ পেজার, যা বিষয়বস্তুকে শেষের দিকে সারিবদ্ধ করে দেখায়।
চিত্র ৫। প্রারম্ভিক প্যাডিং সহ পেজার।

val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    contentPadding = PaddingValues(start = 64.dp),
) { page ->
    // page content
}

start এবং end প্যাডিং উভয়ের মান একই রাখলে আইটেমটি আনুভূমিকভাবে কেন্দ্রে অবস্থান করে:

শুরু এবং শেষের প্যাডিং সহ পেজার যা বিষয়বস্তুকে কেন্দ্রে দেখায়।
চিত্র ৬। আনুভূমিক প্যাডিংযুক্ত পেজার।

val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    contentPadding = PaddingValues(horizontal = 32.dp),
) { page ->
    // page content
}

end প্যাডিং সেট করলে পৃষ্ঠাগুলো শুরুর দিকে সারিবদ্ধ হয়:

শুরু এবং শেষের প্যাডিং সহ পেজার, যা বিষয়বস্তুকে শুরুর দিকে সারিবদ্ধভাবে দেখায়।
চিত্র ৭। প্রান্তভাগে প্যাডিংযুক্ত পেজার।

val pagerState = rememberPagerState(pageCount = {
    4
})
HorizontalPager(
    state = pagerState,
    contentPadding = PaddingValues(end = 64.dp),
) { page ->
    // page content
}

VerticalPager ক্ষেত্রেও একই রকম প্রভাব অর্জনের জন্য আপনি top এবং bottom ভ্যালু সেট করতে পারেন। এখানে 32.dp ভ্যালুটি শুধুমাত্র একটি উদাহরণ হিসেবে ব্যবহার করা হয়েছে; আপনি প্যাডিং-এর প্রতিটি ডাইমেনশন যেকোনো ভ্যালুতে সেট করতে পারেন।

স্ক্রোল আচরণ কাস্টমাইজ করুন

ডিফল্ট HorizontalPager এবং VerticalPager কম্পোজেবলগুলো নির্দিষ্ট করে দেয় যে পেজারের সাথে স্ক্রলিং জেসচার কীভাবে কাজ করবে। তবে, আপনি pagerSnapDistance বা flingBehavior মতো ডিফল্টগুলো কাস্টমাইজ ও পরিবর্তন করতে পারেন।

স্ন্যাপ দূরত্ব

ডিফল্টরূপে, HorizontalPager এবং VerticalPager একটি ফ্লিং জেসচারের মাধ্যমে একবারে সর্বোচ্চ একটি পৃষ্ঠা স্ক্রল করার সীমা নির্ধারণ করে। এটি পরিবর্তন করতে, flingBehaviorpagerSnapDistance সেট করুন:

val pagerState = rememberPagerState(pageCount = { 10 })

val fling = PagerDefaults.flingBehavior(
    state = pagerState,
    pagerSnapDistance = PagerSnapDistance.atMost(10)
)

Column(modifier = Modifier.fillMaxSize()) {
    HorizontalPager(
        state = pagerState,
        pageSize = PageSize.Fixed(200.dp),
        beyondViewportPageCount = 10,
        flingBehavior = fling
    ) {
        PagerSampleItem(page = it)
    }
}

একটি স্বয়ংক্রিয়ভাবে অগ্রসরমান পেজার তৈরি করুন

এই অংশে বর্ণনা করা হয়েছে কীভাবে কম্পোজ-এ পেজ ইন্ডিকেটর সহ একটি স্বয়ংক্রিয়ভাবে অগ্রসরমান পেজার তৈরি করতে হয়। আইটেমগুলোর সংগ্রহ স্বয়ংক্রিয়ভাবে আনুভূমিকভাবে স্ক্রল হয়, তবে ব্যবহারকারীরা আইটেমগুলোর মধ্যে ম্যানুয়ালি সোয়াইপও করতে পারেন। যদি কোনো ব্যবহারকারী পেজারটির সাথে ইন্টারঅ্যাক্ট করেন, তবে স্বয়ংক্রিয় অগ্রগতি থেমে যায়।

মৌলিক উদাহরণ

একসাথে, নিম্নলিখিত কোড স্নিপেটগুলো একটি ভিজ্যুয়াল ইন্ডিকেটর সহ একটি মৌলিক অটো-অ্যাডভান্সিং পেজার ইমপ্লিমেন্টেশন তৈরি করে, যেখানে প্রতিটি পৃষ্ঠা ভিন্ন রঙে রেন্ডার হয়:

@Composable
fun AutoAdvancePager(pageItems: List<Color>, modifier: Modifier = Modifier) {
    Box(modifier = Modifier.fillMaxSize()) {
        val pagerState = rememberPagerState(pageCount = { pageItems.size })
        val pagerIsDragged by pagerState.interactionSource.collectIsDraggedAsState()

        val pageInteractionSource = remember { MutableInteractionSource() }
        val pageIsPressed by pageInteractionSource.collectIsPressedAsState()

        // Stop auto-advancing when pager is dragged or one of the pages is pressed
        val autoAdvance = !pagerIsDragged && !pageIsPressed

        if (autoAdvance) {
            LaunchedEffect(pagerState, pageInteractionSource) {
                while (true) {
                    delay(2000)
                    val nextPage = (pagerState.currentPage + 1) % pageItems.size
                    pagerState.animateScrollToPage(nextPage)
                }
            }
        }

        HorizontalPager(
            state = pagerState
        ) { page ->
            Text(
                text = "Page: $page",
                textAlign = TextAlign.Center,
                modifier = modifier
                    .fillMaxSize()
                    .background(pageItems[page])
                    .clickable(
                        interactionSource = pageInteractionSource,
                        indication = LocalIndication.current
                    ) {
                        // Handle page click
                    }
                    .wrapContentSize(align = Alignment.Center)
            )
        }

        PagerIndicator(pageItems.size, pagerState.currentPage)
    }
}

কোড সম্পর্কে মূল বিষয়গুলো

  • AutoAdvancePager ফাংশনটি স্বয়ংক্রিয়ভাবে পৃষ্ঠা অগ্রসর হওয়ার সুবিধা সহ একটি হরাইজন্টালি পেজিং ভিউ তৈরি করে। এটি ইনপুট হিসেবে Color অবজেক্টের একটি তালিকা গ্রহণ করে, যা প্রতিটি পৃষ্ঠার ব্যাকগ্রাউন্ড কালার হিসেবে ব্যবহৃত হয়।
  • rememberPagerState ব্যবহার করে pagerState তৈরি করা হয়, যা পেজারের অবস্থা ধারণ করে।
  • pagerIsDragged এবং pageIsPressed ব্যবহারকারীর মিথস্ক্রিয়া ট্র্যাক করে।
  • ব্যবহারকারী পেজারটি ড্র্যাগ না করলে বা এর কোনো একটি পেজে চাপ না দিলে, LaunchedEffect প্রতি দুই সেকেন্ড পর পর পেজারটিকে স্বয়ংক্রিয়ভাবে এগিয়ে নিয়ে যায়।
  • HorizontalPager একাধিক পৃষ্ঠার একটি তালিকা প্রদর্শন করে, যার প্রতিটিতে পৃষ্ঠা নম্বর দেখানোর জন্য একটি Text কম্পোজেবল থাকে। মডিফায়ারটি পৃষ্ঠাটিকে পূর্ণ করে, pageItems থেকে পটভূমির রঙ নির্ধারণ করে এবং পৃষ্ঠাটিকে ক্লিকযোগ্য করে তোলে।

@Composable
fun PagerIndicator(pageCount: Int, currentPageIndex: Int, modifier: Modifier = Modifier) {
    Box(modifier = Modifier.fillMaxSize()) {
        Row(
            modifier = Modifier
                .wrapContentHeight()
                .fillMaxWidth()
                .align(Alignment.BottomCenter)
                .padding(bottom = 8.dp),
            horizontalArrangement = Arrangement.Center
        ) {
            repeat(pageCount) { iteration ->
                val color = if (currentPageIndex == iteration) Color.DarkGray else Color.LightGray
                Box(
                    modifier = modifier
                        .padding(2.dp)
                        .clip(CircleShape)
                        .background(color)
                        .size(16.dp)
                )
            }
        }
    }
}

কোড সম্পর্কে মূল বিষয়গুলো

  • একটি Box কম্পোজেবল রুট এলিমেন্ট হিসেবে কাজ করে এবং পেজ ইন্ডিকেটরগুলোকে আনুভূমিকভাবে সাজানোর জন্য এর মধ্যে একটি Row থাকে।
  • একটি কাস্টম পৃষ্ঠা নির্দেশক বৃত্তের একটি সারি হিসাবে প্রদর্শিত হয়, যেখানে CircleShape এ আবদ্ধ প্রতিটি Box একটি পৃষ্ঠাকে প্রতিনিধিত্ব করে।
  • বর্তমান পৃষ্ঠার বৃত্তটি DarkGray রঙের, এবং অন্য বৃত্তগুলো LightGray রঙের। currentPageIndex প্যারামিটারটি নির্ধারণ করে কোন বৃত্তটি গাঢ় ধূসর রঙে প্রদর্শিত হবে।

ফলাফল

এই ভিডিওটিতে পূর্ববর্তী অংশগুলি থেকে নেওয়া মৌলিক স্বয়ংক্রিয়ভাবে এগিয়ে যাওয়া পেজারটি দেখানো হয়েছে:

চিত্র ৮। একটি স্বয়ংক্রিয়ভাবে অগ্রসরমান পেজার, যেখানে প্রতিটি পৃষ্ঠা অগ্রগতির মধ্যে দুই সেকেন্ডের বিলম্ব থাকে।

অতিরিক্ত সম্পদ

{% হুবহু %} {% endverbatim %}