Cri*_*che 4 android kotlin android-chips android-jetpack-compose android-jetpack-compose-material3
我正在尝试实现与照片类似的行为。一个可以做同样事情的库也会很有用。我已经尝试过 https://github.com/dokar3/ChipTextField 但遇到了一些问题
java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/compose/ui/platform/LocalSoftwareKeyboardController;
Run Code Online (Sandbox Code Playgroud)
Thr*_*ian 10
您可以使用FlowRow,Chip和来实现它BasicTextField。
1-创建一个包含 Uri 和 String 的数据类
@Immutable
data class ChipData(
val uri: Uri,
val text: String,
val id: String = UUID.randomUUID().toString()
)
Run Code Online (Sandbox Code Playgroud)
2- 创建显示图像、字符串的自定义芯片。我使用Coil画家图书馆来Painter获取Uri。
@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
)
}
}
Run Code Online (Sandbox Code Playgroud)
3- 用于FlowRow对齐碎片并将 BasicTextField 放在最后一项。
我还使用 RememberLauncherForActivityResult 来选择可以添加到 gradle 的图像
implementation("com.google.modernstorage:modernstorage-photopicker:1.0.0-alpha06")
Run Code Online (Sandbox Code Playgroud)
如果您愿意,可以将其他图像选择器或默认图像选择器与 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 = ""
// Open keyboard after new chip is added
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)
// This minimum width that TextField can have
// if remaining space in same row is smaller it's moved to next line
.widthIn(min = 80.dp)
// TextField can grow as big as Composable width
.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
)
)
}
}
)
)
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法
@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)
}
}
)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
724 次 |
| 最近记录: |