Jetpack Compose学习(15)——Pager组件的使用(对标ViewPager)
原文地址: Jetpack Compose学习(15)——Pager组件的使用(对标ViewPager)-Stars-One的杂货小窝
从名字可以看出,Pager这个就是ViewPager的替代产物
在Jetpack Compose里的,Pager根据方向,主要分为2个组件: VerticalPager HorizontalPager
这2个,一个是默认占满高度,一个是默认占满宽度,可以自行通过Modifier来修改尺寸
基本使用
val pagerState = rememberPagerState(pageCount = {
	2
})
HorizontalPager(state = pagerState){pageIndex->
	//这里写你的页面内容,根据下标自动切换不同页面
	when (pageIndex) {
        0 -> {
            Box(modifier=Modifier) {
            }
        }
        else -> {
            Box(modifier=Modifier) {
            }
        }
    }
}
属性讲解
这里Pager的属性有些多,我挑些常用的属性来进行说明:
fun HorizontalPager(
    state: PagerState,
    modifier: Modifier = Modifier,
    contentPadding: PaddingValues = PaddingValues(0.dp),
    pageSize: PageSize = PageSize.Fill,
    beyondViewportPageCount: Int = PagerDefaults.BeyondViewportPageCount,
    pageSpacing: Dp = 0.dp,
    verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,
    flingBehavior: TargetedFlingBehavior = PagerDefaults.flingBehavior(state = state),
    userScrollEnabled: Boolean = true,
    reverseLayout: Boolean = false,
    key: ((index: Int) -> Any)? = null,
    pageNestedScrollConnection: NestedScrollConnection = PagerDefaults.pageNestedScrollConnection(
        state,
        Orientation.Horizontal
    ),
    snapPosition: SnapPosition = SnapPosition.Start,
    pageContent: @Composable PagerScope.(page: Int) -> Unit
)
pagerState
表明当前Pager容器的状态,通过rememberPagerState来进行创建
此对象有以下几个常用的属性和方法:
- currentPage:与贴靠位置最近的页面。默认情况下,贴靠位置位于布局的开头。
- settledPage:未运行任何动画或滚动时显示的页码。这与 currentPage 属性不同,因为如果网页足够接近固定位置,currentPage 会立即更新,但 settledPage 会保持不变,直到所有动画都运行完毕。
- targetPage:滚动动作的建议停止位置
- scrollToPage(pageIndex)无动画指定滚动到指定页面下标(需要配合开启一个协程使用)
- animateScrollToPage(pageIndex)带动画指定滚动到指定页面下标(需要配合开启一个协程使用)
val coroutineScope = rememberCoroutineScope()
coroutineScope.launch {
	// Call scroll to on pagerState
	pagerState.scrollToPage(5)
}
contentPadding(内边距)
感觉应该不用多说什么,和LazyRow等组件一样,用来设置内边距的
pageSize(页面item尺寸)
默认情况下,HorizontalPager 和 VerticalPager 分别占据整个宽度或整个高度。
可以将 pageSize 变量设置为使用 PageSize.Fixed、PageSize.Fill(默认)或自定义大小计算。
如,在HorizontalPager固定每个页面的宽度,使用PageSize.Fixed(300.dp)
beyondViewportPageCount
接收一个整数,默认为0,即表示: 默认情况下,Pager只会在屏幕上加载可见的页面。
如需在屏幕外加载更多页面,请将 beyondBoundsPageCount 设置为大于零的值
userScrollEnabled
用来控制是否允许用户滚动的一个boolean数值
pageSpacing
接收一个dp数值, 每个页面item的间隔距离
代码示例补充
banner水平轮播
这个是比较常见的效果了,如下图所示:

代码如下:
val pagerState = rememberPagerState(pageCount = {
	4
})
Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
	HorizontalPager(state = pagerState, contentPadding = PaddingValues(horizontal = 32.dp), pageSpacing = 16.dp) { page -> // Our page content
		val bgColor = when (page) {
			0 -> {
				Color.Blue
			}
			1 -> {
				Color.Yellow
			}
			else -> {
				Color.LightGray
			}
		}
		Box(modifier = Modifier
			.fillMaxWidth()
			.height(100.dp)
			.background(bgColor))
	}
	Spacer(modifier = Modifier.height(16.dp))
	CustomIndicator(pagerState)
}
如果想自动轮播的效果,可以使用副作用函数配合,如下代码:
val pagerState = rememberPagerState(pageCount = {
        3
    })
LaunchedEffect(Unit) {
	while (true){
		//间隔1s跳转到下一个页面
		delay(1000)
		 if (pagerState.currentPage ==pagerState.pageCount-1) {
			 //重置的话,跳转不使用动画
			pagerState.scrollToPage(0)
		}else{
			pagerState.animateScrollToPage(pagerState.currentPage+1)
		}
	}
}
Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
	HorizontalPager(state = pagerState, contentPadding = PaddingValues(horizontal = 32.dp), pageSpacing = 16.dp) { page -> // Our page content
		val bgColor = when (page) {
			0 -> {
				Color.Blue
			}
			1 -> {
				Color.Yellow
			}
			else -> {
				Color.LightGray
			}
		}
		Box(modifier = Modifier
			.fillMaxWidth()
			.height(100.dp)
			.background(bgColor))
	}
	Spacer(modifier = Modifier.height(16.dp))
	CustomIndicator(pagerState)
}
滚动小圆点指示器
/**
 * 指示器布局,与[HorizontalPager]
 *
 * @param pagerState pager的状态
 * @param modifier
 * @param activeColor 选中颜色
 * @param inactiveColor 未选中颜色
 * @param indicatorWidth 单个指示器的宽度
 * @param indicatorHeight 单个指示器的高度
 * @param spacing 每个指示器间隔
 * @param indicatorShape 指示器的形状
 *
 * @sample CustomIndicatorSample
 */
@Composable
fun CustomIndicator(
    pagerState: PagerState,
    modifier: Modifier = Modifier,
    activeColor: Color = MaterialTheme.colorScheme.primary,
    inactiveColor: Color = Color.LightGray,
    indicatorWidth: Dp = 10.dp,
    indicatorHeight: Dp = 5.dp,
    spacing: Dp = 5.dp,
    indicatorShape: Shape = CircleShape,
) {
    val spacingPx = LocalDensity.current.run { spacing.roundToPx() }
    Box(
        modifier = modifier, contentAlignment = Alignment.CenterStart
    ) {
        Row(
            horizontalArrangement = Arrangement.spacedBy(spacing),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            val indicatorModifier = Modifier.background(color = inactiveColor, shape = indicatorShape)
            //不能活动的索引的点
            repeat(pagerState.pageCount) {
                Box(
                    indicatorModifier.size(
                        indicatorWidth, indicatorHeight
                    )
                )
            }
        }
        //计算偏移量
        val scrollPosition = (pagerState.currentPage + pagerState.currentPageOffsetFraction).coerceIn(
                0f, (pagerState.pageCount - 1).coerceAtLeast(0).toFloat()
            ) //可以活动的索引点
        Box(Modifier
            .offset {
                IntOffset(
                    x = (spacingPx * scrollPosition + indicatorWidth.roundToPx() * scrollPosition).toInt(), y = 0
                )
            }
            .size(width = indicatorWidth, height = indicatorHeight)
            .background(
                color = activeColor,
                shape = indicatorShape,
            ))
    }
}
//使用示例
@Composable
private fun CustomIndicatorSample() {
    val pagerState = rememberPagerState(pageCount = {
        10
    })
    Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
        HorizontalPager(state = pagerState) { page ->
            Text("page=$page")
        }
        CustomIndicator(pagerState)
    }
}
两侧页面高度减小,且带动画效果
效果不太好描述,直接上动图

添加一个Modifier的扩展方法,然后给Pager里的Item使用即可
fun Modifier.carouselTransition(page: Int, pagerState: PagerState) =
    graphicsLayer {
        val pageOffset =
            ((pagerState.currentPage - page) + pagerState.currentPageOffsetFraction).absoluteValue
        val transformation =
            lerp(
                start = 0.7f,
                stop = 1f,
                fraction = 1f - pageOffset.coerceIn(0f, 1f)
            )
        alpha = transformation
        scaleY = transformation
    }
示例:
val pageState = rememberPagerState(){3}
    Column(modifier = modifier, horizontalAlignment = Alignment.CenterHorizontally) {
        HorizontalPager(state = pageState, contentPadding = PaddingValues(horizontal = 32.dp), pageSpacing = 16.dp, snapPosition = SnapPosition.Center) { page -> // Our page content
            val bgColor = when (page) {
                0 -> {
                    Color.Blue
                }
                1 -> {
                    Color.Yellow
                }
                else -> {
                    Color.LightGray
                }
            }
            Box(modifier = Modifier
                .fillMaxWidth()
                .height(100.dp)
                .carouselTransition(page,pageState)
                .background(bgColor))
        }
    }
参考
Jetpack Compose学习(15)——Pager组件的使用(对标ViewPager)的更多相关文章
- Jetpack Compose学习(5)——从登录页美化开始学习布局组件使用
		原文:Jetpack Compose学习(5)--从登录页美化开始学习布局组件使用 | Stars-One的杂货小窝 本篇主要讲解常用的布局,会与原生Android的布局控件进行对比说明,请确保了解A ... 
- Jetpack Compose学习(7)——MD样式架构组件Scaffold及导航底部菜单
		Jetpack Compose学习(7)--MD样式架构组件Scaffold及导航底部菜单 | Stars-One的杂货小窝 Compose给我们提供了一个Material Design样式的首页组件 ... 
- Jetpack Compose学习(3)——图标(Icon) 按钮(Button) 输入框(TextField) 的使用
		原文地址: Jetpack Compose学习(3)--图标(Icon) 按钮(Button) 输入框(TextField) 的使用 | Stars-One的杂货小窝 本篇分别对常用的组件:图标(Ic ... 
- Jetpack Compose学习(9)——Compose中的列表控件(LazyRow和LazyColumn)
		原文:Jetpack Compose学习(9)--Compose中的列表控件(LazyRow和LazyColumn) - Stars-One的杂货小窝 经过前面的学习,大致上已掌握了compose的基 ... 
- Jetpack Compose学习(1)——从登录页开始入门
		原文地址:Jetpack Compose学习(1)--从登录页开始入门 | Stars-One的杂货小窝 Jetpack Compose UI在前几天出了1.0正式版,之前一直还在观望,终于是出了正式 ... 
- Jetpack Compose学习(2)——文本(Text)的使用
		原文: Jetpack Compose学习(2)--文本(Text)的使用 | Stars-One的杂货小窝 对于开发来说,文字最为基础的组件,我们先从这两个使用开始吧 本篇涉及到Kotlin和DSL ... 
- Jetpack Compose学习(6)——关于Modifier的妙用
		原文: Jetpack Compose学习(6)--关于Modifier的妙用 | Stars-One的杂货小窝 之前学习记录中也是陆陆续续地将常用的Modifier的方法穿插进去了,本期就来详细的讲 ... 
- Jetpack Compose学习(8)——State及remeber
		原文地址: Jetpack Compose学习(8)--State状态及remeber关键字 - Stars-One的杂货小窝 之前我们使用TextField,使用到了两个关键字remember和mu ... 
- Jetpack Compose学习(11)——Navigation页面导航的使用
		原文:Jetpack Compose学习(11)--Navigation页面导航的使用 - Stars-One的杂货小窝 在Android原生的View开发中的,也是有Navigation,原生我之后 ... 
- Jetpack Compose学习(4)——Image(图片)使用及Coil图片异步加载库使用
		原文地址 Jetpack Compose学习(4)--Image(图片)使用及Coil图片异步加载库使用 | Stars-One的杂货小窝 本篇讲解下关于Image的使用及使用Coil开源库异步加载网 ... 
随机推荐
- 【VMware VCF】使用 PowerVCF 连接和管理 VMware Cloud Foundation 环境。
			VMware 有一个非常强大的命令行工具叫 PowerCLI,该工具是基于 PowerShell 开发的模块,主要用于在 Windows 环境中连接和管理传统虚拟化解决方案,比如 vSphere.vS ... 
- `->` 操作符重载的注意事项
			在 C++ 中,-> 操作符可以被重载,用于对象的指针成员访问. 重载后的 -> 操作符主要用于模拟指针访问行为,常见于智能指针的实现等复杂场景. -> 操作符重载后的调用触发流程: ... 
- vue 赶鸭子上架入门笔记(一) 安装开发环境
			准备接手一个 vue 的前端项目,从零开始学习 vue.目标不高大上,能看得懂代码,能进行简单的修改,改完能打包和部署. 首先解决 vue 开发环境的准备.访问 Node.js 官方网站,下载适合你操 ... 
- 分析ueventd Coldboot耗时问题
			安卓go平台启动时间发现如下ueventd耗时1.907s问题: 01-11 00:20:02.854 0 0 I init : Parsing file /odm/etc/init... 01-11 ... 
- MySQL精品学习资源合集 | 含学习教程笔记、运维技巧、图书推荐
			MySQL凭借开源.免费.低门槛.稳定等优势,成为了当前最流行的关系型数据库之一.从1998年发行第一版以来,通过不断地更新迭代,MySQL被越来越多的公司使用,已然成为当下潮流. 为了帮助大家更好地 ... 
- C# Webapi Filter 过滤器 - 生命周期钩子函数  - Exception Filter 基础
			什么是Filter ? 1. 切面编程机制,在 ASP.NET Core 特定的位置执行我们自定义的代码: 2. ASP.NET Core 中的Filter五种类型,Authorization ,fi ... 
- 使用zipkin配置spring boot的链路器(httpclient、restTemplate)
			一.首先导入zipkin需要的依赖 <!--zipkin-brave start--> <dependency> <groupId>io.zipkin.brave& ... 
- flink同步MySQL数据的时候出现内存溢出
			flink同步MySQL数据的时候出现内存溢出 背景:需要将1000w的某类型数据同步到别的数据源里面,使用公司的大数据平台可以很快处理完毕,而且使用的内存只有很少很少量(公司的大数据平台的底层是fl ... 
- 5.29 相约杭州!云原生 Meetup 第二期杭州站开启报名
			以容器技术和容器编排为基础的云原生应用,被越来越多的企业用户接受和使用,并且在生产环境中使用容器技术的比例逐年增加.KubeSphere 作为一款面向应用的开源容器混合云,经过 3 年的发展和 10 ... 
- activiti教程
			一.工作流介绍 1.1 概念 工作流(Workflow),就是通过计算机对业务流程自动化执行管理.它主要解决的是"使在多个参与者之间按照某种预定义的规则自动进行传递文档.信息或任务的过程,从 ... 
