I have a news section on my app that loads some piece of news from my website and some of them contains images, so I load them from the internet. But while the image is not loaded, there is a green square that only disappears when the image loads.
Image not loaded:
Then image loaded:
I want to make that green square invisible.
For simplicity, let's pretend I won't even load the images, just want to make the green square invisible without replacing the image tags with an empty text.
Code:
val exampleText = "Example <br> <img src=\"https://www.w3schools.com/images/w3schools_green.jpg\" alt=\"W3Schools.com\"> <br> Example"
tv_body.text = fromHtml(exampleText)
fun fromHtml(html: String?): Spanned? {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY);
} else {
Html.fromHtml(html);
}
}
Is there a way of changing that default image without doing any shenanigans?
My workaround:
What I did to solve this was adapting a custom fromHtml function.
private var drawable: Drawable? = null
fun fromHtml(context: Activity?, tv: TextView?, text: String?) {
if (TextUtils.isEmpty(text) || context == null || tv == null) return
//Replace all image tags with an empty text
val noImageText = text!!.replace("<img.*?>".toRegex(), "")
//Set the textview text with the imageless html
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
tv.text = Html.fromHtml(noImageText, Html.FROM_HTML_MODE_LEGACY)
} else {
tv.text = Html.fromHtml(noImageText)
}
Thread {
//Creating the imageGetter
val imageGetter = ImageGetter { url ->
drawable = getImageFromNetwork(url)
if (drawable != null) {
var w = drawable!!.intrinsicWidth
var h = drawable!!.intrinsicHeight
// Scaling the width and height
if (w < h && h > 0) {
val scale = 400.0f / h
w = (scale * w).toInt()
h = (scale * h).toInt()
} else if (w > h && w > 0) {
val scale = 1000.0f / w
w = (scale * w).toInt()
h = (scale * h).toInt()
}
drawable!!.setBounds(0, 0, w, h)
} else if (drawable == null) {
return@ImageGetter null
}
drawable!!
}
val textWithImage = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY, imageGetter, null)
} else {
Html.fromHtml(text, imageGetter, null)
}
// update runOnUiThread and change the textview text from the textWithoutImage to the textWithImage
context.runOnUiThread(Runnable { tv.text = textWithImage })
}.start()
}
private fun getImageFromNetwork(imageUrl: String): Drawable? {
var myFileUrl: URL? = null
var drawable: Drawable? = null
try {
myFileUrl = URL(imageUrl)
val conn = myFileUrl
.openConnection() as HttpURLConnection
conn.doInput = true
conn.connect()
val `is` = conn.inputStream
drawable = Drawable.createFromStream(`is`, null)
`is`.close()
} catch (e: Exception) {
e.printStackTrace()
return null
}
return drawable
}
So when I call this
val exampleText = "Example <br> <img src=\"https://www.w3schools.com/images/w3schools_green.jpg\" alt=\"W3Schools.com\"> <br> Example"
fromHtml((activity as NewsActivity?), tv_body, exampleText)
It first shows this:
(because I replaced image tags with an empty text)
Then when the image loads it shows this:
I still think making an imageless text is more a workaround than a proper solution, I think there might be something simpler like:
<style name="LIGHT" parent="Theme.AppCompat.DayNight.DarkActionBar">
<item name="android:placeHolderDefaultImage">@drawable/invisible</item>
So the green square would be an invisible drawable and I wouldn't need to set the html text twice, although I really don't know how to change that default place holder image. Guess I'll stick to the workaround
Example" – GLAPPs Mobile Nov 04 '20 at 13:48