Czy mogę podkreślić tekst w układzie Androida?

Odpowiedzi:

1144

Można to osiągnąć, jeśli używasz zasobów ciąg plik XML, który obsługuje znaczniki HTML jak <b></b>, <i></i>i <u></u>.

<resources>
    <string name="your_string_here">This is an <u>underline</u>.</string>
</resources>

Jeśli chcesz podkreślić coś z kodu użyj:

TextView textView = (TextView) view.findViewById(R.id.textview);
SpannableString content = new SpannableString("Content");
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
textView.setText(content);
Anthony Forloney
źródło
49
Cześć, próbowałem powyższego kodu XML zasobu i nie działało. nadal wyświetlał <u> podkreślenie </u> jako zwykły tekst
Jonathan
4
Zobacz także: android.text.Html.fromHtml (), który zwraca wartość Łączone.
Mark Renouf,
3
Powinieneś wpisać go w samym pliku strings.xml, nie wykonując tego przyciskiem dodawania. W przeciwnym razie otrzymasz to <u & gt; w pliku strings.xml i <u> podkreśl </u> w kodzie
gdrt
3
Zetknąłem się z przypadkami, gdy bazowe za pomocą <u>tagów nie działa, np. Czasami, gdy używasz niestandardowej czcionki. Jednak programowe bazowanie przez UnderlineSpanjeszcze mnie nie zawiodło, dlatego poleciłbym to jako najbardziej niezawodne rozwiązanie.
Giulio Piancastelli
26
Nie będzie się wyświetlać w edytorze, ale gdy uruchomisz aplikację - zostanie podkreślona.
jean d'arme
534

Możesz spróbować

textview.setPaintFlags(textview.getPaintFlags() |   Paint.UNDERLINE_TEXT_FLAG);
Vado
źródło
1
Może drobna uwaga, ale OP chciał, aby to zdefiniować w pliku układu XML; w przeciwnym razie jest to świetne rozwiązanie.
kwishnu
4
skorzystaj z tego rozwiązania, jeśli chcesz je wyczyścić
Bobs
2
tego rozwiązania można również użyć do przycisku
Rudy Kurniawan
3
Ostrożnie, jeśli używasz niestandardowych czcionek lub podobnych, może być konieczne, aby | Paint.ANTI_ALIAS_FLAGtekst był bardzo ostry. Przejawia się to w niższych interfejsach API częściej niż nie.
Martin Marconcini,
4
W Kotlinie:textView.paintFlags = textView.paintFlags or Paint.UNDERLINE_TEXT_FLAG
Albert Vila Calvo,
72

Powyższa „zaakceptowana” odpowiedź NIE działa (przy próbie użycia ciągu jak textView.setText(Html.fromHtml(String.format(getString(...), ...))).

Jak stwierdzono w dokumentacji , musisz uciec (zakodowany w postaci encji HTML) otwierający nawias klamrami wewnętrznymi &lt;, np. Wynik powinien wyglądać następująco:

<resource>
    <string name="your_string_here">This is an &lt;u&gt;underline&lt;/u&gt;.</string>
</resources>

Następnie w kodzie możesz ustawić tekst za pomocą:

TextView textView = (TextView) view.findViewById(R.id.textview);
textView.setText(Html.fromHtml(String.format(getString(R.string.my_string), ...)));
Ognyan
źródło
4
<u> podkreślone tutaj </u> działa idealnie. Podkreślenie nie działało. To jest dla Androida 2.2. Może różne wersje interpretują to inaczej.
user898763452
@autotravis, który jest dla 2.2? Nie testowałem go na starszych wersjach i będzie to niefortunne, jeśli różne wersje będą go obsługiwały inaczej ... Również przynajmniej bieżąca dokumentacja stwierdza, że ​​trzeba go uciec (link jest w odpowiedzi).
Ognyan
Testowałem <u> podkreśliłem </u> na Androidzie 2.3 i działa. Podkreślenie nie działa dla 2.3. Dokumenty mówią: „Czasami możesz chcieć utworzyć stylizowany zasób tekstowy, który będzie również używany jako ciąg formatujący. Zwykle to nie zadziała, ponieważ metoda String.format (String, Object ...) usunie wszystkie informacje o stylu z ciągu. Obejściem tego problemu jest napisanie tagów HTML ze znakami ucieczki, które są następnie odzyskiwane z fromHtml (String), po zakończeniu formatowania. " Sądzę więc, że użyłbyś ucieczki, jeśli uruchomisz go za pomocą tej metody String.format (...).
user898763452
@autotravis tak, masz rację. Używam go z String.format (...). Zredagowałem swoją odpowiedź, dziękuję za opinię.
Ognyan
W 2.3 i 4.1 (tylko te, których do tej pory próbowałem) możesz po prostu użyć textView.setText (getText (R.string.text)) zamiast konieczności używania getString (), Html.fromHtml () i String.format ().
Roy Solberg,
59

Zawartość pliku Strings.xml:

<resource>
     <string name="my_text">This is an <u>underline</u>.</string> 
</resources> 

Układ pliku XML podzielonego na fragmenty użyj powyższego zasobu ciągu z poniższymi właściwościami widoku tekstu, jak pokazano poniżej:

<TextView 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:text="@string/my_text"

    android:selectAllOnFocus="false"
    android:linksClickable="false"
    android:autoLink="all"
    />
Devendra Anurag
źródło
3
Upewnij się, że edytujesz plik zasobów łańcucha w obrębie rzeczywistego XML, a nie w interfejsie pomocniczym edycji interfejsu użytkownika w Eclipse, ponieważ spowoduje to ujście <s.
Chris Rae,
51

W przypadku Button i TextView jest to najprostszy sposób:

Przycisk:

Button button = (Button) findViewById(R.id.btton1);
button.setPaintFlags(button.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);

Widok tekstu:

TextView textView = (TextView) findViewById(R.id.textview1);
textView.setPaintFlags(textView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
awsleiman
źródło
Bardzo eleganckie rozwiązanie. Dziękuję Ci!
Adrian
20

Rozwiązanie jednoliniowe

myTextView.setText(Html.fromHtml("<p><u>I am Underlined text</u></p>"));

Jest trochę późno, ale może być dla kogoś przydatny.

gprathour
źródło
19

W Kotlinie można zastosować funkcję rozszerzenia . Można tego używać tylko z kodu, a nie xml.

fun TextView.underline() {
    paintFlags = paintFlags or Paint.UNDERLINE_TEXT_FLAG
}

Stosowanie:

 tv_change_number.underline()
 tv_resend_otp.underline()
Zabójca
źródło
13

sprawdź podkreślony styl klikalnego przycisku:

<TextView
    android:id="@+id/btn_some_name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/btn_add_contact"
    android:textAllCaps="false"
    android:textColor="#57a0d4"
    style="@style/Widget.AppCompat.Button.Borderless.Colored" />

strings.xml:

<string name="btn_add_contact"><u>Add new contact</u></string>

Wynik:

wprowadź opis zdjęcia tutaj

Kirill Vashilo
źródło
Wygląd Widget.AppCompat.Button.Borderless.Colored jest znacznie lepszy niż podkreślanie, jednak, jak opisał @Kiril Vashilo, możesz to zrobić i tak.
xarlymg89
11

Najnowsze podejście do rysowania podkreślonego tekstu opisuje Romain Guy na nośniku z dostępnym kodem źródłowym na GitHub . Ta przykładowa aplikacja udostępnia dwie możliwe implementacje:

  • Implementacja oparta na ścieżce, która wymaga interfejsu API na poziomie 19
  • Implementacja oparta na regionie, która wymaga interfejsu API poziomu 1

wprowadź opis zdjęcia tutaj

Włodzimierz
źródło
10

Wiem, że to późna odpowiedź, ale wymyśliłem rozwiązanie, które działa całkiem dobrze ... Wziąłem odpowiedź Anthony'ego Forloneya za podkreślenie tekstu w kodzie i stworzyłem podklasę TextView, która to obsługuje. Następnie możesz po prostu użyć podklasy w XML, kiedy tylko chcesz mieć podkreślony TextView.

Oto klasa, którą stworzyłem:

import android.content.Context;
import android.text.Editable;
import android.text.SpannableString;
import android.text.TextWatcher;
import android.text.style.UnderlineSpan;
import android.util.AttributeSet;
import android.widget.TextView;

/**
 * Created with IntelliJ IDEA.
 * User: Justin
 * Date: 9/11/13
 * Time: 1:10 AM
 */
public class UnderlineTextView extends TextView
{
    private boolean m_modifyingText = false;

    public UnderlineTextView(Context context)
    {
        super(context);
        init();
    }

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

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

    private void init()
    {
        addTextChangedListener(new TextWatcher()
        {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after)
            {
                //Do nothing here... we don't care
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count)
            {
                //Do nothing here... we don't care
            }

            @Override
            public void afterTextChanged(Editable s)
            {
                if (m_modifyingText)
                    return;

                underlineText();
            }
        });

        underlineText();
    }

    private void underlineText()
    {
        if (m_modifyingText)
            return;

        m_modifyingText = true;

        SpannableString content = new SpannableString(getText());
        content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
        setText(content);

        m_modifyingText = false;
    }
}

Teraz ... ilekroć chcesz utworzyć podkreślony widok tekstu w XML, po prostu wykonaj następujące czynności:

<com.your.package.name.UnderlineTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:gravity="center"
    android:text="This text is underlined"
    android:textColor="@color/blue_light"
    android:textSize="12sp"
    android:textStyle="italic"/>

Dodałem dodatkowe opcje w tym fragmencie kodu XML, aby pokazać, że mój przykład działa ze zmianą koloru, rozmiaru i stylu tekstu ...

Mam nadzieję że to pomoże!

Justin
źródło
2
Podczas gdy ten przykład działa, szybko zdałem sobie sprawę, że jeśli kiedykolwiek będziesz chciał mieć dodatkową kontrolę w XML, czego to po prostu nie zrobi ... przeszedłem na lepsze rozwiązanie, które obejmuje następujące kroki: 1) Widok tekstu podklasy 2) Dodaj obsługę aby podkreślić tekst za pomocą niestandardowych atrybutów, aby wykonać podkreślenie, jak określono powyżej. Jedyna różnica polega na tym, że kod podkreślenia jest wykonywany tylko wtedy, gdy ustawiony jest atrybut niestandardowy.
Justin
10

Czystszym sposobem zamiast
textView.setPaintFlags(textView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG); metody jest użycie textView.getPaint().setUnderlineText(true);

A jeśli chcesz później wyłączyć podkreślenie dla tego widoku, na przykład w widoku ponownie używanym w RecyclerView, textView.getPaint().setUnderlineText(false);

jk7
źródło
7

Wystarczy użyć atrybutu w pliku zasobów ciągów np

<string name="example"><u>Example</u></string>
Aditya S.
źródło
7

Użyłem tego xml drawable do stworzenia dolnej granicy i zastosowałem drawable jako tło do mojego widoku tekstu

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle" >
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>

    <item android:top="-5dp" android:right="-5dp" android:left="-5dp">
        <shape>
            <solid android:color="@android:color/transparent" />
            <stroke
                    android:width="1.5dp"
                    android:color="@color/pure_white" />
        </shape>
    </item>
</layer-list>
Samuel
źródło
jest to idealne rozwiązanie dla wszystkich podkreślonych widoków z niestandardowym kolorem. nie lekceważ tutaj przezroczystego tła, dla Androida 4 jest to wymagane, twój widok będzie miał czarne tło bez niego
Ivan Mitsura
5

Proste i elastyczne rozwiązanie w XML:

<View
  android:layout_width="match_parent"
  android:layout_height="3sp"
  android:layout_alignLeft="@+id/your_text_view_need_underline"
  android:layout_alignRight="@+id/your_text_view_need_underline"
  android:layout_below="@+id/your_text_view_need_underline"
  android:background="@color/your_color" />
użytkownik3786340
źródło
4

innym rozwiązaniem jest utworzenie niestandardowego widoku, który rozszerza TextView, jak pokazano poniżej

public class UnderLineTextView extends TextView {

    public UnderLineTextView(Context context) {
        super(context);
        this.setPaintFlags(Paint.UNDERLINE_TEXT_FLAG);
    }

    public UnderLineTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.setPaintFlags(Paint.UNDERLINE_TEXT_FLAG);
    }

}

i po prostu dodaj do xml, jak pokazano poniżej

<yourpackage.UnderLineTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="underline text"
 />
has19
źródło
Niesamowite!! Ale kolor podkreślenia jest szary, jak zmienić go na czarny lub inny kolor?
OhhhThatVarun
3

Upraszczam odpowiedź Samuela :

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--https://stackoverflow.com/a/40706098/4726718-->
    <item
        android:left="-5dp"
        android:right="-5dp"
        android:top="-5dp">
        <shape>
            <stroke
                android:width="1.5dp"
                android:color="@color/colorAccent" />
        </shape>
    </item>
</layer-list>
Darush
źródło
3

Z łatwością stworzyłem tę metodę

TextView tv = findViewById(R.id.tv);
tv.setText("some text");

Podkreśl cały TextView

setUnderLineText(tv, tv.getText().toString());

Podkreśl jakąś część TextView

setUnderLineText(tv, "some");

Obsługują również dzieci TextView, takie jak EditText, Button, Checkbox

public void setUnderLineText(TextView tv, String textToUnderLine) {
        String tvt = tv.getText().toString();
        int ofe = tvt.indexOf(textToUnderLine, 0);

        UnderlineSpan underlineSpan = new UnderlineSpan();
        SpannableString wordToSpan = new SpannableString(tv.getText());
        for (int ofs = 0; ofs < tvt.length() && ofe != -1; ofs = ofe + 1) {
            ofe = tvt.indexOf(textToUnderLine, ofs);
            if (ofe == -1)
                break;
            else {
                wordToSpan.setSpan(underlineSpan, ofe, ofe + textToUnderLine.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                tv.setText(wordToSpan, TextView.BufferType.SPANNABLE);
            }
        }
    }

sprawdź moją odpowiedź tutaj, aby zaznaczyć klikalny tekst lub podkreślić wiele części TextView

Khemraj
źródło
2

wypróbuj ten kod

w XML

<resource>
 <string name="my_text"><![CDATA[This is an <u>underline</u>]]></string> 
</resources> 

W kodzie

TextView textView = (TextView) view.findViewById(R.id.textview);
textView.setText(Html.fromHtml(getString(R.string.my_text)));

Powodzenia!

Andrew.J
źródło
2
  1. Przejdź do pliku zasobów strings.xml
  2. W razie potrzeby dodaj ciąg do pliku zasobu ze znacznikiem podkreślenia HTML.

strings.xml Próbka podkreślenia HTML

  1. Wywołaj identyfikator zasobu ciągu w kodzie Java w następujący sposób:
sampleTextView.setText(R.string.sample_string);
  1. Dane wyjściowe powinny mieć podkreślone słowo „Stackoverflow”.

Ponadto poniższy kod nie wydrukuje podkreślenia:

String sampleString = getString(R.string.sample_string);
sampleTextView.setText(sampleString);

Zamiast tego użyj następującego kodu, aby zachować format tekstu sformatowanego:

CharSequence sampleString = getText(R.string.sample_string);
sampleTextView.setText(sampleString);

„Do pobrania ciągu można użyć getString (int) lub getText (int). GetText (int) zachowuje wszelkie style tekstu sformatowanego zastosowane do łańcucha.” Dokumentacja Androida.

Zapoznaj się z dokumentacją: https://developer.android.com/guide/topics/resources/string-resource.html

Mam nadzieję, że to pomoże.

Fahmi Eshaq
źródło
2

Najwyżej głosowana odpowiedź jest właściwa i najprostsza. Czasami jednak może się okazać, że nie działa w przypadku niektórych czcionek, ale działa w przypadku innych. (Na jaki problem natknąłem się podczas pracy z chińskim).

Rozwiązaniem nie jest użycie „WRAP_CONTENT” tylko dla TextView, ponieważ nie ma dodatkowej przestrzeni do rysowania linii. Możesz ustawić stałą wysokość na TextView lub użyć Androida: paddingVertical z WRAP_CONTENT.

Ray Lee
źródło
1
HtmlCompat.fromHtml(
                    String.format(context.getString(R.string.set_target_with_underline)),
                    HtmlCompat.FROM_HTML_MODE_LEGACY)
<string name="set_target_with_underline">&lt;u>Set Target&lt;u> </string>

Zwróć uwagę na symbol Escape w pliku xml

lynn8570
źródło
pracował dla mnie z symbolami ucieczki, dzięki!
Badr
1

Aby to zrobić w Kotlin:

yourTextView.paint?.isUnderlineText = true

Re'em
źródło
0

Jest dość późno, aby odpowiedzieć na to pytanie, ale załóżmy, że jeśli ktoś chce dynamicznie uzyskać tekst, może użyć tego prostego jednego wiersza w kodzie Java, który działa:

 textView.setText(Html.fromHtml("<p><u>" + get_name + "</u></p>"));
abby
źródło
-2

Miałem problem polegający na tym, że używam niestandardowej czcionki, a podkreślenie utworzone za pomocą pliku zasobów trick ( <u>Underlined text</u>) działało, ale Android zdołał przekształcić podkreślenie w rodzaj korytarza uderzenia.

Skorzystałem z tej odpowiedzi, aby sam narysować ramkę poniżej widoku tekstu: https://stackoverflow.com/a/10732993/664449 . Oczywiście nie działa to w przypadku tekstu częściowo podkreślonego lub tekstu wielowarstwowego.

Rick Pastoor
źródło