Câu trả lời:
Nó có thể đạt được nếu bạn đang sử dụng tệp xml tài nguyên chuỗi , hỗ trợ các thẻ HTML như <b></b>
, <i></i>
và <u></u>
.
<resources>
<string name="your_string_here">This is an <u>underline</u>.</string>
</resources>
Nếu bạn muốn gạch chân một cái gì đó từ mã sử dụng:
TextView textView = (TextView) view.findViewById(R.id.textview);
SpannableString content = new SpannableString("Content");
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
textView.setText(content);
<u>
các thẻ không hoạt động, ví dụ đôi khi nếu bạn đang sử dụng một phông chữ tùy chỉnh. Tuy nhiên, cơ bản về mặt lập trình bởi UnderlineSpan
vẫn chưa thất bại với tôi, vì vậy tôi muốn giới thiệu nó như là giải pháp đáng tin cậy nhất.
Bạn có thể thử với
textview.setPaintFlags(textview.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
| Paint.ANTI_ALIAS_FLAG
hoặc văn bản của bạn sẽ trông rất sắc nét. Điều này biểu hiện trong các API thấp hơn thường xuyên hơn không.
textView.paintFlags = textView.paintFlags or Paint.UNDERLINE_TEXT_FLAG
Câu trả lời "được chấp nhận" ở trên KHÔNG hoạt động (khi bạn cố gắng sử dụng chuỗi như thế nào textView.setText(Html.fromHtml(String.format(getString(...), ...)))
.
Như đã nêu trong tài liệu, bạn phải thoát (mở mã thực thể html) của các thẻ bên trong <
, ví dụ: kết quả sẽ như sau:
<resource>
<string name="your_string_here">This is an <u>underline</u>.</string>
</resources>
Sau đó, trong mã của bạn, bạn có thể đặt văn bản với:
TextView textView = (TextView) view.findViewById(R.id.textview);
textView.setText(Html.fromHtml(String.format(getString(R.string.my_string), ...)));
Nội dung tệp String.xml:
<resource>
<string name="my_text">This is an <u>underline</u>.</string>
</resources>
Bố cục tệp xml sẽ sử dụng tài nguyên chuỗi ở trên với các thuộc tính bên dưới của textview, như được hiển thị bên dưới:
<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"
/>
Đối với Nút và TextView, đây là cách dễ nhất:
Cái nút:
Button button = (Button) findViewById(R.id.btton1);
button.setPaintFlags(button.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
Xem văn bản:
TextView textView = (TextView) findViewById(R.id.textview1);
textView.setPaintFlags(textView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
kiểm tra kiểu nút có thể nhấp được nhấn mạnh:
<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" />
chuỗi XML:
<string name="btn_add_contact"><u>Add new contact</u></string>
Kết quả:
Cách tiếp cận gần đây nhất của việc vẽ văn bản được gạch chân được mô tả bởi Romain Guy trên phương tiện với mã nguồn có sẵn trên GitHub . Ứng dụng mẫu này cho thấy hai triển khai có thể:
Tôi biết đây là một câu trả lời muộn, nhưng tôi đã đưa ra một giải pháp hoạt động khá tốt ... Tôi đã lấy câu trả lời từ Anthony Forloney để gạch chân văn bản trong mã và tạo một lớp con TextView xử lý nó cho bạn. Sau đó, bạn chỉ có thể sử dụng lớp con trong XML bất cứ khi nào bạn muốn có TextView được gạch chân.
Đây là lớp tôi đã tạo:
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;
}
}
Bây giờ ... bất cứ khi nào bạn muốn tạo một textview được gạch chân trong XML, bạn chỉ cần làm như sau:
<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"/>
Tôi đã thêm các tùy chọn bổ sung trong đoạn mã XML này để cho thấy ví dụ của tôi hoạt động với việc thay đổi màu văn bản, kích thước và kiểu ...
Hi vọng điêu nay co ich!
Một cách sạch hơn thay vì
textView.setPaintFlags(textView.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
phương pháp là sử dụng
textView.getPaint().setUnderlineText(true);
Và nếu sau này bạn cần tắt gạch chân cho chế độ xem đó, chẳng hạn như trong chế độ xem được sử dụng lại trong RecyclerView, textView.getPaint().setUnderlineText(false);
Tôi đã sử dụng xml drawable này để tạo đường viền dưới cùng và áp dụng drawable làm nền cho textview của tôi
<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>
Một giải pháp đơn giản và linh hoạt trong 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" />
một giải pháp khác là tạo chế độ xem tùy chỉnh mở rộng TextView như hiển thị bên dưới
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);
}
}
và chỉ cần thêm vào xml như hình dưới đây
<yourpackage.UnderLineTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="underline text"
/>
Tôi đã đơn giản hóa câu trả lời của Samuel :
<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>
TextView tv = findViewById(R.id.tv);
tv.setText("some text");
Gạch chân toàn bộ TextView
setUnderLineText(tv, tv.getText().toString());
Gạch chân một số phần của TextView
setUnderLineText(tv, "some");
Cũng hỗ trợ các con TextView như EditText, Nút, Hộp kiểm
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);
}
}
}
sampleTextView.setText(R.string.sample_string);
Hơn nữa, đoạn mã sau sẽ không in phần gạch chân:
String sampleString = getString(R.string.sample_string);
sampleTextView.setText(sampleString);
Thay vào đó, sử dụng mã sau để giữ lại định dạng văn bản phong phú:
CharSequence sampleString = getText(R.string.sample_string);
sampleTextView.setText(sampleString);
"Bạn có thể sử dụng getString (int) hoặc getText (int) để truy xuất chuỗi. GetText (int) giữ lại bất kỳ kiểu văn bản có định dạng nào được áp dụng cho chuỗi." Tài liệu Android.
Tham khảo tài liệu: https://developer.android.com/guide/topics/resource/opes-resource.html
Tôi hi vọng cái này giúp được.
Câu trả lời được bình chọn hàng đầu là đúng và đơn giản nhất. Tuy nhiên, đôi khi bạn có thể thấy rằng không hoạt động đối với một số phông chữ, nhưng làm việc cho những người khác. (Vấn đề mà tôi vừa gặp phải khi giao tiếp với tiếng Trung Quốc.)
Giải pháp không chỉ sử dụng "WRAP_CONTENT" cho TextView của bạn, vì không có thêm không gian để vẽ đường. Bạn có thể đặt chiều cao cố định cho TextView của mình hoặc sử dụng android: paddingV vertical với WRAP_CONTENT.
HtmlCompat.fromHtml(
String.format(context.getString(R.string.set_target_with_underline)),
HtmlCompat.FROM_HTML_MODE_LEGACY)
<string name="set_target_with_underline"><u>Set Target<u> </string>
Lưu ý biểu tượng Escape trong tệp xml
Tôi gặp vấn đề khi tôi sử dụng phông chữ tùy chỉnh và phần gạch chân được tạo bằng thủ thuật tệp tài nguyên ( <u>Underlined text</u>
) đã hoạt động nhưng Android đã quản lý để chuyển đổi phần gạch chân thành một loại máng đình công.
Tôi đã sử dụng câu trả lời này để tự vẽ một đường viền bên dưới textview: https://stackoverflow.com/a/10732993/664449 . Rõ ràng điều này không hoạt động đối với văn bản được gạch chân một phần hoặc văn bản đa lớp.