Html.fromHtml in Android N veraltet

300

Ich verwende Html.fromHtml, um HTML in einem anzuzeigen TextView.

Spanned result = Html.fromHtml(mNews.getTitle());
...
...
mNewsTitle.setText(result);

Ist Html.fromHtmlaber jetzt in Android N + veraltet

Was / Wie finde ich den neuen Weg dazu?

Aldasa
quelle

Antworten:

616

Update : Wie @Andy unten erwähnt, hat Google erstellt HtmlCompat, das anstelle der unten beschriebenen Methode verwendet werden kann. Fügen Sie diese Abhängigkeit implementation 'androidx.core:core:1.0.1 der Datei build.gradle Ihrer App hinzu. Stellen Sie sicher, dass Sie die neueste Version von verwenden androidx.core:core.

Dies ermöglicht Ihnen Folgendes:

HtmlCompat.fromHtml(html, HtmlCompat.FROM_HTML_MODE_LEGACY);

Weitere Informationen zu den verschiedenen Flags finden Sie in der HtmlCompat-Dokumentation

ursprüngliche Antwort: In Android N wurde eine neue Html.fromHtmlMethode eingeführt. Html.fromHtmlJetzt ist ein zusätzlicher Parameter mit dem Namen flags erforderlich. Dieses Flag gibt Ihnen mehr Kontrolle darüber, wie Ihr HTML angezeigt wird.

Unter Android N und höher sollten Sie diese neue Methode verwenden. Die ältere Methode ist veraltet und wird möglicherweise in zukünftigen Android-Versionen entfernt.

Sie können Ihre eigene Util-Methode erstellen, die die alte Methode bei älteren Versionen und die neuere Methode bei Android N und höher verwendet. Wenn Sie keine Versionsprüfung hinzufügen, wird Ihre App bei niedrigeren Android-Versionen beschädigt. Sie können diese Methode in Ihrer Util-Klasse verwenden.

@SuppressWarnings("deprecation")
public static Spanned fromHtml(String html){
    if(html == null){
        // return an empty spannable if the html is null
        return new SpannableString("");
    }else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        // FROM_HTML_MODE_LEGACY is the behaviour that was used for versions below android N
        // we are using this flag to give a consistent behaviour
        return Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY);
    } else {
        return Html.fromHtml(html);
    }
}

Sie können das HTML.FROM_HTML_MODE_LEGACYin einen zusätzlichen Parameter konvertieren, wenn Sie möchten. Dies gibt Ihnen mehr Kontrolle darüber, welches Flag verwendet werden soll.

Weitere Informationen zu den verschiedenen Flags finden Sie in der Dokumentation zur HTML-Klasse

Rockney
quelle
2
Welches Flag repräsentiert die Null?
Ban-Geoengineering
4
Html.FROM_HTML_MODE_LEGACY
Ban-Geoengineering
14
Ah, warten auf etwas wie HtmlCompat zu erscheinen
Vanomart
12
Es ist auch nützlich, einen //noinspection deprecationKommentar direkt unter hinzuzufügen else, um Flusenwarnungen zu vermeiden.
Ted Hopp
1
Sie können sehen, was jede dieser Flaggen in diesem Blog-Beitrag tut
Yair Kukielka
95

Ich hatte viele dieser Warnungen und verwende immer FROM_HTML_MODE_LEGACY, also habe ich eine Hilfsklasse namens HtmlCompat erstellt, die Folgendes enthält:

   @SuppressWarnings("deprecation")
   public static Spanned fromHtml(String source) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            return Html.fromHtml(source, Html.FROM_HTML_MODE_LEGACY);
        } else {
            return Html.fromHtml(source);
        }
    }
k2col
quelle
2
Gleicher Effekt wie die akzeptierte Antwort, aber +1 aufgrund der Annotation zu SuppressWarnings
Stoycho Andreev
Können Sie eine kleine Erklärung zu diesem Modus geben?
Ranjith Kumar
Könntest du alles bereitstellen, was HtmlCompact auf Git Hub sein kann
?
@shareef Ich würde, aber es ist wirklich nur eine langweilige Utility-Klasse mit dieser einzigen Methode darin ....
k2col
61

Vergleichen Sie die Flags von fromHtml ().

<p style="color: blue;">This is a paragraph with a style</p>

<h4>Heading H4</h4>

<ul>
   <li style="color: yellow;">
      <font color=\'#FF8000\'>li orange element</font>
   </li>
   <li>li #2 element</li>
</ul>

<blockquote>This is a blockquote</blockquote>

Text after blockquote
Text before div

<div>This is a div</div>

Text after div

FROM_HTML FLAGS

Xan
quelle
Können Sie bitte auch Eingabe-HTML teilen? Dies würde zum besseren Verständnis der Konvertierung beitragen.
Kalpesh Patel
Ich sehe, dass die Stilattribute nicht implementiert sind. Gibt es eine Möglichkeit, sie zu implementieren?
Christine
42

Oder Sie können verwenden androidx.core.text.HtmlCompat:

HtmlCompat.fromHtml("<b>HTML</b>", HtmlCompat.FROM_HTML_MODE_LEGACY)

HtmlCompat-Dokumente

Ondřej Z.
quelle
25

Wenn Sie das Glück haben, sich auf Kotlin zu entwickeln, erstellen Sie einfach eine Erweiterungsfunktion:

fun String.toSpanned(): Spanned {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        return Html.fromHtml(this, Html.FROM_HTML_MODE_LEGACY)
    } else {
        @Suppress("DEPRECATION")
        return Html.fromHtml(this)
    }
}

Und dann ist es so süß, es überall zu benutzen:

yourTextView.text = anyString.toSpanned()
Leo Droidcoder
quelle
5
Sie können Eingaben speichern, indem Sie entfernen Spannedundreturn
Minami
14

fromHtml

Diese Methode wurde als veraltet in API - Ebene 24 .

Sie sollten FROM_HTML_MODE_LEGACY verwenden

Trennen Sie Elemente auf Blockebene mit Leerzeilen (zwei Zeilenumbruchzeichen) dazwischen. Dies ist das Legacy-Verhalten vor N.

Code

if (Build.VERSION.SDK_INT >= 24)
        {
            etOBJ.setText(Html.fromHtml("Intellij \n Amiyo",Html.FROM_HTML_MODE_LEGACY));

         }
 else
        {
           etOBJ.setText(Html.fromHtml("Intellij \n Amiyo"));
        }

Für Kotlin

fun setTextHTML(html: String): Spanned
    {
        val result: Spanned = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY)
        } else {
            Html.fromHtml(html)
        }
        return result
    }

Anruf

 txt_OBJ.text  = setTextHTML("IIT Amiyo")
IntelliJ Amiya
quelle
Können Sie eine kleine Erklärung zu diesem Modus geben?
Ranjith Kumar
Wenn Sie möchten, dass das SDK Versionsprüfungen durchführt, verwenden Sie: HtmlCompat.fromHtml("textWithHtmlTags", HtmlCompat.FROM_HTML_MODE_LEGACY)
Wajid Ali,
8

Aus dem offiziellen Dokument:

fromHtml(String)Methode wurde in API Level 24 veraltet. Verwenden Sie fromHtml(String, int) stattdessen.

  1. TO_HTML_PARAGRAPH_LINES_CONSECUTIVEOption für toHtml(Spanned, int): Umschließen aufeinanderfolgender Textzeilen, die durch '\n'innere <p> Elemente begrenzt sind.

  2. TO_HTML_PARAGRAPH_LINES_INDIVIDUALOption für toHtml(Spanned, int): Umschließen Sie jede Textzeile, die durch '\n'ein <p>oder ein <li> Element begrenzt ist.

https://developer.android.com/reference/android/text/Html.html

USKMobilität
quelle
8

Wenn Sie Kotlin verwenden , habe ich dies mit einer Kotlin-Erweiterung erreicht:

fun TextView.htmlText(text: String){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        setText(Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY))
    } else {
        setText(Html.fromHtml(text))
    }
}

Dann nenne es wie:

textView.htmlText(yourHtmlText)
David Jarvis
quelle
5

Um die Antwort von @Rockney und @ k2col zu erweitern, kann der verbesserte Code folgendermaßen aussehen:

@NonNull
public static Spanned fromHtml(@NonNull String html) {
    if (CompatUtils.isApiNonLowerThan(VERSION_CODES.N)) {
        return Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY);
    } else {
        //noinspection deprecation
        return Html.fromHtml(html);
    }
}

Wo die CompatUtils.isApiNonLowerThan:

public static boolean isApiNonLowerThan(int versionCode) {
    return Build.VERSION.SDK_INT >= versionCode;
}

Der Unterschied besteht darin, dass es keine zusätzliche lokale Variable gibt und die Abschreibung nur in der elseVerzweigung erfolgt. Dies unterdrückt also nicht alle Methoden außer einem einzelnen Zweig.

Es kann hilfreich sein, wenn Google in einigen zukünftigen Versionen von Android entscheidet, selbst die fromHtml(String source, int flags)Methode zu verwerfen .

jakubbialkowski
quelle
4

Sie können verwenden

//noinspection deprecation
return Html.fromHtml(source);

Inspektion nur für einzelne Anweisung, aber nicht für die gesamte Methode zu unterdrücken.

Nikolay Tsigouro
quelle
2

Die Framework-Klasse wurde so geändert, dass ein Flag zum Informieren erforderlich ist fromHtml() zur Verarbeitung von Zeilenumbrüchen zu erhalten. Dies wurde in Nougat hinzugefügt und berührt nur die Herausforderung von Inkompatibilitäten dieser Klasse über Android-Versionen hinweg.

Ich habe eine Kompatibilitätsbibliothek veröffentlicht, um die Klasse zu standardisieren und zurück zu portieren und weitere Rückrufe für Elemente und Stil zu enthalten:

https://github.com/Pixplicity/HtmlCompat

Obwohl es der HTML-Klasse des Frameworks ähnelt, waren einige Signaturänderungen erforderlich, um mehr Rückrufe zu ermöglichen. Hier ist das Beispiel von der GitHub-Seite:

Spanned fromHtml = HtmlCompat.fromHtml(context, source, 0);
// You may want to provide an ImageGetter, TagHandler and SpanCallback:
//Spanned fromHtml = HtmlCompat.fromHtml(context, source, 0,
//        imageGetter, tagHandler, spanCallback);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(fromHtml);
Paul Lammertsma
quelle
Wenn ich Ihre Bibliothek in einer App verwende, die verwendet, minSdkVersion 15und targetSdkVersion 23ich einen Build-Fehler für values-v24.xml erhalte : Error:(3) Error retrieving parent for item: No resource found that matches the given name 'android:TextAppearance.Material.Widget.Button.Borderless.Colored'.Ihre Bibliothek zielt offensichtlich auf API-Level 25 ab. Wie kann ich es noch benutzen?
JJD
2

Hier ist meine Lösung.

 if (Build.VERSION.SDK_INT >= 24) {
        holder.notificationTitle.setText(Html.fromHtml(notificationSucces.getMessage(), Html.FROM_HTML_MODE_LEGACY));
    } else {
        holder.notificationTitle.setText(Html.fromHtml(notificationSucces.getMessage()));

    }
pavel
quelle
1

mach einfach eine Funktion:

public Spanned fromHtml(String str){
  return Build.VERSION.SDK_INT >= 24 ? Html.fromHtml(str, Html.FROM_HTML_MODE_LEGACY) : Html.fromHtml(str);
}
ROHIT LIEN
quelle
-2

Versuchen Sie Folgendes, um grundlegende HTML-Tags einschließlich ul ol li-Tags zu unterstützen. Erstellen Sie einen Tag-Handler wie unten gezeigt

import org.xml.sax.XMLReader;

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.Html;
import android.text.Html.TagHandler;
import android.util.Log;

public class MyTagHandler implements TagHandler {
    boolean first= true;
    String parent=null;
    int index=1;
    @Override
    public void handleTag(boolean opening, String tag, Editable output,
                          XMLReader xmlReader) {

        if(tag.equals("ul")) parent="ul";
        else if(tag.equals("ol")) parent="ol";
        if(tag.equals("li")){
            if(parent.equals("ul")){
                if(first){
                    output.append("\n\t•");
                    first= false;
                }else{
                    first = true;
                }
            }
            else{
                if(first){
                    output.append("\n\t"+index+". ");
                    first= false;
                    index++;
                }else{
                    first = true;
                }
            }
        }
    }
}

Stellen Sie den Text auf Aktivität wie unten gezeigt ein

@SuppressWarnings("deprecation")
    public void init(){
        try {
            TextView help = (TextView) findViewById(R.id.help);
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
                help.setText(Html.fromHtml(getString(R.string.help_html),Html.FROM_HTML_MODE_LEGACY, null, new MyTagHandler()));
            } else {
                help.setText(Html.fromHtml(getString(R.string.help_html), null, new MyTagHandler()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

Und HTML-Text auf Ressourcen-String-Dateien als

<! [CDATA [... HTML-Rohdaten ...]]>

Bruce
quelle