存在图像时HtmlTextView不调整大小



我遇到HtmlTextView的问题,当响应体中存在图像标记时,textview不会调整大小以显示内容。

p。S-重新打开同一屏幕时,文本视图将正确显示。只有在第一次打开时才起作用

请参阅下面ImageGetter的附加代码,

package com.desidime.editor.editor.render
import android.graphics.Canvas
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.util.Log
import android.view.View
import android.widget.TextView
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
import com.desidime.editor.editor.Constants
import com.desidime.editor.editor.Constants.dp2px
import com.desidime.editor.editor.inner.Html
import java.lang.ref.WeakReference
class AreImageGetter(private val container: TextView) : Html.ImageGetter {
override fun getDrawable(source: String): Drawable {
val urlDrawable = UrlDrawable()
val target = ImageGetterTarget(urlDrawable, this, container, true, Constants.isEmoji(source),
Constants.SCREEN_WIDTH)
Glide.with(container.context)
.asDrawable()
.load(source)
.apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL))
.into(target)
return urlDrawable
}

private class ImageGetterTarget(urlDrawable: UrlDrawable,
imageGetter: AreImageGetter,
container: View,
private val matchParentWidth: Boolean,
private val isEmoji: Boolean,
maxWidth: Int) : SimpleTarget<Drawable>(maxWidth, Target.SIZE_ORIGINAL) {
private val drawableReference: WeakReference<UrlDrawable> = WeakReference(urlDrawable)
private val imageGetterReference: WeakReference<AreImageGetter> = WeakReference(imageGetter)
private val containerReference: WeakReference<View> = WeakReference(container)
private var scale: Float = 1f
private fun getScale(drawable: Drawable): Float {
val container = containerReference.get()
if (!matchParentWidth || container == null) {
return 1f
}
val maxWidth = container.width.toFloat() - container.paddingLeft - container.paddingRight
val originalDrawableWidth = drawable.intrinsicWidth.toFloat()
println(
"/*-------------------------------------------------------------------------------------------*/")
println("maxWidth : $maxWidth")
println("container.width.toFloat() : ${container.width.toFloat()}")
println("container.paddingLeft : ${container.paddingLeft}")
println("container.paddingRight : ${container.paddingRight}")
println("originalDrawableWidth : $originalDrawableWidth")
println("drawable.intrinsicWidth.toFloat() : ${drawable.intrinsicWidth.toFloat()}")

return maxWidth / originalDrawableWidth
}
override fun onResourceReady(drawable: Drawable, transition: Transition<in Drawable>?) {
val urlDrawable = drawableReference.get() ?: return
if (isEmoji) {
if (containerReference.get() != null) {
val dp2px = dp2px(containerReference.get()?.context, 24f)
drawable.setBounds(0, 0, dp2px, dp2px)
urlDrawable.setBounds(0, 0, drawable.bounds.right, drawable.bounds.bottom)
}
} else {
scale = getScale(drawable)
val width: Int = drawable.intrinsicWidth
val height: Int = drawable.intrinsicHeight
println("(drawable.intrinsicWidth * scale).toInt() ${(drawable.intrinsicWidth * scale).toInt()}")
println("(drawable.intrinsicHeight * scale).toInt() ${(drawable.intrinsicHeight * scale).toInt()}")
println("(drawable.intrinsicHeight)${(drawable.intrinsicHeight)}")
println("(drawable.intrinsicWidth)${(drawable.intrinsicWidth)}")
drawable.setBounds(0, 0, (drawable.intrinsicWidth * scale).toInt(),
(drawable.intrinsicHeight * scale).toInt())
//                drawable.setBounds(0, 0, width, height)
// set the correct bound according to the result from HTTP call
urlDrawable.setBounds(0, 0, (drawable.intrinsicWidth * scale).toInt(),
(drawable.intrinsicHeight * scale).toInt())
//                urlDrawable.setBounds(0, 0, width, height)
}
// change the reference of the current drawable to the result from the HTTP call
urlDrawable.drawable = drawable
val imageGetter = imageGetterReference.get() ?: return
// redraw the image by invalidating the container
imageGetter.container.invalidate()
// re-set text to fix images overlapping text
imageGetter.container.text = imageGetter.container.text
println(
"/*-------------------------------------------------------------------------------------------*/")
}
}
inner class UrlDrawable : BitmapDrawable() {
var drawable: Drawable? = null
override fun draw(canvas: Canvas) {
// override the draw to facilitate refresh function later
try {
if (drawable != null) {
drawable!!.draw(canvas)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}

图像标签代码

private static void startImg(Editable text, Attributes attributes, Html.ImageGetter img) {
String src = attributes.getValue("", "src");
if (src == null) {
return;
}
Drawable d = null;
ImageSpan imageSpan = null;
if (img != null) {
Log.e("HTML", "startImg");
d = img.getDrawable(src);
imageSpan = new AreImageSpan(sContext, d, src);
}
if (d == null) {
if (sContext == null) {
d = Resources.getSystem().getDrawable(R.drawable.ic_image);
} else {
d = sContext.getResources().getDrawable(R.drawable.ic_image);
}
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
}
Log.e("HTML", imageSpan.getSource());
int len = text.length();
text.append('uFFFC');
text.setSpan(imageSpan, len, text.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

更新

刚刚发现

d = img.getDrawable(src);

此行返回的图像在第一次打开时具有边界Rect(0,0-0,0(。

UrlDrawable的边界应该与其包含的可绘制对象的边界匹配。我建议用以下方法来实现这一点:

inner class UrlDrawable : BitmapDrawable() {
var drawable: Drawable? = null
set(value) {
field = value?.also {
// Set bounds of the enclosed drawable to its intrinsic size.
it.bounds = Rect(0, 0, it.intrinsicWidth, it.intrinsicHeight)
}
// The wrapper should have the same bounds as the drawable.
bounds = field?.bounds ?: Rect()
}
override fun draw(canvas: Canvas) {
try {
drawable?.draw(canvas)
} catch (e: Exception) {
e.printStackTrace()
}
}
}

现在,当您绘制图像时,它应该具有正确的大小。