Compose笔记(六十九)--Pager

这一节主要了解一下Compose中的Pager,在Jetpack Compose开发中,Pager是用于实现滑动页面集合的核心组件,支持水平(HorizontalPager)和垂直(VerticalPager)方向的滑动,能够灵活管理页面内容、状态和交互。简单总结:

API:
HorizontalPager/VerticalPager:核心组件,分别实现横向 / 纵向翻页
rememberPagerState:创建并记忆 Pager 状态,包含当前页码、滑动偏移等
PagerScope:页面作用域,提供 pageOffset 等页面滑动状态参数
PageSize:定义页面尺寸
PagerSnapDistance:定义滑动后吸附到页面的距离

场景:
1 图片轮播 在电商、新闻等应用中,顶部展示多张图片并自动轮播,用户可手动滑动切换。
2 引导页 应用首次启动时展示多页引导内容,用户滑动浏览后进入主界面。
3 分类标签页 顶部标签栏切换时,下方内容同步滑动

栗子:

implementation("io.coil-kt:coil-compose:2.5.0")
// 权限 <uses-permission android:name="android.permission.INTERNET" />
import androidx.compose.runtime.Composable import androidx.compose.animation.core.animateFloatAsState 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.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.PageSize 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.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.scale import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil.compose.rememberAsyncImagePainter import kotlinx.coroutines.delay import kotlinx.coroutines.launch data class PagerItem( val id: Int, val title: String, val imageUrl: String, val bgColor: androidx.compose.ui.graphics.Color ) fun Float.format(digits: Int): String = "%.${digits}f".format(this) @Composable fun PagerDemo() { val pagerData = listOf( PagerItem(1, "商品A", "https://picsum.photos/800/400?random=1", androidx.compose.ui.graphics.Color(0xFF6495ED)), PagerItem(2, "商品B", "https://picsum.photos/800/400?random=2", androidx.compose.ui.graphics.Color(0xFF90EE90)), PagerItem(3, "商品C", "https://picsum.photos/800/400?random=3", androidx.compose.ui.graphics.Color(0xFFFFB6C1)), PagerItem(4, "商品D", "https://picsum.photos/800/400?random=4", androidx.compose.ui.graphics.Color(0xFFFFD700)) ) Surface(modifier = Modifier.fillMaxSize()) { val pagerState = rememberPagerState( initialPage = 0, pageCount = { pagerData.size } ) val coroutineScope = rememberCoroutineScope() var slideOffset by remember { mutableStateOf(0.0f) } LaunchedEffect(pagerState.currentPage, pagerState.currentPageOffsetFraction) { slideOffset = pagerState.currentPage + pagerState.currentPageOffsetFraction } Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally ) { Text( text = "滑动进度:${slideOffset.format(2)}", fontSize = 16.sp, modifier = Modifier.padding(16.dp) ) HorizontalPager( state = pagerState, modifier = Modifier .weight(1f) .padding(horizontal = 20.dp), pageSize = PageSize.Fill, pageSpacing = 16.dp, contentPadding = androidx.compose.foundation.layout.PaddingValues(horizontal = 20.dp) ) { pageIndex -> val item = pagerData[pageIndex] val pageOffset = pagerState.currentPageOffsetFraction val scale by animateFloatAsState( targetValue = if (pageIndex == pagerState.currentPage) 1f else 0.9f, label = "pageScale" ) val alpha by animateFloatAsState( targetValue = if (pageIndex == pagerState.currentPage) 1f else 0.7f, label = "pageAlpha" ) var isLoading by remember { mutableStateOf(true) } LaunchedEffect(pageIndex) { delay(300) isLoading = false } Box( modifier = Modifier .fillMaxSize() .scale(scale) .alpha(alpha) .background(item.bgColor, MaterialTheme.shapes.medium) .padding(16.dp), contentAlignment = Alignment.Center ) { if (isLoading) { Text(text = "加载中...", color = androidx.compose.ui.graphics.Color.White) } else { Column( horizontalAlignment = Alignment.CenterHorizontally ) { Image( painter = rememberAsyncImagePainter(model = item.imageUrl), contentDescription = item.title, modifier = Modifier .size(200.dp, 150.dp) .padding(bottom = 16.dp), contentScale = ContentScale.Crop ) Text( text = item.title, fontSize = 20.sp, color = androidx.compose.ui.graphics.Color.White ) } } } } Column( modifier = Modifier.padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Row( horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.padding(bottom = 16.dp) ) { pagerData.forEachIndexed { index, _ -> val isSelected = index == pagerState.currentPage Box( modifier = Modifier .size(if (isSelected) 12.dp else 8.dp) .background( color = if (isSelected) androidx.compose.ui.graphics.Color.Blue else androidx.compose.ui.graphics.Color.Gray, shape = CircleShape ) ) } } Row( horizontalArrangement = Arrangement.spacedBy(16.dp) ) { Button( onClick = { coroutineScope.launch { if (pagerState.currentPage > 0) { pagerState.animateScrollToPage(pagerState.currentPage - 1) } } }, enabled = pagerState.currentPage > 0 ) { Text(text = "上一页") } Button( onClick = { coroutineScope.launch { if (pagerState.currentPage < pagerData.size - 1) { pagerState.animateScrollToPage(pagerState.currentPage + 1) } } }, enabled = pagerState.currentPage < pagerData.size - 1 ) { Text(text = "下一页") } } } } } }
import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.pager.VerticalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import coil.compose.rememberAsyncImagePainter @Composable fun PagerDemo() { val imageUrls = listOf( "https://picsum.photos/800/1200?random=1", "https://picsum.photos/800/1200?random=2", "https://picsum.photos/800/1200?random=3" ) val pagerState = rememberPagerState( initialPage = 0, pageCount = { imageUrls.size } ) Surface(modifier = Modifier.fillMaxSize()) { VerticalPager( state = pagerState, modifier = Modifier.fillMaxSize(), pageSize = androidx.compose.foundation.pager.PageSize.Fill ) { pageIndex -> Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center ) { Image( painter = rememberAsyncImagePainter(model = imageUrls[pageIndex]), contentDescription = "商品图片${pageIndex + 1}", modifier = Modifier .fillMaxSize() .padding(20.dp), contentScale = ContentScale.Crop ) Text( text = "${pageIndex + 1}/${imageUrls.size}", fontSize = 20.sp, color = Color.White, modifier = Modifier .background(Color.Black.copy(alpha = 0.5f)) .padding(8.dp) .align(Alignment.BottomCenter) ) } } } }

注意:
1 页面预加载与优化 默认仅加载可见页面,通过beyondViewportPageCount设置屏幕外预加载页面数
2 状态管理与滚动监听 使用LaunchedEffect(pagerState.currentPage)监听页面变化,避免在pageContent中直接监听导致重复重组。
3 滚动控制 滚动需在协程中调用

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

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

相关文章

怎样高效转换网页内容:ReactPage实用演示文稿生成方案

怎样高效转换网页内容&#xff1a;ReactPage实用演示文稿生成方案 【免费下载链接】react-page 项目地址: https://gitcode.com/gh_mirrors/ed/editor 在现代web开发中&#xff0c;ReactPage作为强大的React页面编辑器&#xff0c;提供了丰富的组件和布局功能&#xff…

mimotion小米运动自动刷步数完整教程:2025最新微信支付宝同步方案

mimotion小米运动自动刷步数完整教程&#xff1a;2025最新微信支付宝同步方案 【免费下载链接】mimotion 小米运动刷步数&#xff08;微信支付宝&#xff09;支持邮箱登录 项目地址: https://gitcode.com/gh_mirrors/mimo/mimotion 还在为每天运动步数不足而烦恼吗&…

ReactPage终极指南:从零开始构建现代化网页编辑器

ReactPage终极指南&#xff1a;从零开始构建现代化网页编辑器 【免费下载链接】react-page 项目地址: https://gitcode.com/gh_mirrors/ed/editor ReactPage是一个功能强大的React页面编辑器&#xff0c;专为开发者提供直观的内容创作体验。通过拖拽式界面和丰富的组件…

Ticket Hoarding(1400)

题目描述思路描述容易想到&#xff0c;本题要确保购买天数最少&#xff0c;设购买的天数为cnt&#xff0c;那么要在n天内挑选出门票最小的cnt天。当然&#xff0c;我们考虑&#xff0c;门票价格越小则购买越多&#xff0c;反之&#xff0c;门票价格越大则购买越少。至于天数cnt…

终极指南:WenQuanYi Micro Hei轻量级中文字体的完整配置方案

终极指南&#xff1a;WenQuanYi Micro Hei轻量级中文字体的完整配置方案 【免费下载链接】fonts-wqy-microhei Debian package for WenQuanYi Micro Hei (mirror of https://anonscm.debian.org/git/pkg-fonts/fonts-wqy-microhei.git) 项目地址: https://gitcode.com/gh_mir…

【2025最新】零基础入门学网络安全(详细),看这篇就够了

目录 1.什么是网络安全1.1 网络安全的定义&#xff1a;1.2 信息系统&#xff08;Information System&#xff09;1.3 信息系统安全三要素&#xff08;CIA&#xff09;1.4 网络空间安全1.5 国家网络空间安全战略1.6 网络空间关注点1.7 网络空间安全管理流程 2.网络安全术语3.网络…

语义检索中的向量数据库选型指南:Milvus vs FAISS

语义检索中的向量数据库选型指南:Milvus vs FAISS 关键词:语义检索、向量数据库、Milvus、FAISS、近似最近邻搜索、向量相似度、企业级应用 摘要:在AI时代,语义检索已成为推荐系统、智能客服、多模态搜索等场景的核心技术。而实现高效语义检索的关键,是选择合适的向量数据…

Sign-Sacker:数字签名伪装技术的深度解析与实战应用

Sign-Sacker&#xff1a;数字签名伪装技术的深度解析与实战应用 【免费下载链接】Sign-Sacker 项目地址: https://gitcode.com/gh_mirrors/si/Sign-Sacker 在当今数字安全环境中&#xff0c;数字签名已成为验证软件真实性和完整性的重要机制。然而&#xff0c;这种安全…

网络安全,现在仍然是最好的专业之一

昨天朋友圈看到一个消息&#xff1a;某985计算机专业应届生发文&#xff0c;拿到腾讯安全岗位offer&#xff0c;年薪32万。底下的评论区&#xff1a;有人说运气好&#xff0c;有人说内卷严重。 当然&#xff0c;更多的人说网安已经真的不行了。 我想说&#xff0c;大部分人的思…

FVM中高度非对称矩阵(结构对称)求解器推荐

文章目录1. **Krylov 子空间方法&#xff08;适用于非对称系统&#xff09;**✅ 推荐主算法&#xff1a;2. **预条件子&#xff08;Preconditioner&#xff09;——关键&#xff01;**✅ 高效预条件子&#xff1a;3. **实际工程中的常用组合&#xff08;来自 OpenFOAM、PETSc 等…

ReactPage内容导出为PPT:企业级演示文稿生成全攻略

ReactPage内容导出为PPT&#xff1a;企业级演示文稿生成全攻略 【免费下载链接】react-page 项目地址: https://gitcode.com/gh_mirrors/ed/editor 在当今数字化工作环境中&#xff0c;内容创作与演示展示往往需要跨平台协作。ReactPage作为一款强大的React页面编辑器&…

【国风萌马】Unity 原创表情包卡点

《国风萌马2》暖心回归&#xff01;小马陪你过遍全年传统节日&#xff0c;从守岁到中秋&#xff0c;祝福不重样。日常更有“吃瓜”“拜托”“点赞”等海量萌趣互动&#xff0c;让聊天充满可爱国风。 一套表情&#xff0c;搞定四季问候与每一天的心情。马上下载&#xff01; 【国…

Node.js用WebAssembly加速字符串匹配

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 Node.js中WebAssembly加速字符串匹配&#xff1a;从理论到实践的深度探索目录Node.js中WebAssembly加速字符串匹配&#xff1a;从…

高频信号处理篇---线圈匝数比

我们把它想象成两个“线圈兄弟”之间的能量传递游戏。一、先记住核心原理变压器工作的核心是 “磁”的感应&#xff1a;第一个线圈&#xff08;初级线圈&#xff09; 通上交流电&#xff0c;会产生一个不断变化的磁场。第二个线圈&#xff08;次级线圈&#xff09; 放在这个变化…

救命神器2026 TOP8 AI论文写作软件:本科生毕业论文必备测评

救命神器2026 TOP8 AI论文写作软件&#xff1a;本科生毕业论文必备测评 2026年AI论文写作工具测评&#xff1a;为何需要这份榜单&#xff1f; 随着人工智能技术的不断进步&#xff0c;AI论文写作工具已经成为许多本科生撰写毕业论文的重要辅助手段。然而&#xff0c;面对市场上…

大数据领域数据可视化:打造高效的数据可视化方案

大数据领域数据可视化&#xff1a;打造高效的数据可视化方案关键词&#xff1a;数据可视化、大数据、数据编码、交互设计、数据管道、可视化工具、决策支持摘要&#xff1a;在大数据时代&#xff0c;海量数据如同“数字海洋”&#xff0c;而数据可视化是我们“驾驭海洋”的“导…

脑电波分析中风康复预测提前1月

&#x1f4dd; 博客主页&#xff1a;Jax的CSDN主页 脑电波分析&#xff1a;中风康复预测窗口提前一个月目录脑电波分析&#xff1a;中风康复预测窗口提前一个月 引言&#xff1a;康复预测的“时间黑洞”与突破契机 技术突破&#xff1a;EEG与LLM的协同进化 从数据孤岛到多模态融…

嵌入式知识篇---高阻态与上下拉电阻

高阻态&#xff1a;我打个比方来解释芯片引脚的高阻态&#xff1a;可以把芯片引脚想象成一扇门1. 输出高电平 → 门向外推&#xff08;主动输出“1”&#xff09; 2. 输出低电平 → 门向内拉&#xff08;主动输出“0”&#xff09; 3. 高阻态 → 门完全拆掉&#xff01;关键理解…

开发基于大模型的金融专业教学案例动态生成器

开发基于大模型的金融专业教学案例动态生成器关键词&#xff1a;大模型、金融专业教学案例、动态生成器、自然语言处理、人工智能教育应用摘要&#xff1a;本文聚焦于开发基于大模型的金融专业教学案例动态生成器。首先介绍了该项目的背景&#xff0c;包括目的、预期读者、文档…

Hive与Atlas整合:元数据管理与数据治理

Hive与Atlas整合&#xff1a;元数据管理与数据治理 关键词&#xff1a;Hive、Atlas、元数据管理、数据治理、OpenMetadata、血缘分析、数据血缘 摘要&#xff1a;本文深入探讨Apache Hive与Apache Atlas的整合技术&#xff0c;解析如何通过元数据管理实现高效的数据治理。从核心…