我正在使用运动布局来构建折叠工具栏。
组件如下所示
@Composable
fun CollapsingToolbarWithStartEndIcon(
title: String,
expandedFontSize: Dp = 34.dp,
collapsedFontSize: Dp = 20.dp,
textStyle: TextStyle = MaterialTheme.typography.h6.copy(
color = MaterialTheme.colors.onPrimary
),
backgroundColor: Color = MaterialTheme.colors.primary,
startIcon: Int,
startIconTint: Color = MaterialTheme.colors.onPrimary,
startIconModifier: Modifier = Modifier
.size(defaultIconSize),
endIcon: Int,
endIconTint: Color = MaterialTheme.colors.onPrimary,
endIconModifier: Modifier = Modifier
.size(defaultIconSize),
motionLayoutModifier: Modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colors.onPrimary),
scrollState: Any,
onStartIconClick: () -> Unit,
onEndIconClick: () -> Unit,
startConstraintSet:ConstraintSet = CollapsingTopBarUtils.startConstraintSet(),
endConstraintSet:ConstraintSet = CollapsingTopBarUtils.endConstraintSet(),
motionTime:Int = 500
) {
when (scrollState) {
is LazyListState -> {
val progress by animateFloatAsState(
targetValue = if (scrollState.firstVisibleItemIndex <= 0) 0f else 1f,
tween(motionTime)
)
val motionHeight by animateDpAsState(
targetValue = if (scrollState.firstVisibleItemIndex <= 0) collapsingTopAppBarHeights else collapsedTopAppBarHeights,
tween(motionTime)
)
val fontSize by animateDpAsState(
targetValue = if (scrollState.firstVisibleItemIndex <= 0) expandedFontSize else collapsedFontSize,
tween(motionTime)
)
MotionLayout(
motionLayoutModifier = motionLayoutModifier,
motionHeight =motionHeight ,
progress = progress,
backgroundColor = backgroundColor,
startIconModifier = startIconModifier ,
onStartIconClick = onStartIconClick,
startIconId = startIcon ,
startIconTint = startIconTint,
endIconModifier = endIconModifier,
onEndIconClick = onEndIconClick,
endIconId = endIcon,
endIconTint = endIconTint,
title = title,
textStyle = textStyle,
fontSize = fontSize,
startConstraintSet = startConstraintSet,
endConstraintSet = endConstraintSet
)
}
is ScrollState -> {
val progress by animateFloatAsState(
targetValue = if (scrollState.value <= 0) 0f else 1f,
tween(motionTime)
)
val motionHeight by animateDpAsState(
targetValue = if (scrollState.value <= 0) collapsingTopAppBarHeights else collapsedTopAppBarHeights,
tween(motionTime)
)
val fontSize by animateDpAsState(
targetValue = if (scrollState.value <= 0) expandedFontSize else collapsedFontSize,
tween(motionTime)
)
MotionLayout(
motionLayoutModifier = motionLayoutModifier,
motionHeight =motionHeight ,
progress = progress,
backgroundColor = backgroundColor,
startIconModifier = startIconModifier ,
onStartIconClick = onStartIconClick,
startIconId = startIcon ,
startIconTint = startIconTint,
endIconModifier = endIconModifier,
onEndIconClick = onEndIconClick,
endIconId = endIcon,
endIconTint = endIconTint,
title = title,
textStyle = textStyle,
fontSize = fontSize,
startConstraintSet = startConstraintSet,
endConstraintSet = endConstraintSet
)
}
}
}
@Composable
@OptIn(ExperimentalMotionApi::class)
private fun MotionLayout(
motionLayoutModifier: Modifier,
motionHeight: Dp,
progress: Float,
backgroundColor: Color,
startIconModifier: Modifier,
onStartIconClick: () -> Unit,
startIconId: Int,
startIconTint: Color,
endIconModifier: Modifier,
onEndIconClick: () -> Unit,
endIconId: Int,
endIconTint: Color,
title: String,
textStyle: TextStyle,
fontSize: Dp,
startConstraintSet:ConstraintSet,
endConstraintSet:ConstraintSet
) {
MotionLayout(
modifier = motionLayoutModifier.height(motionHeight),
start = startConstraintSet,
end = endConstraintSet,
progress = progress,
) {
Box(
modifier = Modifier
.layoutId(BOX)
.testTag(TOP_APP_BAR_BOX)
.background(backgroundColor)
)
IconButton(modifier = startIconModifier
.layoutId(START_ICON)
.testTag(ACTION_ICON1),
onClick = { onStartIconClick.invoke() }) {
Icon(
painter = painterResource(id = startIconId),
tint = startIconTint,
contentDescription = stringResource(R.string.close_icon),
modifier = Modifier.fillMaxSize()
)
}
IconButton(modifier = endIconModifier
.layoutId(END_ICON)
.testTag(ACTION_ICON2),
onClick = { onEndIconClick.invoke() }) {
Icon(
painter = painterResource(id = endIconId),
tint = endIconTint,
contentDescription = stringResource(R.string.email_icon),
modifier = Modifier.fillMaxSize()
)
}
Text(
modifier = Modifier
.layoutId(TITLE)
.testTag(TOP_APP_BAR_TITLE),
text = title,
style = textStyle.copy(fontSize = fontSize.value.sp)
)
}
}
json约束如下所示
object CollapsingTopBarUtils {
@Composable
fun startConstraintSet() = ConstraintSet(
""" {
box: {
width: 'spread',
height: 138,
start: ['parent', 'start'],
end: ['parent', 'end'],
top: ['parent', 'top'],
bottom: ['parent','bottom',16]
},
end_icon:{
end: ['box', 'end', 16],
top: ['box', 'top', 16],
},
start_icon:{
start: ['box', 'start', 16],
top: ['box', 'top', 16]
},
title: {
start: ['box', 'start', 16],
bottom: ['box', 'bottom',16]
}
} """
)
@Composable
fun endConstraintSet() = ConstraintSet(
""" {
end_icon:{
top: ['box','top'],
bottom: ['box', 'bottom'],
end: ['box', 'end',16]
},
box: {
width: 'spread',
height: 56,
start: ['parent', 'start'],
end: ['parent', 'end'],
top: ['parent', 'top'],
},
start_icon:{
start: ['box', 'start',16],
bottom: ['box', 'bottom'],
top: ['box', 'top']
},
title: {
start: ['start_icon', 'end', 16],
bottom: ['start_icon', 'bottom'],
top: ['start_icon', 'top']
}
}"""
)
}
如下所示使用此组件
setContent {
OnlyLightTheme {
val lazyScrollState = rememberLazyListState()
Scaffold(
modifier = Modifier
.fillMaxSize(),
topBar = {
CollapsingToolbarWithStartEndIcon(
title = "auto",
scrollState =lazyScrollState ,
onStartIconClick = { finish() },
startIconTint = AllstateBlue,
endIconTint = AllstateBlue,
startIcon = R.drawable.icon_close_blue,
endIcon = R.drawable.ic_actions_email_contact,
onEndIconClick = { }
)
},
) { paddingValues ->
Column(modifier = Modifier.padding(paddingValues)) {
LazyColumn(
modifier = Modifier
.fillMaxSize()
.background(color = Color.White)
.animateContentSize(),
state = lazyScrollState
) {
val aa = listOf(
"hjhss",
"hhhdhd",
"hfhfh",
"hfhf",
"hhhd",
"hjhss",
"hhhdhd",
"hfhfh",
"hfhf",
"hhhd",
"hjhss",
"hhhdhd",
"hfhfh",
"hfhf",
"hhhd",
"hjhss",
"hhhdhd",
"hfhfh",
"hfhf",
"hhhd",
"hjhss",
"hhhdhd",
"hfhfh",
"hfhf",
"hhhd",
"hjhss",
"hhhdhd",
"hfhfh",
"hfhf",
"hhhd"
)
items(aa) {
Text(text = "Item: $it")
}
}
}
}
}
}
}
}
折叠工具栏是不工作,没有填充到项目。如果我给它的作品pading的例子:以下代码不起作用
items(aa) {
Text(text = "Item: $it")
}
当它工作时
items(aa) {
Text(text = "Item: $it", modifier = Modifier.padding(16.dp))
}
没有得到所缺少的东西?
1条答案
按热度按时间dsekswqp1#
CollapsingToolbar在没有填充的情况下无法工作,因为列表不会溢出以激活动画布局。
插入填充后,列表将溢出可用屏幕(视口)高度,从而使工具栏可以在需要的位置折叠
您可以向LazyColumn中添加一个空格作为一个项,使其按照从answer获得的内容滚动