پیجر در نوشتن

برای ورق زدن محتوا به صورت چپ و راست یا بالا و پایین، می‌توانید به ترتیب از Composable HorizontalPager و VerticalPager استفاده کنید. این composable ها عملکردهای مشابه ViewPager در سیستم view دارند. به طور پیش‌فرض، HorizontalPager تمام عرض صفحه را اشغال می‌کند، VerticalPager تمام ارتفاع را اشغال می‌کند، و پیجرها فقط یک صفحه را در یک زمان پر می‌کنند. این پیش فرض ها همه قابل تنظیم هستند.

HorizontalPager

برای ایجاد پیجری که به صورت افقی به چپ و راست حرکت می کند، از HorizontalPager استفاده کنید:

شکل 1 . نسخه ی نمایشی 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 استفاده کنید:

شکل 2 . نسخه ی نمایشی 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 با تنبلی ترکیب شده و در صورت لزوم چیدمان می شوند. همانطور که کاربر در صفحات پیمایش می کند، composable صفحاتی را که دیگر مورد نیاز نیستند حذف می کند.

صفحات بیشتری را خارج از صفحه بارگیری کنید

به طور پیش فرض، پیجر فقط صفحات قابل مشاهده روی صفحه را بارگیری می کند. برای بارگیری بیشتر صفحات خارج از صفحه، beyondBoundsPageCount را روی مقداری بالاتر از صفر تنظیم کنید.

به یک مورد در پیجر بروید

برای پیمایش به صفحه خاصی در پیجر، یک شی PagerState با استفاده از rememberPagerState() ایجاد کنید و آن را به عنوان پارامتر state به پیجر ارسال کنید. شما می توانید PagerState#scrollToPage() را در این حالت، در داخل یک CoroutineScope فراخوانی کنید:

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 : نزدیکترین صفحه به موقعیت snap. به طور پیش فرض، موقعیت snap در ابتدای طرح قرار دارد.
  • settledPage : شماره صفحه زمانی که هیچ انیمیشن یا پیمایشی در حال اجرا نیست. این با خاصیت currentPage متفاوت است، زیرا اگر صفحه به اندازه کافی به موقعیت snap نزدیک شود، 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)
        )
    }
}

پیجر نشانگر دایره ای را در زیر محتوا نشان می دهد
شکل 3 . پیجر نشانگر دایره ای را در زیر محتوا نشان می دهد

اعمال جلوه‌های اسکرول مورد روی محتوا

یک مورد رایج استفاده از موقعیت اسکرول برای اعمال جلوه ها بر روی آیتم های پیجر است. برای اینکه بفهمید یک صفحه چقدر از صفحه انتخاب شده فعلی فاصله دارد، می توانید از PagerState.currentPageOffsetFraction استفاده کنید. سپس می توانید بر اساس فاصله از صفحه انتخاب شده، جلوه های تبدیل را روی محتوای خود اعمال کنید.

شکل 4 . اعمال تغییرات در محتوای پیجر

به عنوان مثال، برای تنظیم کدورت آیتم ها بر اساس فاصله آنها از مرکز، alpha با استفاده از Modifier.graphicsLayer روی یک آیتم در داخل پیجر تغییر دهید:

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 هر دو از تغییر padding پشتیبانی می‌کنند که به شما امکان می‌دهد حداکثر اندازه و تراز صفحات را تحت تأثیر قرار دهید.

به عنوان مثال، تنظیم صفحه 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
}

می توانید مقادیر top و bottom را برای دستیابی به جلوه های مشابه برای VerticalPager تنظیم کنید. مقدار 32.dp فقط در اینجا به عنوان مثال استفاده می شود. می توانید هر یک از ابعاد بالشتک را روی هر مقداری تنظیم کنید.

رفتار اسکرول را سفارشی کنید

ترکیب‌های پیش‌فرض HorizontalPager و VerticalPager مشخص می‌کنند که حرکات حرکتی چگونه با پیجر کار می‌کنند. با این حال، می‌توانید پیش‌فرض‌هایی مانند pagerSnapDistance یا flingBehavior را سفارشی و تغییر دهید.

فاصله گرفتن

به‌طور پیش‌فرض، HorizontalPager و VerticalPager حداکثر تعداد صفحاتی را تنظیم می‌کنند که یک حرکت حرکتی می‌تواند به یک صفحه در هر بار پیمایش کند. برای تغییر این مورد، pagerSnapDistance روی flingBehavior تنظیم کنید:

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),
        beyondBoundsPageCount = 10,
        flingBehavior = fling
    ) {
        PagerSampleItem(page = it)
    }
}

{% کلمه به کلمه %} {% آخر کلمه %} {% کلمه به کلمه %} {% آخر کلمه %}