夏季兒看看:
嵌套滑動(NestedScroll) | 你好 Compose
章節(jié)中的nestscroll
示例:伸縮 ToolBar
樣例的代碼地址:Compose 伸縮 ToolBar 的實現(xiàn) | 你好 Compose
看到效果我想實現(xiàn),滾動的時候,向上滾動,先折疊圖片。向下滾動,先滾動列表,以保持最大的可視數(shù)據(jù)窗口
package com.example.myapplication.ui.nestscrolltest
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.max
import com.example.myapplication.R
/**
*
* ╭︿︿︿╮
* {/ . . /}
* ( (oo) )
* ︶︶︶
* Create by cps 2025/6/24 15:13
*
*/
@Composable
fun ScrollBarView() {
Surface(modifier = Modifier.fillMaxWidth(), color = Color.Gray) {
val toolbarHeight = 200.dp
var total = 0f
val maxUpPx = with(LocalDensity.current) {
total = toolbarHeight.roundToPx().toFloat()
toolbarHeight.roundToPx().toFloat() - 56.dp.roundToPx().toFloat()
}
val minUpPx = 0f
val toolbarOffsetHeightPx = remember {
mutableFloatStateOf(0f)
}
val lazyListstate = rememberLazyListState(0, 0)
val totalOffset by remember {
derivedStateOf {
var offset = 0
for (i in 0 until lazyListstate.firstVisibleItemIndex) {
offset += lazyListstate.layoutInfo.visibleItemsInfo.firstOrNull { it.index == i }?.size
?: 0
}
offset + lazyListstate.firstVisibleItemScrollOffset
offset
}
}
/**
* 實現(xiàn)原理是: colume list 是一直滾動的
* 唯一的區(qū)別是 ttilebar 的offset 什么時候需要執(zhí)行
*/
val nestedScrollConnect = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
val delta = available.y
println("$totalOffset ${toolbarOffsetHeightPx.floatValue} $total")
if (delta > 0) {
if (totalOffset + toolbarOffsetHeightPx.floatValue.toInt() < 0) { //list的滾動偏移量跟目前的offset 一樣了,需要減小offset 了
val newOffset = toolbarOffsetHeightPx.floatValue + delta
toolbarOffsetHeightPx.floatValue = newOffset.coerceIn(-maxUpPx, minUpPx)
}
return Offset.Zero
}
val newOffset = toolbarOffsetHeightPx.floatValue + delta
toolbarOffsetHeightPx.floatValue = newOffset.coerceIn(-maxUpPx, minUpPx)
return Offset.Zero
}
//不需要
// override fun onPostScroll(
// consumed: Offset,
// available: Offset,
// source: NestedScrollSource
// ): Offset {
// if (totalOffset + toolbarOffsetHeightPx.floatValue.toInt() < 0) {
// return Offset.Zero
// } else {
// return available
// }
// }
}
}
Box(
Modifier
.fillMaxSize()
.nestedScroll(nestedScrollConnect)
) {
LazyColumn(
contentPadding = PaddingValues(top = toolbarHeight),
state = lazyListstate
) {
items(100) {
Text(
"$it --------", Modifier
.fillMaxWidth()
.padding(16.dp)
.clickable {
println("it$it clicked")
}
)
}
}
}
ScrollableAppBar(
title = "測試滾動",
bgImageId = R.drawable.img,
scrollableAppBarHeight = toolbarHeight,
toolbarOffsetHeightPx = toolbarOffsetHeightPx
)
}
}
實現(xiàn)原理其實就一句 實現(xiàn)原理是: colume list 是一直滾動的
* 唯一的區(qū)別是 ttilebar 的offset 什么時候需要執(zhí)行