跳转至

如何在安卓系统中在文本视图中显示 HTML 和图像?

原文:https://www . geesforgeks . org/how-display-html-in-textview-with-images-in-Android/

有些情况下,人们需要在应用程序中显示丰富的格式化文本,比如博客应用程序或像 Quora 这样的应用程序,但是安卓的内置功能默认不允许显示内嵌图像,此外,它们在 blockquote 标签中的任何内容的左侧显示难看的蓝线。以下是在文本视图中显示 HTML 以及在安卓中显示图像的简单解决方案。请注意,我们将在安卓系统中使用 Kotlin 语言来实现这个项目。下面是该应用的演示截图。

demo

先决条件

方法

步骤 1:创建新项目

在安卓工作室创建新项目请参考 如何在安卓工作室创建/启动新项目注意选择 Kotlin 作为编程语言。

步骤 2:编码前的项目设置

  • colors.xml 文件中添加一些颜色。此处的颜色用于区块引用样式。你可以自由选择不同的颜色。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#0F9D58</color>
    <color name="colorPrimaryDark">#0F9D58</color>
    <color name="colorAccent">#03DAC5</color>
    <color name="Grey">#878585</color>
</resources>

// Picasso library to downloading images 
implementation 'com.squareup.picasso:picasso:2.71828'
// Coroutines dependency to put the downloading 
process in background thread implementation 
'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'

第三步:使用活动文件

在下面的 activity_main.xml 文件中,我们添加了以下小部件:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <!-- Edittext to take input for this sample app,
          for real app you will not need this -->
    <EditText
        android:id="@+id/editor"
        android:layout_width="0dp"
        android:layout_height="40dp"
        app:layout_constraintEnd_toStartOf="@+id/display_html"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <!-- Button to trigger an event to display html/Rich text-->
    <Button
        android:id="@+id/display_html"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:text="Display Html"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <!-- Scroll View for smooth scrolling -->
    <ScrollView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginTop="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editor">

        <!-- Text View in which you will display the html after 
             processing the input-->
        <TextView
            android:id="@+id/html_viewer"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </TextView>

    </ScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>

输出 UI:

第四步:创建一个 Kotlin 类 ImageGetter.kt

创建一个类,该类将下载包含在【img】标签中的图像。下面是完整的 ImageGetter.kt 文件。通过参考代码中相应的注释来理解完整的代码。

*ImageGetter.kt*

import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.text.Html
import android.widget.TextView
import com.squareup.picasso.Picasso
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

// Class to download Images which extends [Html.ImageGetter]
class ImageGetter(
    private val res: Resources,
    private val htmlTextView: TextView
) : Html.ImageGetter {

    // Function needs to overridden when extending [Html.ImageGetter] ,
    // which will download the image
    override fun getDrawable(url: String): Drawable {
        val holder = BitmapDrawablePlaceHolder(res, null)

        // Coroutine Scope to download image in Background
        GlobalScope.launch(Dispatchers.IO) {
            runCatching {

                // downloading image in bitmap format using [Picasso] Library
                val bitmap = Picasso.get().load(url).get()
                val drawable = BitmapDrawable(res, bitmap)

                // To make sure Images don't go out of screen , Setting width less
                // than screen width, You can change image size if you want
                val width = getScreenWidth() - 150

                // Images may stretch out if you will only resize width,
                // hence resize height to according to aspect ratio
                val aspectRatio: Float =
                    (drawable.intrinsicWidth.toFloat()) / (drawable.intrinsicHeight.toFloat())
                val height = width / aspectRatio
                drawable.setBounds(10, 20, width, height.toInt())
                holder.setDrawable(drawable)
                holder.setBounds(10, 20, width, height.toInt())
                withContext(Dispatchers.Main) {
                    htmlTextView.text = htmlTextView.text
                }
            }
        }
        return holder
    }

    // Actually Putting images
    internal class BitmapDrawablePlaceHolder(res: Resources, bitmap: Bitmap?) :
        BitmapDrawable(res, bitmap) {
        private var drawable: Drawable? = null

        override fun draw(canvas: Canvas) {
            drawable?.run { draw(canvas) }
        }

        fun setDrawable(drawable: Drawable) {
            this.drawable = drawable
        }
    }

    // Function to get screenWidth used above
    fun getScreenWidth() =
        Resources.getSystem().displayMetrics.widthPixels
}


回到顶部