XML'de html biçimli dize kaynağından TextView metni ayarlayın


198

İçimde bazı sabit dizeler var strings.xml, şöyle bir şey:

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

ve TextViewdüzenimde html biçimli dizeyle doldurmak istediğim bir tane var .

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

eğer bunu yaparsam, içeriği formattedtextyalnızca somestringherhangi bir html etiketinin içeriğidir ve dolayısıyla biçimlendirilmez.

Biçimlendirilmiş metni programlı olarak ayarlamanın mümkün olduğunu biliyorum.

.setText(Html.fromHtml(somestring));

çünkü bunu programımın beklendiği gibi çalıştığı diğer bölümlerinde kullanıyorum.

Bu işlevi çağırmak için bir ihtiyacım var Activity, ancak şu anda düzenim düz XML'de az çok statik bir görünüm ve ben bunu böyle bırakmayı tercih ederim, beni Activitysadece biraz ayarlamak için oluşturma yükünden kurtarmak için Metin.

Açık bir şeyi gözden kaçırıyor muyum? Hiç mümkün değil mi? Herhangi bir yardım veya geçici çözüm hoş geldiniz!

Düzenleme: Bazı şeyleri denedim ve xml'deki HTML biçimlendirmesinin bazı kısıtlamaları olduğu görülüyor:

  • etiketler küçük harfle yazılmalıdır

  • burada bahsedilen bazı etiketler çalışmaz, örneğin <br/>(bunun \nyerine kullanmak mümkündür )


1
Uzun zamandır biliyorum, ancak bir TextView için html kullanarak yeni bir satır için <br> kullanabildim ve \ n kullanamadım.
Tam

2
Bu sadece xml ile çalışabilir mi? Cevabımda küçük bir ödülüm var. Hayır, bu noktada zaten etrafına kodladığım gerçek cevapları kabul ediyorum.
danny117

2
Kimsenin soruyu gerçekten cevaplamamasını ilginç buluyorum. OP, bunu fromHtml () ile nasıl yapacağını bildiğini, ancak bunu doğrudan mizanpaj dosyasında yapmak istediğini belirtir (bununla birlikte, nedenler iyi değildir ... üzerinde çizim yapıyorsanız her zaman bir etkinlik / bağlam vardır ekran). Yanıtların hiçbiri de bağlantı etiketlerinin etkilerine dalmaz.
lilbyrdie

Yanıtlar:


481

Herhangi birinin bunu bulması durumunda, belgelenmemiş daha güzel bir alternatif var (saatlerce aradıktan sonra ona takıldım ve sonunda Android SDK'nın hata listesinde buldum). Sen CAN zamandır sarın olduğunca strings.xml ham HTML içerir

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

Misal:

<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>

Ardından, kodunuzda:

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

IMHO, bu, çalışmak için birkaç kat daha güzeldir :-)


26
Eklemek için, CDATA bloğu içinde ters eğik çizgi kaçış kesme işaretlerinden / tek tırnak işaretlerinden de yararlanabilirsiniz, böylece sonsuz çirkin <b> can & apos; t < / b>
Bitbang3r

5
Bu hala çalışıyor mu? Sadece denedim ve kelimenin tam anlamıyla <p> ve </p> gösteriyor.
Peri Hartman

1
@PeriHartman Sen de Html.fromHtml(getString(R.string.nice_html))biraz yaptın mı ? :)
async

1
TextView nerede foo = (TextView) findViewById (R.id.foo); foo.setText (Html.fromHtml (getString (R.string.nice_html))); gitmem gerek?
RustyIngles

2
"Html.fromHtml" yi önlemenin bir yolu var mı?
android geliştiricisi

130

Buradaki en iyi cevap yanlış (veya en azından çok karmaşık) bir şey önermek olduğu için, soru oldukça eski olmasına rağmen bunun güncellenmesi gerektiğini düşünüyorum:

Android'de String kaynaklarını kullanırken, sadece getString(...)Java kodundan çağırmanız veya android:text="@string/..."mizanpaj XML'nizde kullanmanız gerekir.

Dizelerinizde HTML işaretlemesi kullanmak isteseniz bile, çok fazla değişiklik yapmanız gerekmez:

String kaynaklarınızda kaçmanız gereken karakterler şunlardır:

  • çift ​​tırnak işareti: "olur\"
  • tek tırnak işareti: 'olur\'
  • ve işareti: &olur &#38;veya&amp;

Bu, HTML işaretlemenizi etiketlerden kaçmadan ekleyebileceğiniz anlamına gelir :

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

Ancak emin olmak için, yalnızca kullanmalısınız <b>, <i>ve <u>onlar belgelerinde listelenmiştir.

HTML dizelerinizi XML'den kullanmak istiyorsanız, kullanmaya devam edin, android:text="@string/..."iyi çalışacaktır.

Tek fark, HTML dizelerinizi Java kodundan kullanmak istiyorsanız getText(...), getString(...)şimdi yerine kullanmak zorunda olmanızdır , çünkü ilki stili korur ve ikincisi onu çıkarır.

Bu kadar kolay. CDATA yok, hayır Html.fromHtml(...).

Sadece gerekir Html.fromHtml(...)eğer yaptığımız HTML biçimlendirme içinde kodlamak özel karakterler. O zaman birlikte kullanın getString(...). Dize'yi geçirmek istiyorsanız bu gerekli olabilir String.format(...).

Bunların hepsi belgelerde de anlatılmıştır .

Düzenle:

Çıkış getText(...)karaktersiz HTML (önerdiğim gibi) ile ve CDATAbölümleri arasında hiçbir fark yoktur Html.fromHtml(...).

Karşılaştırma için aşağıdaki grafiğe bakın:

görüntü açıklamasını buraya girin


Benimki onu soyuyor. Şu kodu kullanıyorum:getResources().getText(R.string.codename)
Si8

3
Daha iyi yardımcı olmak için Java / XML alıntılarını görmem gerekiyor. Yazdığım Ama: Kullanmakta ediyorsanız yalnızca eminiz <b>, <i>, <u>. Diğer etiketler her zaman desteklenmez.
2013

1
Cevabınız işe yarıyor ve basit. Dizenizi strings.xml'ye istenen html etiketleriyle birlikte koyun ve düzen xml dosyanızdan referans alın. <sup> etiketini kullandım.
Peri Hartman

1
Sizinki başka bir çözüm, diğerine alternatif değil çünkü diğerleri gibi tüm etiketleri desteklemiyor. Diğeri çok basitken bu çözümde herhangi bir avantaj göremiyorum.
mobilepotato7

1
"CDATA" kullanımında bir sorun yaşadığım gibi bir sorunla karşılaştım, örneğin: <! [CDATA [... HTML ...]]> 22 harf ve html kısmı 10'a sahip, bu yüzden HTML.fromhtml kullanıyorsanız ( getstring (...)) metniniz doğru bir şekilde gösterilecek, ancak metnin içeriği 22 harflik boşluklara ihtiyaç duyacaktır. Liste görünümünde kullandım ve yabani alanlar gördüm. bu yüzden gettext () DAHA İYİ.
David

16

HTML etiketlerinizden çıkın ...

<resources>
    <string name="somestring">
        &lt;B&gt;Title&lt;/B&gt;&lt;BR/&gt;
        Content
    </string>
</resources>

Dokümanlar şöyle diyor: developer.android.com/intl/zh-TW/guide/topics/resources/… ama bu TextViewHTML'yi göstermesi için yeterli mi?
Macarse

3
Bunu test ettim ve java kaynak kodundan kullanırsanız, sorun değil. Ancak metninizi doğrudan düzen XML'den ilişkilendirirseniz, etiketler metin görünümünde gösterilir (örneğin <B> Başlık </B> ...)
ZoltanF

Metni bir görünümde göstermek için , özellikle [ developer.android.com/reference/android/text/Html.html] sınıfını kullanın fromHTML().
ekawas

@ZoltanF doğru, HTML içeren bir düzenden android: text = "" kullanılması dizedeki etiketleri gösterecektir.
Andrew Mackenzie

1
XML doğrudan HTML dizesini kullanmak isterseniz şunları yapabilirsiniz değil dizede kodlamak HTML özel karakter. Koddan dize kullanmak istiyorsanız Ancak, üzeri Html.fromHTML()sen zorunda özel karakterleri kodlamak. Garip!
2013

12

Android, kaynak dizesinin türünü (ör. Metin / düz veya metin / html) belirtmek için bir spesifikasyona sahip değildir. Bununla birlikte, geliştiricinin bunu XML dosyasında belirtmesine izin verecek bir geçici çözüm var.

  1. Android: text özniteliğinin html olduğunu belirtmek için özel bir öznitelik tanımlayın.
  2. Alt sınıflandırılmış bir TextView kullanın.

Bunları tanımladıktan sonra, setText (Html.fromHtml (...)) 'yi tekrar çağırmanıza gerek kalmadan xml dosyalarında kendinizi HTML ile ifade edebilirsiniz. Bu yaklaşımın API'nin bir parçası olmamasına oldukça şaşırdım.

Bu çözüm, Android stüdyo simülatörünün metni işlenmiş HTML olarak göstereceği derecede çalışır.

görüntü açıklamasını buraya girin

res / values ​​/ strings.xml (HTML olarak dize kaynağı)

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

layout.xml (yalnızca ilgili parçalar)

Özel öznitelik ad alanını bildirin ve android_ex: isHtml özelliğini ekleyin. Ayrıca TextView alt sınıfını kullanın.

<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 (alt sınıf için özel öznitelikleri tanımlayın)

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

TextViewEx.java (TextView alt sınıfı)

 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();
    }
}
}

Uygulama, her yerde HTML.fromHtml'yi çağırmak yerine birden çok yerde HTML biçimli dizeler kullanırsa bu yaklaşım daha iyi olacaktır. Uygulamanın kendisi, biri normal diğeri HTML için olmak üzere iki görünüme sahip olacaktır.
Manju

mükemmel !! .. kod için teşekkürler.
Hussnain Hashmi

10

Son Güncelleme:

Html.fromHtml(string);// Android N sürümlerinden sonra kullanımdan kaldırıldı ..

Aşağıdaki kod, android N ve üzeri sürümleri desteklemektedir ...

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));
}

3
  String termsOfCondition="<font color=#cc0029>Terms of Use </font>";
  String commma="<font color=#000000>, </font>";
  String privacyPolicy="<font color=#cc0029>Privacy Policy </font>";
  Spanned text=Html.fromHtml("I am of legal age and I have read, understood, agreed and accepted the "+termsOfCondition+commma+privacyPolicy);
        secondCheckBox.setText(text);

2

Bir sunucudan HTML dizesini aldığım için CDATA'yı xml'ye koyma şansım olmadığında başka bir durumum var.

İşte bir sunucudan aldığım şey:

<p>The quick brown&nbsp;<br />
fox jumps&nbsp;<br />
 over the lazy dog<br />
</p>

Daha karmaşık görünüyor ama çözüm çok daha basit.

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());

}

Umarım yardımcı olur!
Linh


4
getHTMLContentFromAServer () işlevinin uygulaması nerede
Pallavi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.