Jetpack Compose实现类似Viewpager滚动
通过扩展Row实现简单的viewpager
fun Modifier.horizontalScroll(
state: ScrollState,
enabled: Boolean = true,
flingBehavior: FlingBehavior? = null,
reverseScrolling: Boolean = false
) = scroll(
state = state,
isScrollable = enabled,
reverseScrolling = reverseScrolling,
flingBehavior = flingBehavior,
isVertical = false
)
上面是compose水平滚动的方法 state 用来操作滚动条状态 flingBehavior 是手指释放后的惯性事件,通过自定义FlingBehavior 在手指释放的时候判断

fling类
@Composable
fun pagerFlingBehavior(state: ScrollState,childNum: Int): FlingBehavior {
val flingSpec = rememberSplineBasedDecay<Float>()
return remember(flingSpec) {
PagerFling(flingSpec, state,childNum = childNum)
}
}
class PagerFling(private val flingDecay: DecayAnimationSpec<Float>,val state:ScrollState,
var childNum:Int) : FlingBehavior {
override suspend fun ScrollScope.performFling(initialVelocity: Float): Float {
// come up with the better threshold, but we need it since spline curve gives us NaNs
// Log.e("lin","velocity=$initialVelocity,value=${state.value},maxValue=${state.maxValue}")
return if (abs(initialVelocity) >= 0f) {
var velocityX = initialVelocity
var childWidth = state.maxValue/(childNum-1)
var destValue = 0f
var childLeft = state.value%childWidth;
if(abs(velocityX)<500){
if(childLeft<childWidth/2){
destValue = state.value.toFloat()-childLeft
}else{
destValue = state.value.toFloat()-childLeft+childWidth;
}
}else{
if(velocityX<0)
destValue = state.value.toFloat()-childLeft
else
destValue = state.value.toFloat()-childLeft+childWidth;
}
var velocityLeft = initialVelocity
var startPos = state.value
animate(state.value.toFloat(),destValue,0f){value, velocity ->
velocityLeft = value-startPos
scrollBy(velocityLeft)
startPos = value.toInt()
}
velocityLeft
} else {
initialVelocity
}
}
}
测试类
@Composable
fun SwipeableSample() {
var list = mutableListOf<String>()
for (i in 0..10)
list.add("$i")
var width = LocalConfiguration.current.screenWidthDp
var height = LocalConfiguration.current.screenHeightDp
val state = rememberScrollState()
ComposeLauncherTheme {
Scaffold(
topBar = { TopAppBar(backgroundColor = Color.Red) {
Text(text = "Test Compose", color = Color.White
,fontSize = 22.sp,
modifier = Modifier.offset(x=10.dp)
)
} },
content = {
Row(modifier = Modifier
.width(width = width.dp)
.horizontalScroll(state,flingBehavior = pagerFlingBehavior(state,list.size))
) {
repeat(list.size){
Text(text = "1111 $it",
modifier = Modifier.width(width =width.dp).height(height = height.dp))
Log.e("lin","init $it")
}
}
}
)
}

浙公网安备 33010602011771号