Ist es möglich, mehrere Stile in einer Textansicht zu haben?


547

Ist es möglich, mehrere Stile für verschiedene Textteile in einer Textansicht festzulegen?

Zum Beispiel setze ich den Text wie folgt:

tv.setText(line1 + "\n" + line2 + "\n" + word1 + "\t" + word2 + "\t" + word3);

Ist es möglich, für jedes Textelement einen anderen Stil zu haben? ZB Zeile1 fett, Wort1 kursiv usw.

Die allgemeinen Aufgaben und die Vorgehensweise des Entwicklerhandbuchs in Android umfassen das Auswählen, Hervorheben oder Stylen von Textteilen :

// Get our EditText object.
EditText vw = (EditText)findViewById(R.id.text);

// Set the EditText's text.
vw.setText("Italic, highlighted, bold.");

// If this were just a TextView, we could do:
// vw.setText("Italic, highlighted, bold.", TextView.BufferType.SPANNABLE);
// to force it to use Spannable storage so styles can be attached.
// Or we could specify that in the XML.

// Get the EditText's internal text storage
Spannable str = vw.getText();

// Create our span sections, and assign a format to each.
str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new BackgroundColorSpan(0xFFFFFF00), 8, 19, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
str.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 21, str.length() - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

Dabei werden jedoch explizite Positionsnummern im Text verwendet. Gibt es einen saubereren Weg, dies zu tun?


6
Wenn die TextView-Zeichenfolge statisch ist, können Sie der String-Ressourcendatei einfach HTML-Tags <b>, <i> und <u> hinzufügen. Diese werden dann automatisch angewendet. Beispiel: <TextView android: text = "@ string / test" /> wobei @ string / test auf <string> <b> fett </ b>, <i>italic </ i> </ string>
greg7gkb

2
+1 @ greg7gkb! Das Schlüsselwort ist "statisch". Ich zog mir die Haare aus und fragte mich, warum einige meiner Saiten mit <b> funktionierten und andere nicht. Diejenigen, die keine Variablen enthielten.
Scott Biggs

Antworten:


694

Für den Fall, dass sich jemand fragt, wie das geht, gibt es eine Möglichkeit: (Nochmals vielen Dank an Mark!)

mBox = new TextView(context);
mBox.setText(Html.fromHtml("<b>" + title + "</b>" +  "<br />" + 
            "<small>" + description + "</small>" + "<br />" + 
            "<small>" + DateAdded + "</small>"));

Eine inoffizielle Liste der von dieser Methode unterstützten Tags finden Sie unter diesem Link oder in dieser Frage: Welche HTML-Tags werden von Android TextView unterstützt?


1
@ JānisGruzis: Vielleicht ist eine Möglichkeit, dies zu tun, beispielsweise eine Stub-Methode, bei formatTextWhite(string text)der der Text nur in die folgende Formatzeichenfolge eingefügt wird : "<font size="..." color="..." face="...">%s</font>".
Legende

@Legend Ich habe <font fgcolor = '# ffff5400'> <b> <big> "+" Title "+" </ big> </ b> </ font> verwendet, aber die fgcolor / color (beide ausprobiert) ist nicht Arbeiten ... wissen Sie, wie man die Farbe mit HTML macht
Muhammad Babar

@ MuhammadBabar: Kannst du das versuchen : Html.fromHtml("<![CDATA[<font color='#ffff5400'>the html content you already have</font>]]>");? Ich erinnere mich, dass das vor einiger Zeit für mich funktioniert hat. Ich bin mir nicht sicher, ob es noch funktioniert.
Legende

1
@ Legend danke, aber ich habe einen Weg gefunden, Html.fromHtml("<font color=\"#999999\">die Fluchtsequenzen haben für mich funktioniert :) ...
Muhammad Babar

2
warum das nicht funktioniert mBox..setText(Html.fromHtml("<b>" + name + "</b>") + doNotApplyHTML);keine Ahnung danke
Shan Xeeshi

216

Versuchen Sie es Html.fromHtml()und markieren Sie Ihren Text mit fetten und kursiven HTML-Tags, z.

Spanned text = Html.fromHtml("This mixes <b>bold</b> and <i>italic</i> stuff");
textView.setText(text);

1
Das bringt mich zu einer anderen Frage: Ist es besser, eine Textansicht mit HTML-Text oder drei Textansichten mit unterschiedlichen Markups ohne Verwendung der HTML-Klasse einzurichten? Ich gehe davon aus, dass es offensichtlich das erste ist, wollte es aber nur bestätigen ...
Legende

2
Ich habe keine Ahnung, welche vollständige Liste der Tags Html.fromHtml () unterstützt - Sie müssten sich den Quellcode ansehen. Inline-Markup und mehrere TextView-Widgets sollten orthogonale Entscheidungen sein. Verwenden Sie mehrere Widgets, wenn Sie diskrete Textteile präzise platzieren möchten. Verwenden Sie Inline-Markup, wenn Sie Inline-Markup in einem Widget benötigen. Denken Sie daran: In Android gibt es kein FlowLayout. Daher ist es für AFAIK nicht wirklich praktisch, mehrere TextViews zu einem Absatz zusammenzufügen.
CommonsWare

1
Danke dafür ... Eigentlich hat das <small> -Tag funktioniert ... Also werde ich es einfach halten und es einfach benutzen ...
Legende

1
@ TimBoland: Sie werfen Ihre Spannen über weg monthText + " " + month.getYearLabel(). Siehe StringUtils.concat().
CommonsWare

2
@ TimBoland: Sie könnten das alles in einem tun: monthYearLabel.setText(Html.fromHtml("<b>"+month.getMonthLabel().toUpperCase()+"</b>&nbsp;"+month.getYearLabel()))wenn Sie die einzelnen Teile nicht benötigen.
CommonsWare

191

Etwas abseits des Themas, aber ich fand das zu nützlich, um hier nicht erwähnt zu werden.

Was ist, wenn wir den HTML-Text aus der Ressource string.xml lesen und so die Lokalisierung vereinfachen möchten ? CDATA machen dies möglich:

<string name="my_text">
  <![CDATA[
    <b>Autor:</b> Mr Nice Guy<br/>
    <b>Contact:</b> myemail@grail.com<br/>
    <i>Copyright © 2011-2012 Intergalactic Spacebar Confederation </i>
  ]]>
</string> 

Aus unserem Java-Code könnten wir ihn jetzt folgendermaßen verwenden:

TextView tv = (TextView) findViewById(R.id.myTextView);
tv.setText(Html.fromHtml(getString(R.string.my_text))); 

Ich hatte nicht erwartet, dass das funktioniert. Aber es tat es.

Hoffe, es ist nützlich für einige von euch!


2
Normalerweise bedeutet "false", dass Sie auf einen seltsamen Wert in der Nachschlagetabelle zugegriffen haben. Ich bekam dies, als ich R.id.ok und R.string.ok hatte und versehentlich getString (R.id.ok) anstelle des korrekten getString (R.string.ok) verwendete
Joe Plante

Funktioniert das auch in einem Layout-XML? Wenn ich dort auf die Zeichenfolgenressource verweise "@string/someText"(wobei "someText" eine in einer Zeichenfolge.xml definierte Ressource ist), erhalte ich nur die Zeichenfolge mit allen HTML-Tags als "Text".
Gee.E

3
Ich fand das die beste Antwort. Inspiriere mich. Konnte nicht anders, als meine zwei Cent wert Antwort zu geben. Lösung hier gist.github.com/aegis1980/b138dcb2fd1b2e98aa30 ermöglicht das Zuweisen in Layoutdateien, sodass Sie keine Textressource programmgesteuert zuweisen müssen (und eine Vorschau in Android Studio anzeigen können!)
Jon

127

Wenn Sie keine Lust auf HTML haben, können Sie einfach eine styles.xml erstellen und wie folgt verwenden:

TextView tv = (TextView) findViewById(R.id.textview);
SpannableString text = new SpannableString(myString);

text.setSpan(new TextAppearanceSpan(getContext(), R.style.myStyle), 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setSpan(new TextAppearanceSpan(getContext(), R.style.myNextStyle), 6, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

tv.setText(text, TextView.BufferType.SPANNABLE);

Kopieren Sie es in eine einfache Android-Anwendung, an der Sie möglicherweise arbeiten. Sie werden sehen, dass in einer einzelnen Textansicht zwei Stile angewendet werden.
Kent Andersen

Entschuldigung, ich war nicht klar. Wenn Sie die Teilzeichenfolge (über die beiden Indizes) angeben müssen, wo der Stil angewendet werden soll, funktioniert dies nicht für lokalisierte Zeichenfolgen, da die Indizes natürlich für jedes Gebietsschema unterschiedlich sind.
Jeffrey Blattman

Du hast Recht. Wenn Sie mehrere Sprachen unterstützen, ist dies nicht der Weg, den Sie einschlagen möchten. Es sei denn, Sie waren sich sicher, dass die Zeichenfolge die Größe nicht ändern würde ... wie zum Beispiel der Anwendungsname.
Kent Andersen

9
Ich verstehe nicht, warum l10n mit dieser Lösung nicht arbeiten kann. Holen Sie sich einfach separate Zeichenfolgen anstelle von nur einer: String firstPart = getString (R.string.line1); String secondPart = getString (R.string.line2); Spannbarer Text = neuer SpannableString (firstPart + secondPart); text.setSpan (neues ForegroundColorSpan (Color.parseColor (TEXT_COLOR_FOR_FIRST_PART)), 0, firstPart.length (), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); myTextView.setText (text, TextView.BufferType.SPANNABLE);
Rui

5
@ Rui, weil l10n auch positionell ist. Sie können die Position von Wörtern in einer Phrase nicht fest codieren und trotzdem l10n sein. Deshalb sieht man Dinge wie $1%s is a happy $2%sin String-Bundles. Sie müssen zulassen, dass die Token neu angeordnet werden.
Jeffrey Blattman

60

Es ist leichter, ein SpannableStringanstelle von HTML-Markup zu verwenden. Es hilft mir, visuelle Beispiele zu sehen, daher hier eine ergänzende Antwort.

Geben Sie hier die Bildbeschreibung ein

Dies ist eine Single TextView.

// set the text
SpannableString s1 = new SpannableString("bold\n");
SpannableString s2 = new SpannableString("italic\n");
SpannableString s3 = new SpannableString("foreground color\n");
SpannableString s4 = new SpannableString("background color\n");
SpannableString s5 = new SpannableString("underline\n");
SpannableString s6 = new SpannableString("strikethrough\n");
SpannableString s7 = new SpannableString("bigger\n");
SpannableString s8 = new SpannableString("smaller\n");
SpannableString s9 = new SpannableString("font\n");
SpannableString s10 = new SpannableString("URL span\n");
SpannableString s11 = new SpannableString("clickable span\n");
SpannableString s12 = new SpannableString("overlapping spans\n");

// set the style
int flag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
s1.setSpan(new StyleSpan(Typeface.BOLD), 0, s1.length(), flag);
s2.setSpan(new StyleSpan(Typeface.ITALIC), 0, s2.length(), flag);
s3.setSpan(new ForegroundColorSpan(Color.RED), 0, s3.length(), flag);
s4.setSpan(new BackgroundColorSpan(Color.YELLOW), 0, s4.length(), flag);
s5.setSpan(new UnderlineSpan(), 0, s5.length(), flag);
s6.setSpan(new StrikethroughSpan(), 0, s6.length(), flag);
s7.setSpan(new RelativeSizeSpan(2), 0, s7.length(), flag);
s8.setSpan(new RelativeSizeSpan(0.5f), 0, s8.length(), flag);
s9.setSpan(new TypefaceSpan("monospace"), 0, s9.length(), flag);
s10.setSpan(new URLSpan("https://developer.android.com"), 0, s10.length(), flag);
s11.setSpan(new ClickableSpan() {
    @Override
    public void onClick(View widget) {
        Toast.makeText(getApplicationContext(), "Span clicked", Toast.LENGTH_SHORT).show();
    }
}, 0, s11.length(), flag);
s12.setSpan(new ForegroundColorSpan(Color.RED), 0, 11, flag);
s12.setSpan(new BackgroundColorSpan(Color.YELLOW), 4, s12.length(), flag);
s12.setSpan(new UnderlineSpan(), 4, 11, flag);

// build the string
SpannableStringBuilder builder = new SpannableStringBuilder();
builder.append(s1);
builder.append(s2);
builder.append(s3);
builder.append(s4);
builder.append(s5);
builder.append(s6);
builder.append(s7);
builder.append(s8);
builder.append(s9);
builder.append(s10);
builder.append(s11);
builder.append(s12);

// set the text view with the styled text
textView.setText(builder);
// enables clicking on spans for clickable span and url span
textView.setMovementMethod(LinkMovementMethod.getInstance());

Weitere Studie

Dieses Beispiel wurde ursprünglich von hier inspiriert .


5
Ihr Beitrag ist besser als Google-Dokumentation über SpannableString .. Vielen Dank
MBH

Hat dies Bilder unterstützt, die vom Webdienst stammen? Meine Anforderung so.
MohanRaj S

@MohanRajS SpannableStrings unterstützen Unicode-Emoji, jedoch keine anderen Bilder.
Suragch

@ Suragch danke für die schnelle Antwort, aber meine Nebenanforderung ist jpg, png. Die einzige Wahl ist Webview? :(
MohanRaj S

43

Die Liste der unterstützten Tags lautet:

Wenn Sie eine Zeichenfolgenressource verwenden, können Sie ein einfaches Styling hinzufügen, z. B. fett oder kursiv in HTML-Notation. Die derzeit unterstützten Tags sind: B(fett), I(kursiv), U(unterstrichen), TT(Monospace) BIG, SMALL, SUP(Exponent), SUB(Index) und STRIKE( durchgestrichen). So res/values/strings.xmlkönnten Sie beispielsweise Folgendes deklarieren:

<resource>
    <string id="@+id/styled_welcome_message">We are <b><i>so</i></b> glad to see you.</string>
</resources>

(Von http://developer.android.com/guide/faq/commontasks.html#selectingtext - Webarchiv-Link ist <resource>Tippfehler im Original!)

Es zeigt auch, dass dies Html.fromHtmlin einfachen Fällen nicht wirklich benötigt wird.


Html.fromHtml ist oft eine einfachere Möglichkeit, Text zu formatieren. Auch dieser Link befindet sich bereits in der ursprünglichen Frage.
Komplikationen

17

Ich hatte das gleiche Problem. Ich könnte fromHtml verwenden, aber ich bin jetzt Android, nicht Web, also habe ich beschlossen, dies auszuprobieren. Ich muss dies allerdings lokalisieren, also habe ich es mit dem String-Ersatz-Konzept versucht. Ich habe den Stil in der Textansicht als Hauptstil festgelegt und dann nur die anderen Teile formatiert.

Ich hoffe, dies hilft anderen, die das Gleiche tun möchten - ich weiß nicht, warum dies im Framework nicht einfacher ist.

Meine Saiten sehen so aus:


<string name="my_text">{0} You will need a {1} to complete this assembly</string>
<string name="text_sub0">1:</string>
<string name="text_sub1">screwdriver, hammer, and measuring tape</string>

Hier sind die Stile:


<style name="MainStyle">
    <item name="android:textSize">@dimen/regular_text</item>
    <item name="android:textColor">@color/regular_text</item>
</style>
<style name="style0">
    <item name="android:textSize">@dimen/paragraph_bullet</item>
    <item name="android:textColor">@color/standout_text</item>
    <item name="android:textStyle">bold</item>
</style>
<style name="style1">
    <item name="android:textColor">@color/standout_light_text</item>
    <item name="android:textStyle">italic</item>
</style>

Hier ist mein Code, der meine formatStyles-Methode aufruft:


SpannableString formattedSpan = formatStyles(getString(R.string.my_text), getString(R.string.text_sub0), R.style.style0, getString(R.string.main_text_sub1), R.style.style1);
textView.setText(formattedSpan, TextView.BufferType.SPANNABLE);

Die Formatierungsmethode:


private SpannableString formatStyles(String value, String sub0, int style0, String sub1, int style1)
{
    String tag0 = "{0}";
    int startLocation0 = value.indexOf(tag0);
    value = value.replace(tag0, sub0);

    String tag1 = "{1}";
    int startLocation1 = value.indexOf(tag1);
    if (sub1 != null && !sub1.equals(""))
    {
        value = value.replace(tag1, sub1);
    }

    SpannableString styledText = new SpannableString(value);
    styledText.setSpan(new TextAppearanceSpan(getActivity(), style0), startLocation0, startLocation0 + sub0.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    if (sub1 != null && !sub1.equals(""))
    {
        styledText.setSpan(new TextAppearanceSpan(getActivity(), style1), startLocation1, startLocation1 + sub1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

    return styledText;
}

Ich denke nicht, dass dies funktionieren wird, wenn eine lokalisierte Version der Zeichenfolge {0} und {1} neu anordnet. Möglicherweise müssen Sie startLocation0 ändern, wenn startLocation1 <startLocation0
JonathanC


8

Hier ist eine einfache Möglichkeit, dies mit HTMLBuilder zu tun

    myTextView.setText(new HtmlBuilder().
                    open(HtmlBuilder.Type.BOLD).
                    append("Some bold text ").
                    close(HtmlBuilder.Type.BOLD).
                    open(HtmlBuilder.Type.ITALIC).
                    append("Some italic text").
                    close(HtmlBuilder.Type.ITALIC).
                    build()
    );

Ergebnis:

Einige fette Texte Einige kursive Texte


7

Wenn Sie den gestalteten Text in XML hinzufügen möchten, können Sie eine benutzerdefinierte Ansicht erstellen, die TextView erweitert, und setText () überschreiben:

public class HTMLStyledTextView extends TextView
{
    public HTMLStyledTextView(Context context) {
        super(context);
    }

    public HTMLStyledTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public HTMLStyledTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void setText(CharSequence text, BufferType type)
    {
       super.setText(Html.fromHtml(text.toString()), type);
    }
}

Dann können Sie es wie folgt verwenden (durch PACKAGE_NAMEIhren Paketnamen ersetzen ):

<PACKAGE_NAME.HTMLStyledTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="<![CDATA[
        <b>Bolded Text:</b> Non-Bolded Text
    ]]>"
/>

Wird die Vorschau in Android Studio dann richtig angezeigt?
JPM


3

Ich auch

Wie wäre es mit einem schönen Markup mit Kotlin und Anko -

import org.jetbrains.anko.*
override fun onCreate(savedInstanceState: Bundle?) {
    title = "Created with Beautiful Markup"
    super.onCreate(savedInstanceState)

    verticalLayout {
        editText {
            hint = buildSpanned {
                append("Italic, ", Italic)
                append("highlighted", backgroundColor(0xFFFFFF00.toInt()))
                append(", Bold", Bold)
            }
        }
    }
}

Erstellt mit schönen Markup


2

Ja, es ist möglich mit SpannedString. Wenn Sie Kotlin verwenden, wird die Verwendung noch einfacher core-ktx, da hierfür eine domänenspezifische Sprache (DSL) bereitgestellt wird:

    val string: SpannedString = buildSpannedString {
        bold {
            append("1111")
        }
        append("Devansh")     
    }

Weitere Optionen sind:

append("Hello There")
bold {
    append("bold")
    italic {
        append("bold and italic")
        underline {
            append("then some text with underline")
        }
    }
}

Endlich können Sie einfach:

textView.text = string

0

Mit Ausnahme des HTML-Objekts können Sie auch die Spannable-Typklassen verwenden, z. B. TextAppearanceSpan oder TypefaceSpan und SpannableString zusammen. Die HTML-Klasse verwendet diese Mechanismen ebenfalls. Mit den Spannable-Typklassen haben Sie jedoch mehr Freiheit.


0

Es kann so einfach sein, wie die Methode length () des Strings zu nutzen:

  1. Teilen Sie die Textzeichenfolge in der Strings-XML-Datei in so viele Unterzeichenfolgen (aus Sicht von Android eine separate Zeichenfolge) auf, wie viele verschiedene Stile benötigen. Es könnte also so aussehen: str1, str2, str3 (wie in Ihrem Fall), Wenn sie zusammengefügt werden, ist dies die gesamte einzelne Zeichenfolge, die Sie verwenden.

  2. Und dann folgen Sie einfach der "Span" -Methode, genau wie Sie es mit Ihrem Code dargestellt haben. Kombinieren Sie jedoch anstelle einer einzelnen Zeichenfolge alle Teilzeichenfolgen, die sie zu einer einzigen zusammenführen, die jeweils einen anderen benutzerdefinierten Stil haben.

Sie verwenden die Zahlen immer noch, jedoch nicht direkt - sie haben jetzt keine fest codierte Form mehr (wie in Ihrem Code), sondern werden durch die kombinierten length () -Methoden ersetzt (beachten Sie zwei Sterne vor und mit dem Suffix str. Länge () anstelle der absoluten Zahl, um die Änderung auszulöschen):

str.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, **str.length()**, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

für die erste Zeichenfolgengröße dann str.length () + 1, str.length () + str2.length () für die zweite Zeichenfolgengröße usw. mit allen Teilzeichenfolgen anstelle von z. B. 0,7 oder 8,19 und so weiter...


0

Verwenden einer zusätzlichen überspannbaren Klasse als Android String Resources- Freigabe am Ende der Webseite. Sie können dies erreichen, CharSquencesindem Sie ihnen einen Stil erstellen und geben.

Aber in dem Beispiel, das sie uns geben, ist nur für fett, kursiv und sogar kolorieren Text. Ich musste mehrere Stile in a CharSequenceeinschließen, um sie in a zu setzen TextView. Also habe ich dieser Klasse (ich habe sie genannt CharSequenceStyles) gerade diese Funktion hinzugefügt.

public static CharSequence applyGroup(LinkedList<CharSequence> content){
    SpannableStringBuilder text = new SpannableStringBuilder();
    for (CharSequence item : content) {
        text.append(item);
    }
    return text;
}

Und in der Ansicht habe ich dies hinzugefügt.

            message.push(postMessageText);
            message.push(limitDebtAmount);
            message.push(pretMessageText);
            TextView.setText(CharSequenceStyles.applyGroup(message));

Ich hoffe das hilft dir!


0

Spanny vereinfacht die Verwendung von SpannableString.

Spanny spanny = new Spanny("Underline text", new UnderlineSpan())
                .append("\nRed text", new ForegroundColorSpan(Color.RED))
                .append("\nPlain text");
textView.setText(spanny)

0

Wie Jon sagte , ist dies für mich die beste Lösung und Sie müssen zur Laufzeit keinen Text festlegen. Verwenden Sie nur diese benutzerdefinierte Klasse HtmlTextView

public class HtmlTextView extends TextView {

  public HtmlTextView(Context context) {
      super(context);
  }

  public HtmlTextView(Context context, AttributeSet attrs) {
      super(context, attrs);
  }

  public HtmlTextView(Context context, AttributeSet attrs, int defStyleAttr) 
  {
      super(context, attrs, defStyleAttr);
  }

  @TargetApi(21)
  public HtmlTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
      super(context, attrs, defStyleAttr, defStyleRes);
  }

  @Override
  public void setText(CharSequence s,BufferType b){
      super.setText(Html.fromHtml(s.toString()),b);
  }

}

und das wars, jetzt nur noch in dein XML

<com.fitc.views.HtmlTextView
    android:id="@+id/html_TV"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/example_html" />

mit Ihrem HTML-String

<string name="example_html">
<![CDATA[
<b>Author:</b> Mr Donuthead<br/>
<b>Contact:</b> me@donut.com<br/>
<i>Donuts for life </i>
]]>

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.