Ustaw TextView tekst z zasobu tekstowego sformatowanego w html w XML

Mam kilka stałych ciągów w moim strings.xml, coś w stylu:

<resources>
    <string name="somestring">
        <B>Title</B><BR/>
        Content
    </string>
</resources>

A w moim layoucie mam TextView, który chciałbym wypełnić ciągiem html sformatowanym.

<TextView android:id="@+id/formattedtext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/htmlstring"/>

Jeśli to zrobię, zawartość formattedtext jest tylko zawartością somestring pozbawioną jakichkolwiek znaczników html, a tym samym nieformatowaną.

Wiem, że można programowo ustawić sformatowany tekst za pomocą

.setText(Html.fromHtml(somestring));

Ponieważ używam tego w innych częściach mojego programu, gdzie jest działa zgodnie z oczekiwaniami.

Aby wywołać tę funkcję, potrzebuję Activity, ale w tej chwili mój układ jest tylko prostym, mniej lub bardziej statycznym widokiem w zwykłym XML i wolałbym zostawić go w ten sposób, aby uchronić mnie od napowietrznego tworzenia Activity tylko po to, aby ustawić jakiś tekst.

Czy przeoczyłem coś oczywistego? Czy to w ogóle możliwe? Każda pomoc lub obejścia mile widziane!

Edit: po prostu próbowałem kilku rzeczy i wydaje się, że formatowanie HTML w xml ma pewne ograniczenia:

  • Tagi muszą być pisane małymi literami

  • Niektóre tagi, które są wymienione tutaj nie działają, np. <br/> (można zamiast tego użyć \n)

Author: Community, 2010-07-13

6 answers

Na wypadek, gdyby ktoś to znalazł, istnieje ładniejsza alternatywa, która nie jest udokumentowana (potknąłem się o nią po kilku godzinach szukania i w końcu znalazłem ją na liście błędów dla samego Android SDK). Ty CAN Dołącz surowy HTML w ciągach.xml, tak długo, jak zawijasz go w

<![CDATA[ ...raw html... ]]>

Przykład:

<string name="nice_html">
<![CDATA[
<p>This is a html-formatted string with <b>bold</b> and <i>italic</i> text</p>
<p>This is another paragraph of the same string.</p>
]]>
</string>

Następnie w kodzie:

TextView foo = (TextView)findViewById(R.id.foo);
foo.setText(Html.fromHtml(getString(R.string.nice_html)));

IMHO, to jest kilka rzędów wielkości ładniejsze do pracy: -)

 451
Author: Bitbang3r,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-28 03:52:44

Ponieważ najlepsza odpowiedź tutaj sugeruje coś złego (lub przynajmniej zbyt skomplikowane), uważam, że powinno to zostać zaktualizowane, chociaż pytanie jest dość stare: {]}

Podczas korzystania z zasobów String w Androidzie, wystarczy wywołać {[1] } z kodu Javy lub użyć android:text="@string/..." w układzie XML.

Nawet jeśli chcesz używać znaczników HTML w swoich ciągach, nie musisz wiele zmieniać:

Jedyne znaki, które musisz uciec w swoich Zasobach ciągów są:

  • podwójny cudzysłów: " staje się \"
  • pojedynczy cudzysłów: ' staje się \'
  • ampersand: & staje się &#38; lub &amp;

Oznacza to, że możesz dodać swoje znaczniki HTML bez uciekania znaczników:

<string name="my_string"><b>Hello World!</b> This is an example.</string>

Jednak, aby mieć pewność, należy używać tylko<b>, <i> i <u> zgodnie z ich wykazem w dokumentacji.

Jeśli chcesz używać ciągów HTML z XML , po prostu używaj android:text="@string/...", to będzie działać dobrze.

Jedyną różnicą jest to, że jeśli chcesz używać łańcuchów HTML z kodu Javy , musisz użyć getText(...) zamiast getString(...) teraz, ponieważ pierwszy zachowuje styl, a drugi po prostu go usunie.

To takie proste. Brak CDATA, brak Html.fromHtml(...).

Będziesz potrzebował Html.fromHtml(...) tylko wtedy, gdy zakodujesz znaki specjalne w znacznikach HTML. Następnie użyj go z getString(...). Może to być konieczne, jeśli chcesz przekazać ciąg znaków do String.format(...).

To wszystko jest opisane W dokumentach.

Edit:

Nie ma różnicy między getText(...) z nieoznaczonym HTML (jak zaproponowałem) lub CDATA sekcjami i Html.fromHtml(...).

Zobacz poniższą grafikę dla porównania:

Tutaj wpisz opis obrazka

 113
Author: caw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-01 10:48:26

Unikaj znaczników HTML ...

<resources>
    <string name="somestring">
        &lt;B&gt;Title&lt;/B&gt;&lt;BR/&gt;
        Content
    </string>
</resources>
 15
Author: ekawas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-13 13:07:08

Android nie ma specyfikacji wskazującej Typ łańcucha zasobów (np. text/plain lub text / html). Istnieje jednak obejście, które pozwoli programiście określić to w pliku XML.

  1. Zdefiniuj Niestandardowy atrybut, aby określić, że atrybutem android: text jest html.
  2. Użyj podklasowanego widoku tekstu.

Gdy je zdefiniujesz, możesz wyrazić siebie za pomocą HTML w plikach xml bez konieczności wywoływania setText (Html.fromHtml(...)) jeszcze raz. Jestem raczej zaskoczony, że takie podejście nie jest częścią API.

To rozwiązanie działa do tego stopnia, że symulator Android studio wyświetli tekst jako renderowany HTML.

Tutaj wpisz opis obrazka

Res / wartości / ciągi.xml (string resource as HTML)

<resources>
<string name="app_name">TextViewEx</string>
<string name="string_with_html"><![CDATA[
       <em>Hello</em> <strong>World</strong>!
 ]]></string>
</resources>

Układ.xml (tylko odpowiednie części)

Zadeklaruj niestandardową przestrzeń nazw atrybutów i Dodaj atrybut android_ex: isHtml. Użyj również podklasy TextView.

<RelativeLayout
...
xmlns:android_ex="http://schemas.android.com/apk/res-auto"
...>

<tv.twelvetone.samples.textviewex.TextViewEx
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/string_with_html"
    android_ex:isHtml="true"
    />
 </RelativeLayout>

Res / values / attrs.xml (definiowanie własnych atrybutów dla podklasy)

 <resources>
<declare-styleable name="TextViewEx">
    <attr name="isHtml" format="boolean"/>
    <attr name="android:text" />
</declare-styleable>
</resources>

Tekstviewex.java (podklasa TextView)

 package tv.twelvetone.samples.textviewex;

 import android.content.Context;
 import android.content.res.TypedArray;
 import android.support.annotation.Nullable;
 import android.text.Html;
 import android.util.AttributeSet;
 import android.widget.TextView;

public TextViewEx(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextViewEx, 0, 0);
    try {
        boolean isHtml = a.getBoolean(R.styleable.TextViewEx_isHtml, false);
        if (isHtml) {
            String text = a.getString(R.styleable.TextViewEx_android_text);
            if (text != null) {
                setText(Html.fromHtml(text));
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        a.recycle();
    }
}
}
 7
Author: Steven Spungin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-22 04:16:14

Ostatnia aktualizacja:

Html.fromHtml (string); / / deprecated after Android N versions..

Poniższy kod daje wsparcie dla wersji android N i nowszych...

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
textView.setText(Html.fromHtml(yourHtmlString,Html.FROM_HTML_MODE_LEGACY));
}

else 
{
textView.setText(Html.fromHtml(yourHtmlString));
}
 7
Author: Ranjith Kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-22 14:51:10

Mam inny przypadek, kiedy nie mam szansy umieścić CDATA w xml, ponieważ otrzymuję łańcuch HTML z serwera.

Oto co dostaję z serwera:

<p>The quick brown&nbsp;<br />
fox jumps&nbsp;<br />
 over the lazy dog<br />
</p>
Wydaje się to bardziej skomplikowane, ale rozwiązanie jest o wiele prostsze.
private TextView textView;

protected void onCreate(Bundle savedInstanceState) { 
.....
textView = (TextView) findViewById(R.id.text); //need to define in your layout
String htmlFromServer = getHTMLContentFromAServer(); 
textView.setText(Html.fromHtml(htmlFromServer).toString());

}
Mam nadzieję, że to pomoże!
Linh
 2
Author: Linh Lino,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-24 02:50:54