本文介绍了Android 文本注释 java.lang.ClassCastException:java.lang.String 无法转换为 android.text.SpannedString的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我制作了一个自定义材质 textview 类,它使用注释来设置给定文本的样式.但我最终遇到了这个错误java.lang.ClassCastException: java.lang.String 无法转换为 android.text.SpannedString导致我的安卓应用崩溃.

I have made a custom material textview class which uses annotations to style the given text. But i have ended up with this errorjava.lang.ClassCastException: java.lang.String cannot be cast to android.text.SpannedStringcausing my android app to crash.

我从 Firebase Firestore 获取文本,并直接将下面的类实现到我的布局中.我正在从我的视图中调用 .setText 并且只在那里使用 .setText("Text from Firebase").

I get the texts from Firebase Firestore and i have implemented the class below into my layouts directly. I am calling .setText from my viewholder and only using .setText("Text from Firebase") there.

import android.graphics.Color
import android.text.Annotation
import android.text.SpannableString
import android.text.Spanned
import android.text.SpannedString
import android.text.style.*
import android.util.AttributeSet
import android.util.Log
import android.view.View
import com.google.android.material.textview.MaterialTextView


class SpannedAnnotationMaterialTextView : MaterialTextView {

    private var mListener: OnItemClickListener? = null

    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    override fun setText(text: CharSequence, type: BufferType) {

        super.setText(processingText(text), type)
    }

    /**
     * Beispieltext Deutsch
     * nach Anamnese, Schmerzzustand und Untersuchungsbefunden\n \n Hochrisiko-Anamnese:\n <annotation format="bulletspan">bekanntes Marfan-Syndrom oder andere Bindegewebserkrankung</annotation>\n <annotation format="bulletspan">positive Familienanamnese für Aortenerkrankungen</annotation>\n <annotation format="bulletspan">bekannte Aortenklappenerkrankung</annotation>\n <annotation format="bulletspan">bekanntes thorakales Aortenaneurysma</annotation>\n <annotation format="bulletspan">vorausgegangene(r) Manipulation Aorta <per> Herzkatheter <per> herzchirurg. Eingriff</annotation>\n \n Hochrisiko-Schmerzsymptomatik:\n <annotation format="bulletspan">Schmerzen im Brust- <per> Rücken <per> Bauchbereich (und<per>oder)</annotation>\n <annotation format="bulletspan">abrupter Beginn</annotation>\n <annotation format="bulletspan">hohe Schmerzintensität</annotation>\n <annotation format="bulletspan">reißender Schmerzcharakter</annotation>\n \n Hochrisiko-Untersuchungsbefund:\n <annotation format="bulletspan">Pulsdefizit <per> Pulsdifferenz (evtl. Blutdruckdifferenz > 20mmHg (Arme), evtl. einseitig fehlender Radialispuls oder fehlende Pulse Leiste und Beine peripher Blutdruckdifferenz (syst. Messwert, höherer Wert zählt als realer syst. Blutdruck)</annotation>\n <annotation format="bulletspan">neurologische Symptomatik in Zusammenhang mit Schmerzauftreten</annotation>\n <annotation format="bulletspan">diastolisches Geräusch bei Auskultation über Erb'schem Punkt (neu und in Zusammenhang mit dem Schmerz)</annotation>\n <annotation bulletspan>Hypotension <per> Schocksymptomatik</annotation>\n
     *
     * Exampletext English
     * according to anamnesis, pain condition and examination results \ n \ n high-risk anamnesis: \ n <annotation format = "bulletspan"> known Marfan syndrome or other connective tissue disease </annotation> \ n <annotation format = "bulletspan"> positive family history for aortic diseases < / annotation> \ n <annotation format = "bulletspan"> known aortic valve disease </annotation> \ n <annotation format = "bulletspan"> known thoracic aortic aneurysm </annotation> \ n <annotation format = "bulletspan"> previous Manipulation aorta <per> cardiac catheter <per> cardiac surgeon. Intervention </annotation> \ n \ n High-risk pain symptoms: \ n <annotation format = "bulletspan"> Pain in the chest <per> back <per> abdominal area (and <per> or) </annotation> \ n <annotation format = "bulletspan"> abrupt beginning </annotation> \ n <annotation format = "bulletspan"> high pain intensity </annotation> \ n <annotation format = "bulletspan"> tearing pain character </annotation> \ n \ n high risk Examination results: \ n <annotation format = "bulletspan"> Pulse deficit <per> Pulse difference (possibly blood pressure difference> 20mmHg (arms), possibly one-sided missing radial pulse or missing pulses Groin and legs peripheral blood pressure difference (system measured value, higher value counts as real syst. blood pressure) </annotation> \ n <annotation format = "bulletspan"> neurological symptoms in connection with the occurrence of pain </annotation> \ n <annotation format = "bulletspan"> diastolic noise during auscultation over Erb's point (new and in connection with the pain) </annotation> \ n <annotation bulletspan> Hypotensi on <per> Shock symptoms </annotation> \ n
     */

    private fun processingText(text: CharSequence): CharSequence {

        Log.e(TAG, "processing Text")

        // get the text as spannableString so we can get the spans attached to the text
        val fullText = text as SpannedString
        val spannableString = SpannableString(fullText)

        // get all the annotation spans from the text
        // make sure you import android.text.Annotation
        val annotations = fullText.getSpans(0, fullText.length, Annotation::class.java)


        Log.e(TAG, "annotations found, size = ${annotations.size}")

        // iterate through all the annotation spans
        for (annotation in annotations) {

            // look for the span with the key font
            when (annotation.key) {
                "link" -> {
                    spannableString.apply {
                        // set the span the same indices as the annotation
                        setSpan(
                            object : ClickableSpan() {
                                override fun onClick(widget: View) {
                                    mListener!!.onSpanClick(annotation.value)
                                }
                            },
                            fullText.getSpanStart(annotation),
                            fullText.getSpanEnd(annotation),
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                        )
                    }
                }
                "format" -> {
                    when (annotation.value) {
                        "bulletspan" -> {
                            spannableString.apply {
                                setSpan(
                                    BulletSpan(),
                                    fullText.getSpanStart(annotation),
                                    fullText.getSpanEnd(annotation),
                                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                                )
                            }
                        }
                        "bold" -> {
                            spannableString.apply {
                                setSpan(
                                    BulletSpan(12),
                                    fullText.getSpanStart(annotation),
                                    fullText.getSpanEnd(annotation),
                                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                                )
                            }
                        }
                        "underline" -> {
                            // first underline then resize with x1.15

                            spannableString.apply {
                                setSpan(
                                    UnderlineSpan(),
                                    fullText.getSpanStart(annotation),
                                    fullText.getSpanEnd(annotation),
                                    Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                                )
                                setSpan(
                                        RelativeSizeSpan(1.15f),
                                fullText.getSpanStart(annotation),
                                fullText.getSpanEnd(annotation),
                                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                                )
                            }
                        }
                    }
                }
                "color" -> {
                    spannableString.apply {
                        setSpan(
                            ForegroundColorSpan(Color.parseColor(annotation.value)),
                            fullText.getSpanStart(annotation),
                            fullText.getSpanEnd(annotation),
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
                        )
                    }
                }
            }
        }
        return spannableString
    }

    /**
     * Method to bind the OnItemClickListener.
     *
     * @param listener see down below
     */
    fun setOnItemClickListener(listener: OnItemClickListener?) {
        mListener = listener
    }

    interface OnItemClickListener {
        fun onSpanClick(spanText: String?)
    }

    companion object {
        const val TAG = "SpannedAnnotationMaterialTextView"
    }
}

当我从 val fullText = text as SpannedString 更改为 val fullText = SpannedString(text) 时,它不会崩溃但永远找不到任何注释.

And when i change from val fullText = text as SpannedString to val fullText = SpannedString(text) it wont crash but never finds any annotation.

推荐答案

你的错误字面上告诉你,编译器不能自动将 String 转换为 SpannedString.您应该通过调用 SpannedString 构造函数来实现.所以你有点回答了你自己的问题:)

Your error literally tells you, that compiler cannot cast String to SpannedString automatically.You should do it by calling SpannedString constructor.So you kinda answered your own question :)

这篇关于Android 文本注释 java.lang.ClassCastException:java.lang.String 无法转换为 android.text.SpannedString的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-08 21:22