Compose——下拉刷新、上拉加载更多

news2024/11/15 11:30:09

效果图:

  

主要的代码为:

package com.yaona.compose_list_shangla.swipe

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ButtonDefaults.elevation
import androidx.compose.material.ButtonDefaults.textButtonColors
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.paging.LoadState
import androidx.paging.compose.LazyPagingItems
import com.google.accompanist.swiperefresh.SwipeRefresh
import com.google.accompanist.swiperefresh.rememberSwipeRefreshState
import com.yaona.compose_list_shangla.ui.theme.gray300
import com.yaona.compose_list_shangla.ui.theme.gray600
import com.yaona.compose_list_shangla.ui.theme.gray700
import kotlinx.coroutines.launch
import com.yaona.compose_list_shangla.R

/**
 * 下拉刷新,上拉加载view的封装
 *
 * implementation "com.google.accompanist:accompanist-swiperefresh:xxx"
 * */
@Composable
fun <T : Any> SwipeRefreshList(
    collectAsLazyPagingItems: LazyPagingItems<T>,
    listContent: LazyListScope.() -> Unit,
) {
    val rememberSwipeRefreshState = rememberSwipeRefreshState(isRefreshing = false)

    SwipeRefresh(
        state = rememberSwipeRefreshState,
        onRefresh = { collectAsLazyPagingItems.refresh() }
    ) {
        val lazyListState = rememberLazyListState()

        val coroutineScope = rememberCoroutineScope()

        rememberSwipeRefreshState.isRefreshing =
            collectAsLazyPagingItems.loadState.refresh is LoadState.Loading

        LazyColumn(
            state = lazyListState,
            modifier = Modifier
                .fillMaxWidth()
                .fillMaxHeight(),

            ) {
            listContent()
            collectAsLazyPagingItems.apply {
                when {
                    loadState.append is LoadState.Loading -> {
                        //加载更多,底部loading
                        item { LoadingItem() }
                    }
                    loadState.append is LoadState.Error -> {
                        //加载更多异常
                        item {
                            ErrorMoreRetryItem() {
                                collectAsLazyPagingItems.retry()
                            }
                        }
                    }

                    loadState.append == LoadState.NotLoading(endOfPaginationReached = true) -> {
                        // 已经没有更多数据了
                        item {
                            NoMoreDataFindItem(onClick = {
                                coroutineScope.launch {
                                    lazyListState.animateScrollToItem(0)
                                }
                            })
                        }
                    }

                    loadState.refresh is LoadState.Error -> {
                        if (collectAsLazyPagingItems.itemCount <= 0) {
                            //刷新的时候,如果itemCount小于0,第一次加载异常
                            item {
                                ErrorContent() {
                                    collectAsLazyPagingItems.retry()
                                }
                            }
                        } else {
                            item {
                                ErrorMoreRetryItem() {
                                    collectAsLazyPagingItems.retry()
                                }
                            }
                        }
                    }
                    loadState.refresh is LoadState.Loading -> {
                        // 第一次加载且正在加载中
                        if (collectAsLazyPagingItems.itemCount == 0) {
                        }
                    }
                }
            }
        }
    }
}

/**
 * 底部加载更多失败处理
 * */
@Composable
fun ErrorMoreRetryItem(retry: () -> Unit) {
    Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
        TextButton(
            onClick = { retry() },
            modifier = Modifier
                .padding(20.dp)
                .width(80.dp)
                .height(30.dp),
            shape = RoundedCornerShape(6.dp),
            contentPadding = PaddingValues(3.dp),
            colors = textButtonColors(backgroundColor = gray300),
            elevation = elevation(
                defaultElevation = 2.dp,
                pressedElevation = 4.dp,
            ),
        ) {
            Text(text = "请重试", color = gray600)
        }
    }
}

@Composable
fun NoMoreDataFindItem(onClick: () -> Unit) {
    Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
        TextButton(
            onClick = { onClick() },
            modifier = Modifier
                .padding(20.dp)
                .width(80.dp)
                .height(30.dp),
            shape = RoundedCornerShape(6.dp),
            contentPadding = PaddingValues(3.dp),
            colors = textButtonColors(backgroundColor = gray300),
            elevation = elevation(
                defaultElevation = 2.dp,
                pressedElevation = 4.dp,
            ),
        ) {
            Text(text = "已经没有更多数据啦 ~~ Click to top", color = gray600)
        }
    }
}

/**
 * 页面加载失败处理
 * */
@Composable
fun ErrorContent(retry: () -> Unit) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(top = 100.dp),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Image(
            modifier = Modifier.padding(top = 80.dp),
            painter = painterResource(id = R.drawable.ic_default_empty),
            contentDescription = null
        )
        Text(text = "请求失败,请检查网络", modifier = Modifier.padding(8.dp))
        TextButton(
            onClick = { retry() },
            modifier = Modifier
                .padding(20.dp)
                .width(80.dp)
                .height(30.dp),
            shape = RoundedCornerShape(10.dp),
            contentPadding = PaddingValues(5.dp),
            colors = textButtonColors(backgroundColor = gray300),
            elevation = elevation(
                defaultElevation = 2.dp,
                pressedElevation = 4.dp,
            )
            //colors = ButtonDefaults
        ) { Text(text = "重试", color = gray700) }
    }
}

/**
 * 底部加载更多正在加载中...
 * */
@Composable
fun LoadingItem() {
    Row(
        modifier = Modifier
            .height(34.dp)
            .fillMaxWidth()
            .padding(5.dp),
        horizontalArrangement = Arrangement.Center
    ) {
        CircularProgressIndicator(
            modifier = Modifier
                .size(24.dp),
            color = gray600,
            strokeWidth = 2.dp
        )
        Text(
            text = "加载中...",
            color = gray600,
            modifier = Modifier
                .fillMaxHeight()
                .padding(start = 20.dp),
            fontSize = 18.sp,
        )
    }
}

整体的代码下载地址为:https://download.csdn.net/download/wy313622821/88646806

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1323785.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 操作系统(Vim)

vim 编译器&#xff08;相当于windows中记事本&#xff09; 当在终端窗口直接运行vim命令&#xff0c;会出现以下截图&#xff08;类似手册对vim编译器简单的介绍&#xff09;&#xff1a; vim提供三种基本工作模式&#xff1a; 命令模式(默认模式) 插入模式 末行模式 创建文本…

字节跳动的辉煌与波澜:兴衰成败的深度剖析

导言 字节跳动作为一家全球知名的科技公司&#xff0c;其在短视频领域的崛起备受瞩目。然而&#xff0c;随着时间的推移&#xff0c;公司也面临了一系列挑战。本文将深入研究字节跳动的兴衰成败&#xff0c;以及公司在发展过程中所面临的困境和成功之道。 1. 创业初期与初见成绩…

2023 英特尔On技术创新大会直播 |我感受到的AI魅力

文章目录 前言英特尔技术创新大会 的来历芯生无限 赋能AI创新后记 前言 近年来&#xff0c;人工智能&#xff08;Artificial Intelligence&#xff09;的应用与发展呈现出爆发式增长的态势&#xff0c;成为科技领域最为引人注目的热门话题之一。作为全球领先的半导体公司&…

SpringIOC之AnnotatedElementKey

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

C语言——高精度乘法

一、引子 高精度乘法相较于高精度加法和减法有更多的不同&#xff0c;加法和减法是一位对应一位进行操作的&#xff0c;而乘法是一个数的每一位对另一个数的每一位进行操作&#xff0c;需要的计算步骤更多。 二、核心算法 void Calculate(int num1[], int num2[], int numres…

从零开始的Docker Desktop使用,Docker快速上手,Docker介绍和基础使用

目录 1 Docker简介和安装和基础配置1.1 Docker简介1.2 安装Docker Desktop1.3 换源1.4 Docker基础使用1.5 对Docker操作1.5.1 获取当时所有镜像(docker images)1.5.2 拉镜像(docker pull)1.5.3 删除镜像(docker rmi)1.5.4加载镜像(docker run) 1.6 使用交互式容器1.6.1 查看容器…

【2023 英特尔On技术创新大会直播 |我与英特尔的初次相遇】—— AIPC探索下一代的物联网时代

&#x1f308;个人主页: Aileen_0v0 &#x1f525;系列专栏:英特尔技术学习专栏 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 硅谷经济的发展与挑战 Intel开发者云与AI技术的应用 AI压缩技术的发展与应用 英特尔与阿里巴巴在AI领域的合作 AIPC时代的…

司铭宇老师:销售经理培训课程内容

销售经理是销售团队的核心领导&#xff0c;他们的能力和素质直接影响到整个团队的绩效。针对销售经理的培训课程内容应涵盖多个方面&#xff0c;旨在提升销售经理的领导力、团队管理能力、沟通技巧和市场分析能力。以下是一篇关于针对销售经理的培训课程内容的文章&#xff0c;…

逻辑回归代价函数

逻辑回归的代价函数通常使用交叉熵损失来定义。这种损失函数非常适合于二元分类问题。 本篇来推导一下逻辑回归的代价函数。 首先&#xff0c;我们在之前了解了逻辑回归的定义&#xff1a;逻辑回归模型是一种用于二元分类的模型&#xff0c;其预测值是一个介于0和1之间的概率…

ESP32 - Thonny+MicroPython+ESP32开发环境搭建

ThonnyMicroPythonESP32开发环境搭建 ①下载Thonny②下载MicroPython③下载对应驱动④烧录MicroPython到EPS32⑤Thonny与ESP32交互到此为止&#xff0c;我们就搭建好了整个流程 ①下载Thonny 链接&#xff1a;https://thonny.org/ ②下载MicroPython 链接&#xff1a;https:…

2023年第四届 “赣网杯” 网络安全大赛 gwb-web3 Write UP【PHP 临时函数名特性 + 绕过trim函数】

一、题目如下&#xff1a; 二、代码解读&#xff1a; 这段代码是一个简单的PHP脚本&#xff0c;它接受通过GET请求传递的两个参数&#xff1a;‘pass’和’func’&#xff1a; ① $password trim($_GET[pass] ?? );&#xff1a;从GET请求中获取名为’pass’的参数&#xff0…

0086-Java_四种进制介绍

文章目录 1 进制(程序员的基本功)1.1 进制介绍1.2 进制的转换(基本功)1.2.1 进制转换的介绍 1.3 二进制在运算中的说明1.4 原码、反码、补码(重点 难点) 1 进制(程序员的基本功) 1.1 进制介绍 对于整数&#xff0c;有四种表示方式&#xff1a; 二进制&#xff1a;0,1 &#x…

command ‘python.execSelectionInTerminal‘ not found

command python.execSelectionInTerminal not found 问题描述解决方案 问题描述 选择解释器提示&#xff1a; 解决方案 在左侧栏中搜索workspaceUnsupported 可以看到Python在受限制模式下运行 关闭受限制模式 再来看就没有受限制了 这就可以选择解释器了 参考1 参考…

细说 MySQL 用户安全加固策略

这是一篇关于如何加强 MySQL 用户安全的文章&#xff0c;通读全文您可以了解密码复杂度策略、连接控制插件以及密码变更策略的相关知识。本文内容仅供参考&#xff0c;请在操作时以实际环境为准&#xff0c;避免造成经济损失。 作者&#xff1a;余振兴&#xff0c;爱可生 DBA 团…

7-1 抢红包(PTA - 数据结构)

没有人没抢过红包吧…… 这里给出N个人之间互相发红包、抢红包的记录&#xff0c;请你统计一下他们抢红包的收获。 输入格式&#xff1a; 输入第一行给出一个正整数N&#xff08;≤104&#xff09;&#xff0c;即参与发红包和抢红包的总人数&#xff0c;则这些人从1到N编号。…

[每周一更]-(第31期):Mysql安装汇总

写自&#xff1a;20230204 23:25 一. mysql rpm二进制包 rpm -Uvh http://repo.mysql.com/mysql-community-release-el6-5.noarch.rpm yum install mysql-community-server service mysqld start set password password(“123456”)二. mysql yum安装 1、安装查看有没有安装…

Dbvis 链接Oracle数据库

安装 Dbvisualizer 后 1&#xff0c;打开Dbvisualizer&#xff0c;单机左键 图片标注处。 2&#xff0c;点击右键&#xff0c;显示。 3&#xff0c;点击Creat Datebase Connection 4,点击 use wizard &#xff0c;填写 地址&#xff0c;下一步 5&#xff0c;选择 Orcal Thin …

华为atlas300安装教程

1、安装包位置&#xff1a; /data/ai_install_packages 2、添加HwHiAiUser用户&#xff1a; groupadd -g 1000 HwHiAiUser useradd -g HwHiAiUser -u 1000 -d /home/HwHiAiUser -m HwHiAiUser -s /bin/bash 3、安装驱动&#xff1a; ./Ascend-hdk-310p-npu-driver_6.0.0_l…

【小技巧】得力多功能计算器,小数变成10的负幂,应该怎么设置正常显示小数

1.本人计算器如图 2.点击MODE&#xff0c;再次点击可以翻页&#xff0c;找到NORM&#xff0c;如图是3 3.1次方&#xff0c;2是小数点。再摁一下2即可

速通Python基础语法--变量篇

Python设计哲学 解决一个问题&#xff0c;只提供一种方案&#xff1a;变量类型 写法灵活,一行代码表达更多意思,提高语言表达能力:动态类型(两面性) 颜色标识&#xff1a; 紫色&#xff1a;Python与C语言的区别 一、常量与表达式 二、变量 1、认识变量&#xff08;存数据&am…