Я показал изображения в TextView с помощью ImageSpan и загрузил их в RecyclerView . Прежде всего, я сопоставил шаблон регулярного выражения в тексте и применил Imagespan к этим сопоставленным позициям. Я реализовал Glide , чтобы изображение можно было рисовать с сервера.
fun stringToImage(string:String,imageSize:Int,callback:JoyPixelCallback ) {
val ssb = SpannableStringBuilder(string)
val matcher = joypixelEmojiMatcher(string)
val joyPixelMatcherRangeList = ArrayList<JoyPixelMatcherRange>()
while (matcher.find()) {
joyPixelMatcherRangeList.add(JoyPixelMatcherRange(
mappingString = matcher.group(0) ?: "",
startIndex = matcher.start(),
endIndex = matcher.end()
))
}
if (joyPixelMatcherRangeList.size == 0) {
callback.onSuccess(ssb)
}
replaceShortNameWithImages(ssb, imageSize, matchList, callback);
}
private fun replaceShortNameWithImages(ssb: SpannableStringBuilder, imageSize: Int, matchList: ArrayList<JoyPixelMatcherRange>,
callback: JoyPixelCallback) {
if (matchList.size == 0) {
callback.onSuccess(ssb)
} else {
try {
val shortName = matchList[0].mappingString
val start = matchList[0].startIndex
val end = matchList[0].endIndex
matchList.removeAt(0)
val cleanName = shortName.removePrefix("(:").removeSuffix(":)")
val emoji = cleanName.removeRange(0, cleanName.indexOf(":") + 1)
val categoryName = cleanName.substring(0, cleanName.indexOf(":"))
val url = "https://joypixel.s3-ap-southeast-2.amazonaws.com/emojis/$categoryName/$emoji.png"
if (url.contains(AppContracts.FileType.IMAGE_PNG)) {
Glide.with(context)
.asDrawable()
.diskCacheStrategy(DiskCacheStrategy.DATA)
.load(url)
.into(object : CustomTarget<Drawable>(imageSize, imageSize) {
override fun onResourceReady(bmpDrawable: Drawable, transition: Transition<in Drawable>?) {
try {
bmpDrawable.setBounds(0, 0, bmpDrawable.intrinsicWidth, bmpDrawable.intrinsicHeight)
ssb.setSpan(ImageSpan(bmpDrawable), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
replaceShortNameWithImages( ssb, imageSize, matchList, callback)
} catch (e: Exception) {
Timber.d("Joypixel Message : ${e.localizedMessage}")
}
}
override fun onLoadCleared(placeholder: Drawable?) {}
override fun onLoadFailed(errorDrawable: Drawable?) {
replaceShortNameWithImages( ssb, imageSize, matchList, callback)
super.onLoadFailed(errorDrawable)
}
})
}
} catch (e: Exception) {
e.printStackTrace()
callback.onSuccess(ssb)
}
}
}
Благодаря этому процессу рендеринг текста происходит очень медленно, а также наблюдается задержка при прокрутке. Однако, если я заменю совпадающий текст одним символом, производительность будет нормальной.
override fun onResourceReady(bmpDrawable: Drawable, transition: Transition<in Drawable>?) {
try {
val startIndex: Int = ssb.toString().indexOf(shortName)
bmpDrawable.setBounds(0, 0, bmpDrawable.intrinsicWidth, bmpDrawable.intrinsicHeight)
ssb.replace(startIndex, startIndex + shortName.length, ".")
ssb.setSpan(ImageSpan(bmpDrawable), startIndex, startIndex + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
replaceShortNameWithImages( ssb, imageSize, matchList, callback)
} catch (e: Exception) {
Timber.d("Joypixel Message : ${e.localizedMessage}")
}
}
Я пробовал использовать * preComputedText , но проблема все еще существует. Примечание: мне нужно повысить производительность без замены совпадающего текста одним символом.