Tarik untuk me-refresh

Komponen tarik untuk memuat ulang memungkinkan pengguna menarik ke bawah di awal konten aplikasi untuk memuat ulang data.

Permukaan API

Gunakan composable PullToRefreshBox untuk menerapkan tarik untuk memuat ulang, yang bertindak sebagai penampung untuk konten yang dapat di-scroll. Parameter utama berikut mengontrol perilaku dan tampilan pemuatan ulang:

  • isRefreshing: Nilai boolean yang menunjukkan apakah tindakan pemuatan ulang sedang berlangsung.
  • onRefresh: Fungsi lambda yang dieksekusi saat pengguna memulai pemuatan ulang.
  • indicator: Menyesuaikan indikator yang digambar sistem pada tarik untuk memuat ulang.

Contoh dasar

Cuplikan ini menunjukkan penggunaan dasar PullToRefreshBox:

@Composable
fun PullToRefreshBasicSample(
    items: List<String>,
    isRefreshing: Boolean,
    onRefresh: () -> Unit,
    modifier: Modifier = Modifier
) {
    PullToRefreshBox(
        isRefreshing = isRefreshing,
        onRefresh = onRefresh,
        modifier = modifier
    ) {
        LazyColumn(Modifier.fillMaxSize()) {
            items(items) {
                ListItem({ Text(text = it) })
            }
        }
    }
}

Poin utama tentang kode

  • PullToRefreshBox menggabungkan LazyColumn, yang menampilkan daftar string.
  • PullToRefreshBox memerlukan parameter isRefreshing dan onRefresh.
  • Konten dalam blok PullToRefreshBox mewakili konten yang dapat di-scroll.

Hasil

Video ini menunjukkan implementasi tarik untuk memuat ulang dasar dari kode sebelumnya:

Gambar 1. Implementasi tarik untuk memuat ulang dasar pada daftar item.

Contoh lanjutan: Menyesuaikan warna indikator

@Composable
fun PullToRefreshCustomStyleSample(
    items: List<String>,
    isRefreshing: Boolean,
    onRefresh: () -> Unit,
    modifier: Modifier = Modifier
) {
    val state = rememberPullToRefreshState()

    PullToRefreshBox(
        isRefreshing = isRefreshing,
        onRefresh = onRefresh,
        modifier = modifier,
        state = state,
        indicator = {
            Indicator(
                modifier = Modifier.align(Alignment.TopCenter),
                isRefreshing = isRefreshing,
                containerColor = MaterialTheme.colorScheme.primaryContainer,
                color = MaterialTheme.colorScheme.onPrimaryContainer,
                state = state
            )
        },
    ) {
        LazyColumn(Modifier.fillMaxSize()) {
            items(items) {
                ListItem({ Text(text = it) })
            }
        }
    }
}

Poin utama tentang kode

  • Warna indikator disesuaikan melalui properti containerColor dan color dalam parameter indicator.
  • rememberPullToRefreshState() mengelola status tindakan pemuatan ulang. Anda menggunakan status ini bersama dengan parameter indicator.

Hasil

Video ini menampilkan implementasi tarik untuk memuat ulang dengan indikator berwarna:

Gambar 2. Implementasi tarik untuk memuat ulang dengan gaya kustom.

Contoh lanjutan: Membuat indikator yang sepenuhnya disesuaikan

Anda dapat membuat indikator kustom yang kompleks dengan memanfaatkan composable dan animasi yang ada.Cuplikan ini menunjukkan cara membuat indikator yang sepenuhnya kustom dalam implementasi tarik untuk memuat ulang:

@Composable
fun PullToRefreshCustomIndicatorSample(
    items: List<String>,
    isRefreshing: Boolean,
    onRefresh: () -> Unit,
    modifier: Modifier = Modifier
) {
    val state = rememberPullToRefreshState()

    PullToRefreshBox(
        isRefreshing = isRefreshing,
        onRefresh = onRefresh,
        modifier = modifier,
        state = state,
        indicator = {
            MyCustomIndicator(
                state = state,
                isRefreshing = isRefreshing,
                modifier = Modifier.align(Alignment.TopCenter)
            )
        }
    ) {
        LazyColumn(Modifier.fillMaxSize()) {
            items(items) {
                ListItem({ Text(text = it) })
            }
        }
    }
}

// ...
@Composable
fun MyCustomIndicator(
    state: PullToRefreshState,
    isRefreshing: Boolean,
    modifier: Modifier = Modifier,
) {
    Box(
        modifier = modifier.pullToRefresh(
            state = state,
            isRefreshing = isRefreshing,
            threshold = PositionalThreshold,
            onRefresh = {

            }
        ),
        contentAlignment = Alignment.Center
    ) {
        Crossfade(
            targetState = isRefreshing,
            animationSpec = tween(durationMillis = CROSSFADE_DURATION_MILLIS),
            modifier = Modifier.align(Alignment.Center)
        ) { refreshing ->
            if (refreshing) {
                CircularProgressIndicator(Modifier.size(SPINNER_SIZE))
            } else {
                val distanceFraction = { state.distanceFraction.coerceIn(0f, 1f) }
                Icon(
                    imageVector = Icons.Filled.CloudDownload,
                    contentDescription = "Refresh",
                    modifier = Modifier
                        .size(18.dp)
                        .graphicsLayer {
                            val progress = distanceFraction()
                            this.alpha = progress
                            this.scaleX = progress
                            this.scaleY = progress
                        }
                )
            }
        }
    }
}

Poin utama tentang kode

  • Cuplikan sebelumnya menggunakan Indicator yang disediakan oleh library. Cuplikan ini membuat composable indikator kustom yang disebut MyCustomIndicator. Dalam composable ini, pengubah pullToRefreshIndicator menangani penentuan posisi dan memicu pemuatan ulang.
  • Seperti pada cuplikan sebelumnya, contoh ini mengekstrak instance PullToRefreshState, sehingga Anda dapat meneruskan instance yang sama ke PullToRefreshBox dan pullToRefreshModifier.
  • Contoh ini menggunakan warna penampung dan nilai minimum posisi dari class PullToRefreshDefaults. Dengan cara ini, Anda dapat menggunakan kembali perilaku dan gaya default dari library Material, sekaligus hanya menyesuaikan elemen yang Anda inginkan.
  • MyCustomIndicator menggunakan Crossfade untuk bertransisi antara ikon cloud dan CircularProgressIndicator. Ikon cloud akan diperbesar saat pengguna menarik, dan bertransisi ke CircularProgressIndicator saat tindakan pemuatan ulang dimulai.
    • targetState menggunakan isRefreshing untuk menentukan status yang akan ditampilkan (ikon cloud atau indikator progres melingkar).
    • animationSpec menentukan animasi tween untuk transisi, dengan durasi yang ditentukan CROSSFADE_DURATION_MILLIS.
    • state.distanceFraction menunjukkan seberapa jauh pengguna telah menarik ke bawah, mulai dari 0f (tidak ada tarikan) hingga 1f (ditarik sepenuhnya).
    • Pengubah graphicsLayer mengubah skala dan transparansi.

Hasil

Video ini menampilkan indikator kustom dari kode sebelumnya:

Gambar 3. Implementasi tarik untuk memuat ulang dengan indikator kustom.

Referensi lainnya