我最终做了一个看起来工作正常的小技巧,所以基本上我添加了一个虚拟 Box 作为 trailingIcon 来获取它的位置,然后我在它外面添加了一个 IconButton(都包裹在一个 Box 中)和我也得到了它的位置+我使用虚拟框的位置来偏移它。不是理想的解决方案,但效果很好。
如果有人需要,这里是完整的来源:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
Surface(
modifier = Modifier.padding(16.dp),
color = MaterialTheme.colors.background
) {
var text by remember { mutableStateOf("") }
var trailingIconOffset by remember { mutableStateOf(Offset.Zero) }
var iconButtonOffset by remember { mutableStateOf(Offset.Zero) }
val colors = TextFieldDefaults.outlinedTextFieldColors()
Column {
//With hack
Box {
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
label = { Text(text = "With hack") },
value = text,
onValueChange = { text = it },
trailingIcon = {
Box(modifier = IconButtonSizeModifier
.onGloballyPositioned {
trailingIconOffset = it.positionInRoot()
}
)
},
colors = colors
)
val contentColor by colors.trailingIconColor(
enabled = true,
isError = false
)
CompositionLocalProvider(
LocalContentColor provides contentColor,
LocalContentAlpha provides contentColor.alpha
) {
IconButton2(
modifier = Modifier
.onGloballyPositioned {
iconButtonOffset = it.positionInRoot()
}
.absoluteOffset {
IntOffset(
(trailingIconOffset.x - iconButtonOffset.x).toInt(),
(trailingIconOffset.y - iconButtonOffset.y).toInt()
)
},
onClick = {
text = "onClick"
},
onLongClick = {
text = "onLongClick"
}
) {
Icon(imageVector = Icons.Filled.Menu, contentDescription = null)
}
}
}
//Without hack
Box {
OutlinedTextField(
modifier = Modifier.fillMaxWidth(),
label = { Text(text = "Without hack") },
value = text,
onValueChange = { text = it },
trailingIcon = {
IconButton2(
onClick = {
text = "onClick"
},
onLongClick = {
text = "onLongClick"
}
) {
Icon(
imageVector = Icons.Filled.Menu,
contentDescription = null
)
}
},
colors = colors
)
}
}
}
}
}
}
}
private val RippleRadius = 24.dp
private val IconButtonSizeModifier = Modifier.size(48.dp)
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun IconButton2(
modifier: Modifier = Modifier,
onClick: () -> Unit,
onLongClick: (() -> Unit)? = null,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: @Composable () -> Unit
) {
Box(
modifier = modifier
.combinedClickable(
onClick = onClick,
onLongClick = onLongClick,
enabled = enabled,
role = Role.Button,
interactionSource = interactionSource,
indication = rememberRipple(bounded = false, radius = RippleRadius)
)
.then(IconButtonSizeModifier),
contentAlignment = Alignment.Center
) {
val contentAlpha = if (enabled) LocalContentAlpha.current else ContentAlpha.disabled
CompositionLocalProvider(LocalContentAlpha provides contentAlpha, content = content)
}
}