z 索引未因状态更改而刷新
zIndex is not refeshing as result of state change
我设法解决了这个问题,并设置了 3 张卡片,一张放在另一张上面,作为单独的框组成具有 onclick 和 on drag 属性的元素。
现在的问题是,我希望我 pressing/dragging 的卡片设置在前面,所以,我使用了 z-index 修饰符,但是,看起来我做错了什么。有什么想法吗?
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Test1Theme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
for (i in 1 until 4) {
DraggableBox(title = "Box_${+1}", initX = 100f*i.toFloat(), initY = 100f, content =
{
Text(text = "Box_${i}", color = Color.White, fontSize = 16.sp, textAlign = TextAlign.Center)
}
)
}
}
}
}
}
}
@Composable
fun DraggableBox(title: String, initX: Float = 0f, initY: Float = 0f, content: @Composable() () -> Unit) {
val cardInitWidth = 135f
val cardInitHeight = 190f
val expandValue = 20f
Box(
modifier = Modifier
.fillMaxSize()
) {
val shape = RoundedCornerShape(12.dp)
val coroutineScope = rememberCoroutineScope()
val enable = remember { mutableStateOf(true) }
var offsetX = remember { Animatable(initialValue = initX) }
var offsetY = remember { Animatable(initialValue = initY) }
val interactionSource = remember { MutableInteractionSource() }
val clickable = Modifier.clickable(
interactionSource = interactionSource,
indication = LocalIndication.current
) { }
val isPressed by interactionSource.collectIsPressedAsState()
val size = animateSizeAsState(
targetValue = if (enable.value && !isPressed) {
Size(width = cardInitWidth, height = cardInitHeight)
} else {
Size(width = cardInitWidth + expandValue, height = cardInitHeight + expandValue)
}
)
Box(
Modifier
.offset {
IntOffset(
x = offsetX.value.roundToInt(),
y = offsetY.value.roundToInt()
)
}
.zIndex(zIndex = if (enable.value && !isPressed) 5f else 0f)
.size(size.value.width.dp, size.value.height.dp)
.clip(shape)
//.background(Color(0xFF5FA777))
.background(color = MaterialTheme.colors.primary)
.border(BorderStroke(2.dp, Color.Black), shape = shape)
.pointerInput(Unit) {
detectDragGestures(
onDragStart = {
enable.value = !enable.value
},
onDrag = { change, dragAmount ->
change.consumeAllChanges()
coroutineScope.launch {
offsetX.snapTo(targetValue = offsetX.value + dragAmount.x)
offsetY.snapTo(targetValue = offsetY.value + dragAmount.y)
}
spring(stiffness = Spring.StiffnessHigh, visibilityThreshold = 0.1.dp)
},
onDragEnd = {
enable.value = !enable.value
spring(stiffness = Spring.StiffnessLow, visibilityThreshold = 0.1.dp)
coroutineScope.launch {
launch {
offsetY.animateTo(
targetValue = initY,
animationSpec = tween(
durationMillis = 700,
delayMillis = 50,
easing = LinearOutSlowInEasing
)
)
}
offsetX.animateTo(
targetValue = initX,
animationSpec = tween(
durationMillis = 700,
delayMillis = 50,
easing = LinearOutSlowInEasing
)
)
}
}
)
}
.then(clickable)
) {
Row (modifier = Modifier
.fillMaxHeight(),
verticalAlignment = Alignment.CenterVertically
)
{
Column (modifier = Modifier
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
)
{
Column (
horizontalAlignment = Alignment.CenterHorizontally
)
{
Text(text = "init-X: ${initX.toString()}", color = Color.White, fontSize = 16.sp, textAlign = TextAlign.Center)
Text(text = "init-Y: ${initY.toString()}", color = Color.White, fontSize = 16.sp, textAlign = TextAlign.Center)
}
Column (
horizontalAlignment = Alignment.CenterHorizontally
)
{
Text(text = "offset-X: ${offsetX.value.roundToInt().toString()}", color = Color.White, fontSize = 16.sp, textAlign = TextAlign.Center)
Text(text = "offset-Y: ${offsetY.value.roundToInt().toString()}", color = Color.White, fontSize = 16.sp, textAlign = TextAlign.Center)
}
Column (
horizontalAlignment = Alignment.CenterHorizontally
)
{
content()
}
}
}
}
}
}
Modifier.zIndex
仅适用于同一父项中的子项。
在您的情况下,您应该将此修饰符移动到最顶层 Box
。为此,您还必须将 enable
和 isPressed
向上移动一个级别,我也会移动所有其他变量 - 但我想这只是个人喜好问题。
val enable = remember { mutableStateOf(true) }
val isPressed by interactionSource.collectIsPressedAsState()
Box(
modifier = Modifier
.fillMaxSize()
.zIndex(zIndex = if (enable.value && !isPressed) 5f else 0f)
) {
// ...
我设法解决了这个问题,并设置了 3 张卡片,一张放在另一张上面,作为单独的框组成具有 onclick 和 on drag 属性的元素。 现在的问题是,我希望我 pressing/dragging 的卡片设置在前面,所以,我使用了 z-index 修饰符,但是,看起来我做错了什么。有什么想法吗?
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
Test1Theme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
for (i in 1 until 4) {
DraggableBox(title = "Box_${+1}", initX = 100f*i.toFloat(), initY = 100f, content =
{
Text(text = "Box_${i}", color = Color.White, fontSize = 16.sp, textAlign = TextAlign.Center)
}
)
}
}
}
}
}
}
@Composable
fun DraggableBox(title: String, initX: Float = 0f, initY: Float = 0f, content: @Composable() () -> Unit) {
val cardInitWidth = 135f
val cardInitHeight = 190f
val expandValue = 20f
Box(
modifier = Modifier
.fillMaxSize()
) {
val shape = RoundedCornerShape(12.dp)
val coroutineScope = rememberCoroutineScope()
val enable = remember { mutableStateOf(true) }
var offsetX = remember { Animatable(initialValue = initX) }
var offsetY = remember { Animatable(initialValue = initY) }
val interactionSource = remember { MutableInteractionSource() }
val clickable = Modifier.clickable(
interactionSource = interactionSource,
indication = LocalIndication.current
) { }
val isPressed by interactionSource.collectIsPressedAsState()
val size = animateSizeAsState(
targetValue = if (enable.value && !isPressed) {
Size(width = cardInitWidth, height = cardInitHeight)
} else {
Size(width = cardInitWidth + expandValue, height = cardInitHeight + expandValue)
}
)
Box(
Modifier
.offset {
IntOffset(
x = offsetX.value.roundToInt(),
y = offsetY.value.roundToInt()
)
}
.zIndex(zIndex = if (enable.value && !isPressed) 5f else 0f)
.size(size.value.width.dp, size.value.height.dp)
.clip(shape)
//.background(Color(0xFF5FA777))
.background(color = MaterialTheme.colors.primary)
.border(BorderStroke(2.dp, Color.Black), shape = shape)
.pointerInput(Unit) {
detectDragGestures(
onDragStart = {
enable.value = !enable.value
},
onDrag = { change, dragAmount ->
change.consumeAllChanges()
coroutineScope.launch {
offsetX.snapTo(targetValue = offsetX.value + dragAmount.x)
offsetY.snapTo(targetValue = offsetY.value + dragAmount.y)
}
spring(stiffness = Spring.StiffnessHigh, visibilityThreshold = 0.1.dp)
},
onDragEnd = {
enable.value = !enable.value
spring(stiffness = Spring.StiffnessLow, visibilityThreshold = 0.1.dp)
coroutineScope.launch {
launch {
offsetY.animateTo(
targetValue = initY,
animationSpec = tween(
durationMillis = 700,
delayMillis = 50,
easing = LinearOutSlowInEasing
)
)
}
offsetX.animateTo(
targetValue = initX,
animationSpec = tween(
durationMillis = 700,
delayMillis = 50,
easing = LinearOutSlowInEasing
)
)
}
}
)
}
.then(clickable)
) {
Row (modifier = Modifier
.fillMaxHeight(),
verticalAlignment = Alignment.CenterVertically
)
{
Column (modifier = Modifier
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
)
{
Column (
horizontalAlignment = Alignment.CenterHorizontally
)
{
Text(text = "init-X: ${initX.toString()}", color = Color.White, fontSize = 16.sp, textAlign = TextAlign.Center)
Text(text = "init-Y: ${initY.toString()}", color = Color.White, fontSize = 16.sp, textAlign = TextAlign.Center)
}
Column (
horizontalAlignment = Alignment.CenterHorizontally
)
{
Text(text = "offset-X: ${offsetX.value.roundToInt().toString()}", color = Color.White, fontSize = 16.sp, textAlign = TextAlign.Center)
Text(text = "offset-Y: ${offsetY.value.roundToInt().toString()}", color = Color.White, fontSize = 16.sp, textAlign = TextAlign.Center)
}
Column (
horizontalAlignment = Alignment.CenterHorizontally
)
{
content()
}
}
}
}
}
}
Modifier.zIndex
仅适用于同一父项中的子项。
在您的情况下,您应该将此修饰符移动到最顶层 Box
。为此,您还必须将 enable
和 isPressed
向上移动一个级别,我也会移动所有其他变量 - 但我想这只是个人喜好问题。
val enable = remember { mutableStateOf(true) }
val isPressed by interactionSource.collectIsPressedAsState()
Box(
modifier = Modifier
.fillMaxSize()
.zIndex(zIndex = if (enable.value && !isPressed) 5f else 0f)
) {
// ...