你可以使用
FlowRow
、
Chip
和
BasicTextField
来实现它。
1- 创建一个数据类,它包含Uri和String的属性。
@Immutable
data class ChipData(
val uri: Uri,
val text: String,
val id: String = UUID.randomUUID().toString()
)
2- 创建自定义芯片,显示图像和字符串。我使用了Coil库来获取Uri中的Painter。
@Composable
private fun MyChip(
backgroundColor: Color,
data: ChipData,
onDeleteClick: () -> Unit
) {
Chip(
modifier = Modifier,
shape = RoundedCornerShape(50),
enabled = false,
onClick = {},
border = BorderStroke(1.dp, Green400.copy(alpha = .9f)),
colors = ChipDefaults.chipColors(
disabledBackgroundColor = backgroundColor,
disabledContentColor = Color.White
),
leadingIcon = {
Image(
painter = rememberAsyncImagePainter(data.uri),
modifier = Modifier
.padding(vertical = 4.dp)
.size(34.dp)
.clip(CircleShape),
contentScale = ContentScale.FillBounds,
contentDescription = null
)
}
) {
Text(
text = data.text,
modifier = Modifier.weight(1f, fill = false),
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
Spacer(modifier = Modifier.width(ButtonDefaults.IconSpacing))
Icon(
modifier = Modifier
.clip(CircleShape)
.clickable {
onDeleteClick()
}
.background(Color.Black.copy(alpha = .4f))
.size(16.dp)
.padding(2.dp),
imageVector = Icons.Filled.Close,
tint = Color(0xFFE0E0E0),
contentDescription = null
)
}
}
3- 使用
FlowRow
来对齐芯片,并将一个BasicTextField放在最后一项。
另外,我使用了rememberLauncherForActivityResult来选择图片,你可以将其添加到gradle中。
implementation("com.google.modernstorage:modernstorage-photopicker:1.0.0-alpha06")
如果你想的话,你可以在SAF中使用另一个或默认的图片选择器。
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun ChipAndTextFieldLayout(
modifier: Modifier = Modifier,
backgroundColor: Color,
list: List<ChipData> = emptyList(),
onChipCreated: (ChipData) -> Unit,
chip: @Composable (data: ChipData, index: Int) -> Unit
) {
var text by remember {
mutableStateOf("")
}
val focusRequester = remember {
FocusRequester()
}
val keyboardController: SoftwareKeyboardController? = LocalSoftwareKeyboardController.current
val photoPicker =
rememberLauncherForActivityResult(PhotoPicker()) { uris ->
uris.firstOrNull()?.let { uri: Uri ->
onChipCreated(
ChipData(
uri = uri,
text = text
)
)
text = ""
keyboardController?.show()
}
}
LaunchedEffect(Unit) {
delay(100)
focusRequester.requestFocus()
}
FlowRow(
modifier = modifier
.drawWithContent {
drawContent()
drawLine(
Green400.copy(alpha = .6f),
start = Offset(0f, size.height),
end = Offset(size.width, size.height),
strokeWidth = 4.dp.toPx()
)
},
horizontalArrangement = Arrangement.spacedBy(6.dp)
) {
list.forEachIndexed { index, item ->
key(item.id) {
chip(item, index)
}
}
Box(
modifier = Modifier.height(54.dp)
.widthIn(min = 80.dp)
.weight(1f),
contentAlignment = Alignment.CenterStart
) {
BasicTextField(
modifier = Modifier.focusRequester(focusRequester),
value = text,
textStyle = TextStyle(
fontSize = 20.sp
),
cursorBrush = SolidColor(backgroundColor),
singleLine = true,
onValueChange = { text = it },
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Done
),
keyboardActions = KeyboardActions(
onDone = {
if (text.isNotEmpty()) {
keyboardController?.hide()
photoPicker.launch(
PhotoPicker.Args(
PhotoPicker.Type.IMAGES_ONLY, 1
)
)
}
}
)
)
}
}
}
使用方法
@Preview
@Composable
private fun ChipSampleAndTextLayoutSample() {
val backgroundColor = Green400.copy(alpha = .6f)
val chipDataSnapshotStateList = remember {
mutableStateListOf<ChipData>()
}
ChipAndTextFieldLayout(
modifier = Modifier.fillMaxWidth().padding(8.dp),
list = chipDataSnapshotStateList,
backgroundColor = backgroundColor,
onChipCreated = {
chipDataSnapshotStateList.add(it)
},
chip = { data: ChipData, index: Int->
MyChip(backgroundColor, data){
chipDataSnapshotStateList.removeAt(index)
}
}
)
}