Android создает TextField с изображением, используя InlineTextContentAndroid

Форум для тех, кто программирует под Android
Ответить
Гость
 Android создает TextField с изображением, используя InlineTextContent

Сообщение Гость »


Я разрабатываю приложение для Android с помощью Jetpack Compose.
Я хочу реализовать TextField. Это TextField должно отображать небольшой смайлик или изображение вместо текста при вводе определенного токена.
Такой случай можно найти в приложении Slack. Приложение Slack поддерживает собственные смайлы в дополнение к обычным смайлам.
InlineTextContent я обнаружил в качестве подсказки.

Код: Выделить всё

val inlineContentMap = mapOf(
"ab_12" to emojiImage("https://c.tenor.com/Rd6ULrCRvlQAAAAd/tenor.gif")
)

var inputText by remember { mutableStateOf("") }
BasicTextField(
value = inputText,
onValueChange = {
inputText = it
},
modifier = Modifier
.fillMaxWidth()
.border(1.dp, Color.LightGray, RoundedCornerShape(4.dp))
.padding(8.dp),
textStyle = TextStyle(fontSize = 16.sp).copy(color = Color.Transparent),
visualTransformation = EmojiVisualTransformation,
decorationBox = { innerTextField ->
Box(
modifier = Modifier,
contentAlignment = Alignment.TopStart
) {
val annotatedString = replaceTokens(inputText)
Text(
text = annotatedString,
style = TextStyle(fontSize = 16.sp),
inlineContent = inlineContentMap
)
innerTextField()
}
}
)
и вот другие функции:

Код: Выделить всё

@Composable
private fun emojiImage(imgUrl: String) =
InlineTextContent(Placeholder(16.sp, 16.sp, PlaceholderVerticalAlign.TextCenter)) {
val context = LocalContext.current
val imageLoader = ImageLoader.Builder(context)
.components {
add(ImageDecoderDecoder.Factory())
}
.build()
Image(
painter = rememberAsyncImagePainter(
model = ImageRequest.Builder(context)
.data(data = imgUrl)
.build(),
imageLoader = imageLoader
),
contentDescription = null,
modifier = Modifier.size(16.dp),
)
}

private fun replaceTokens(input: String): AnnotatedString {
val annotatedString = buildAnnotatedString {
val regex = Regex("\\{:(\\w+_\\d+):\\}")
var currentIndex = 0
regex.findAll(input).forEach { matchResult ->
val token = matchResult.groupValues[1]
val tokenIndex = matchResult.range.first
val tokenLength = matchResult.value.length
append(input.substring(currentIndex, tokenIndex))
appendInlineContent(id = token)
currentIndex = tokenIndex + tokenLength
}
append(input.substring(currentIndex, input.length))
}
return annotatedString
}
Вот VisualTransformation:

Код: Выделить всё

object EmojiVisualTransformation: VisualTransformation {

override fun filter(text: AnnotatedString): TransformedText {
val originText = text.text

val annotatedString = replaceTokens(originText)

return TransformedText(annotatedString, EmojiOffsetMapping(originText, annotatedString.text))
}
}

data class EmojiOffsetMapping(
private val origin: String,
private val transformed: String,
): OffsetMapping {

private val tokenPositionRanges = mutableListOf()

init {
val regex = Regex("\\{:(\\w+_\\d+):\\}")
regex.findAll(origin).forEach { matchResult ->
val tokenPosition = matchResult.range
tokenPositionRanges.add(tokenPosition)
}
}

private fun getTransformedOffset(offset: Int): Int {
if (offset == 0) {
return 0
}

var newOffset = offset
tokenPositionRanges.forEachIndexed { index, tokenRange ->
if (tokenRange.first + 1 

Источник: [url]https://stackoverflow.com/questions/78145214/android-compose-textfield-with-image-using-inlinetextcontent[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»