水平ページャーと垂直ページャーを使用した Compose ページャーの入門 (2023/8)

序文

この記事を読むには、Compose の基本的な知識が必要です。知識がない場合は、Jetpack Compose にアクセスして詳細な紹介を参照してください (リアルタイムで更新されます)。

この記事では、viewpager2 の構成バージョンである構成ページャーを紹介します。これはまだ実験的な API であり、依存関係は以前に移行されています。

頼る

    implementation 'androidx.compose.foundation:foundation:1.4.3'
    //已弃用
    //implementation "com.google.accompanist:accompanist-pager:0.33.1-alpha"

上記のバージョン番号は、この記事の執筆時点で最も安定したバージョンです。


コンセプト紹介

Pager は水平方向のhorizo​​ntalPagerと垂直方向のverticalPagerに分かれており、それらが継承する基本クラスはPager です。

Pager
HorizontalPager
VerticalPager

パラメータの紹介

viewpager または viewpager2 を使用したことがある場合は、これらのプロパティに精通していると思います。

ここに画像の説明を挿入します

  • pageCount - このポケットベルのページ数

  • 修飾子- 修飾子

  • state - このポケットベルの状態を制御します

  • contentPadding - ページネータのパディング値。これにより、コンテンツが切り取られた後にパディングが追加されますが、これは修飾子パラメーターでは不可能です。これを使用して、最初のページの前または最後のページの後にパディングを追加できます。pageSpacing を使用してページ間にスペースを追加することもできます。

  • pageSize - このオプションを使用して、このポケットベルにページを埋める方法を変更します。それらは Fill、adaptiveFixed であり、calculateMainAxisPageSize によって設定されます。デフォルトは Fill です。

  • BeyondBoundsPageCount - 表示可能なページのリストの前後にロードされたページ。注意: 大きなbeyondBoundsPageCount値を使用すると、多数のページが合成、測定、配置されることになり、遅延読み込みを使用する目的が損なわれることに注意してください。これは、表示されるページの前後にいくつかのページをプリロードする最適化として使用する必要があります。(簡単に言うとプリロードされたページです)

  • pageSpacing - このポケットベルでページを区切るために使用されるスペースの量

  • flingBehavior - スクロール後のジェスチャに使用される flingBehavior。

  • userScrollEnabled - ユーザー ジェスチャまたはアクセシビリティ アクションによるスクロールが許可されるかどうか。PagerState.scroll が無効になっている場合でも、PagerState.scroll を使用してプログラムでスクロールできます。

  • reverseLayout - スクロールとレイアウトの方向を逆にします。

  • key - プロジェクトの安定した一意のキーを表します。キーを指定すると、スクロール位置はキーに従って維持されます。つまり、現在表示されている項目の前に項目を追加または削除すると、指定されたキーを持つ項目が最初に表示される項目として残ります。
    pageNestedScrollConnection - この Pager にネストされたリストの使用方法を指示するネストされた ScrollConnection。デフォルトの動作では、ページャーはすべてのネストされたデルタを消費します。

水平ページャー

  • verticalAlignment - この Pager のページの垂直方向の配置。

垂直ページャー

  • horizo​​ntalAlignment - この Pager のページの水平方向の配置。

使用

基本的な使い方

サンプルコード:

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun Greeting() {
    
    

        HorizontalPager(pageCount = 20) {
    
     page ->

               Text(
                   text = "Page: $page",
                   modifier = Modifier
                       .fillMaxWidth()
                       .height(170.dp)
                       .background(Color.Yellow)
               )


        }
}

効果:

ここに画像の説明を挿入します

アピールサンプルコードでは非常にシンプルなページャーを実装していますが、実際の開発では以下の点に注意してください。

  1. ページャの結合可能な項目には、pageCount パラメータを指定する必要があります。そうでない場合は、エラーが報告されます。その他のパラメータはオプションです。
  2. PagerState は初期化する必要があります。ポケットベルの制御を容易にするために、組み込みのものを使用しないことをお勧めします。
  3. 実際の条件に基づいて、beyondBoundsPageCount を柔軟に使用して、パフォーマンスとユーザー エクスペリエンスの最適なバランスを実現します。

標準使用

上記の点に基づいて、上記のサンプルコードを次のように変更できます。

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun Greeting() {
    
    

        val list = mutableListOf<Int>()
        list.add(R.mipmap.advocate)
        list.add(R.mipmap.arabianman)
        list.add(R.mipmap.boy)

        val pagerState = rememberPagerState(
            1
        )


        HorizontalPager(pageCount = 3,
            state = pagerState,
            beyondBoundsPageCount = 1
            ) {
    
     page ->
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(170.dp)
                    .background(Color.Yellow)
            ) {
    
    
                Image(painter = painterResource(id = list[page]) ,
                    modifier = Modifier
                        .align(alignment = Alignment.CenterHorizontally)
                        .padding(top = 25.dp),
                    contentDescription = "person" )
                Text(
                    text = "Page: $page",
                    Modifier.align(alignment = Alignment.CenterHorizontally)
                )
            }
        }
}

効果は次のとおりです。
ここに画像の説明を挿入します

rememberPagerState を 1 に設定して、ページャーの最初の表示が 1 から始まるようにします。同様に、horizo​​ntalPager をverticalPager に変更し、他のコードは変更しないままにすると、効果は次のようになります。
ここに画像の説明を挿入します

指定されたページャにジャンプします pagerState.scrollToPage()

指定したページャーにジャンプしたい場合は、サンプルコードを使用して次のように変更できます。

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun Greeting() {
    
    

        val list = mutableListOf<Int>()
        list.add(R.mipmap.advocate)
        list.add(R.mipmap.arabianman)
        list.add(R.mipmap.boy)

        val pagerState = rememberPagerState(
            0
        )

    val coroutineScope = rememberCoroutineScope()

    Column() {
    
    
        HorizontalPager(pageCount = 3,
            state = pagerState,
            beyondBoundsPageCount = 1
        ) {
    
     page ->
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(170.dp)
                    .background(Color.Yellow)
            ) {
    
    
                Image(painter = painterResource(id = list[page]) ,
                    modifier = Modifier
                        .align(alignment = Alignment.CenterHorizontally)
                        .padding(top = 25.dp),
                    contentDescription = "person" )
                Text(
                    text = "Page: $page",
                    Modifier.align(alignment = Alignment.CenterHorizontally)
                )
            }
        }


        Button(onClick = {
    
    
            coroutineScope.launch {
    
    
                // Call scroll to on pagerState
                pagerState.scrollToPage(3)
            }
        }) {
    
    
            Text("跳转到页面3")
        }
    }

}

効果は次のとおりです。

ここに画像の説明を挿入します
上記のコード例では、PagerState.scrollToPageメソッドを使用して、ボタンをクリックして指定されたページャーにジャンプする効果を実現しています。アニメーションが必要な場合は、pagerState.animateScrollToPage()メソッドを使用できます。

インジケーター pagerState.currentPage を追加

ページネータインジケーターを追加したい場合は、次のコードを追加するだけです。

val pageCount = 3

...

 Row(
            Modifier
                .height(50.dp)
                .fillMaxWidth(),
            horizontalArrangement = Arrangement.Center
        ) {
    
    
            repeat(pageCount) {
    
     iteration ->
                val color =
                    if (pagerState.currentPage == iteration) Color.DarkGray else Color.LightGray
                Box(
                    modifier = Modifier
                        .padding(2.dp)
                        .clip(CircleShape)
                        .background(color)
                        .size(10.dp)

                )
            }
        }

効果は次のとおりです。

ここに画像の説明を挿入します
上記のコード例では、pagerState.currentPageメソッドを使用して、現在のセレクターが選択されているかどうかを判断します。

完全なコード

package com.zyf.composepager

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement

import androidx.compose.foundation.layout.Box

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.VerticalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

import com.zyf.composepager.ui.theme.ComposepagerTheme
import kotlinx.coroutines.launch

class MainActivity : ComponentActivity() {
    
    
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContent {
    
    
            ComposepagerTheme {
    
    
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
    
    
                    Greeting()
                }
            }
        }
    }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun Greeting() {
    
    

    val list = mutableListOf<Int>()
    list.add(R.mipmap.advocate)
    list.add(R.mipmap.arabianman)
    list.add(R.mipmap.boy)

    val pagerState = rememberPagerState(
        0
    )

    val coroutineScope = rememberCoroutineScope()

    val pageCount = 3


    Column() {
    
    
        HorizontalPager(
            pageCount = 3,
            state = pagerState,
            beyondBoundsPageCount = 1,
            modifier = Modifier .background(Color.Yellow)
        ) {
    
     page ->
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(170.dp)
            ) {
    
    
                Image(
                    painter = painterResource(id = list[page]),
                    modifier = Modifier
                        .align(alignment = Alignment.CenterHorizontally)
                        .padding(top = 25.dp),
                    contentDescription = "person"
                )
                Text(
                    text = "Page: $page",
                    Modifier.align(alignment = Alignment.CenterHorizontally)
                )
            }
        }


        Row(
            Modifier
                .height(50.dp)
                .fillMaxWidth(),
            horizontalArrangement = Arrangement.Center
        ) {
    
    
            repeat(pageCount) {
    
     iteration ->
                val color =
                    if (pagerState.currentPage == iteration) Color.DarkGray else Color.LightGray
                Box(
                    modifier = Modifier
                        .padding(2.dp)
                        .clip(CircleShape)
                        .background(color)
                        .size(10.dp)

                )
            }
        }


        Button(onClick = {
    
    
            coroutineScope.launch {
    
    
                pagerState.animateScrollToPage(3)
            }
        }) {
    
    
            Text("跳转到页面3")
        }

    }
}

@Preview(showBackground = true, showSystemUi = true)
@Composable
fun GreetingPreview() {
    
    
    ComposepagerTheme {
    
    
        Greeting()
    }
}

要約する

pagerState.currentPage と pagerState.scrollToPage を使用することで、インジケーターをクリックすると指定したページャーにジャンプするという共通機能も実現できます 興味のある方はぜひ試してみてください この記事は主に公式ドキュメントの学習概要を参照しています 詳しい使い方 公式ドキュメントはじめに、ここでは詳細は説明しません。

おすすめ

転載: blog.csdn.net/shop_and_sleep/article/details/132535523