1. 基礎(chǔ)介紹
TextView 是 Android 中最基礎(chǔ)的 UI 組件之一,用于顯示文本內(nèi)容。
基本屬性
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textSize="16sp"
android:textColor="#000000" />
2. 文本內(nèi)容相關(guān)屬性
2.1 文本顯示
<TextView
android:text="顯示文本"
android:hint="提示文本" <!-- 提示文字 -->
android:textColorHint="#999999" <!-- 提示文字顏色 -->
android:text="@string/app_name" /> <!-- 引用字符串資源 -->
2.2 文本樣式
<TextView
android:textStyle="bold" <!-- normal|bold|italic -->
android:textSize="18sp"
android:textColor="#FF5722"
android:textAllCaps="true" <!-- 全部大寫 -->
android:fontFamily="sans-serif" <!-- 字體族 -->
android:typeface="monospace" /> <!-- 字型 -->
2.3 字體資源使用(API 26+)
<TextView
android:fontFamily="@font/roboto_regular" />
<!-- 或在代碼中 -->
TextView textView = findViewById(R.id.textView);
Typeface typeface = ResourcesCompat.getFont(context, R.font.roboto_regular);
textView.setTypeface(typeface);
3. 布局和對齊
3.1 對齊方式
<TextView
android:gravity="center" <!-- 文本在 View 內(nèi)的對齊 -->
android:textAlignment="center" <!-- 文本對齊方式 -->
android:layout_gravity="center" /> <!-- View 在父容器中的對齊 -->
gravity 常用值:
-
left|right|start|end- 水平對齊 -
top|bottom|center_vertical- 垂直對齊 -
center- 居中 -
fill- 填充
3.2 尺寸和邊距
<TextView
android:layout_width="match_parent" <!-- wrap_content|match_parent|具體數(shù)值 -->
android:layout_height="wrap_content"
android:minWidth="100dp"
android:minHeight="40dp"
android:maxWidth="200dp"
android:maxHeight="80dp"
android:padding="16dp"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:layout_margin="8dp" />
4. 文本溢出處理
4.1 單行和多行顯示
<TextView
android:singleLine="true" <!-- 已廢棄,推薦使用 maxLines -->
android:maxLines="3" <!-- 最大行數(shù) -->
android:minLines="1" <!-- 最小行數(shù) -->
android:lines="2" <!-- 固定行數(shù) -->
android:ellipsize="end" <!-- 省略號(hào)位置 -->
android:breakStrategy="simple" <!-- 換行策略 -->
android:hyphenationFrequency="normal" /> <!-- 連字符頻率 -->
ellipsize 選項(xiàng):
-
end- 在末尾顯示省略號(hào) -
start- 在開頭顯示省略號(hào) -
middle- 在中間顯示省略號(hào) -
marquee- 跑馬燈效果
4.2 跑馬燈效果
<TextView
android:id="@+id/marqueeText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:focusable="true"
android:focusableInTouchMode="true"
android:scrollHorizontally="true"
android:text="這是一個(gè)很長的文本,將會(huì)以跑馬燈效果顯示..." />
代碼中需要設(shè)置:
TextView marqueeText = findViewById(R.id.marqueeText);
marqueeText.setSelected(true); // 啟動(dòng)跑馬燈
5. 富文本顯示
5.1 SpannableString 使用
String text = "這是一個(gè)富文本示例";
SpannableString spannableString = new SpannableString(text);
// 設(shè)置前景色
spannableString.setSpan(new ForegroundColorSpan(Color.RED), 2, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設(shè)置背景色
spannableString.setSpan(new BackgroundColorSpan(Color.YELLOW), 5, 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設(shè)置粗體
spannableString.setSpan(new StyleSpan(Typeface.BOLD), 8, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設(shè)置斜體
spannableString.setSpan(new StyleSpan(Typeface.ITALIC), 11, 13, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設(shè)置下劃線
spannableString.setSpan(new UnderlineSpan(), 14, 16, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設(shè)置刪除線
spannableString.setSpan(new StrikethroughSpan(), 17, 19, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設(shè)置字體大小
spannableString.setSpan(new AbsoluteSizeSpan(24, true), 20, 22, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設(shè)置相對大小
spannableString.setSpan(new RelativeSizeSpan(1.5f), 23, 25, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設(shè)置上標(biāo)/下標(biāo)
spannableString.setSpan(new SuperscriptSpan(), 26, 28, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new SubscriptSpan(), 29, 31, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// 設(shè)置點(diǎn)擊事件
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
Toast.makeText(MainActivity.this, "點(diǎn)擊了文本", Toast.LENGTH_SHORT).show();
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(Color.BLUE);
ds.setUnderlineText(false);
}
};
spannableString.setSpan(clickableSpan, 32, 34, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(spannableString);
textView.setMovementMethod(LinkMovementMethod.getInstance()); // 啟用點(diǎn)擊
5.2 HTML 文本顯示
// 簡單 HTML 支持
String htmlText = "這是<b>粗體</b>文本,這是<i>斜體</i>文本,<font color='red'>紅色文字</font>";
textView.setText(Html.fromHtml(htmlText, Html.FROM_HTML_MODE_COMPACT));
// 自定義 HTML 標(biāo)簽處理
Html.ImageGetter imageGetter = new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
// 處理圖片
return null;
}
};
Html.TagHandler tagHandler = new Html.TagHandler() {
@Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
// 處理自定義標(biāo)簽
}
};
6. 自動(dòng)鏈接識(shí)別
6.1 XML 配置
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:autoLink="all" <!-- 識(shí)別所有類型鏈接 -->
android:linksClickable="true"
android:text="官網(wǎng): https://www.example.com
郵箱: test@example.com
電話: 13800138000
地址: 北京市朝陽區(qū)" />
autoLink 選項(xiàng):
-
none- 不自動(dòng)識(shí)別 -
web- 識(shí)別網(wǎng)址 -
email- 識(shí)別郵箱 -
phone- 識(shí)別電話 -
map- 識(shí)別地址 -
all- 識(shí)別所有類型
6.2 代碼配置
textView.setAutoLinkMask(Linkify.ALL);
textView.setLinksClickable(true);
// 自定義鏈接識(shí)別
Linkify.addLinks(textView, Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES);
// 自定義正則表達(dá)式匹配
Pattern pattern = Pattern.compile("#\\w+");
Linkify.addLinks(textView, pattern, "content://com.example.app/tag/");
7. 自定義字體和樣式
7.1 使用 Assets 中的字體
// 方法1:通過 Typeface
Typeface typeface = Typeface.createFromAsset(getAssets(), "fonts/custom_font.ttf");
textView.setTypeface(typeface);
// 方法2:通過 ResourcesCompat(推薦)
Typeface typeface = ResourcesCompat.getFont(this, R.font.custom_font);
textView.setTypeface(typeface);
7.2 字體樣式組合
// 設(shè)置粗體
textView.setTypeface(null, Typeface.BOLD);
// 設(shè)置斜體
textView.setTypeface(null, Typeface.ITALIC);
// 粗斜體
textView.setTypeface(null, Typeface.BOLD_ITALIC);
8. 文本選擇和復(fù)制
8.1 啟用文本選擇
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:selectAllOnFocus="true"
android:text="可以選擇和復(fù)制的文本" />
8.2 自定義選擇操作
textView.setCustomSelectionActionModeCallback(new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// 創(chuàng)建自定義菜單
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// 準(zhǔn)備菜單
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// 處理菜單項(xiàng)點(diǎn)擊
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
// 銷毀模式
}
});
9. 陰影和視覺效果
9.1 文本陰影
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="帶陰影的文本"
android:shadowColor="#80000000"
android:shadowDx="2" <!-- X軸偏移 -->
android:shadowDy="2" <!-- Y軸偏移 -->
android:shadowRadius="4" <!-- 陰影模糊半徑 -->
android:textColor="#FFFFFF" />
9.2 代碼設(shè)置陰影
textView.setShadowLayer(4, 2, 2, Color.parseColor("#80000000"));
10. 國際化支持
10.1 多語言支持
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<!-- 在 res/values/strings.xml -->
<string name="hello_world">Hello World!</string>
<!-- 在 res/values-zh/strings.xml -->
<string name="hello_world">你好世界!</string>
10.2 RTL(從右到左)支持
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textDirection="locale" <!-- 跟隨系統(tǒng)語言方向 -->
android:textAlignment="viewStart" />
11. 性能優(yōu)化技巧
11.1 減少過度繪制
<!-- 避免不必要的背景 -->
<TextView
android:background="@null" />
<!-- 使用 selector 代替代碼設(shè)置背景 -->
<TextView
android:background="@drawable/text_bg_selector" />
11.2 文本測量優(yōu)化
// 預(yù)計(jì)算文本尺寸
TextPaint textPaint = textView.getPaint();
float textWidth = textPaint.measureText(textView.getText().toString());
float textHeight = textPaint.getFontMetrics().bottom - textPaint.getFontMetrics().top;
// 對于固定文本,設(shè)置固定尺寸
textView.setWidth((int) textWidth);
textView.setHeight((int) textHeight);
12. 實(shí)用工具方法
12.1 工具類示例
public class TextViewUtils {
// 設(shè)置文本并保持滾動(dòng)位置
public static void setTextKeepState(TextView textView, String text) {
int scrollX = textView.getScrollX();
int scrollY = textView.getScrollY();
textView.setText(text);
textView.scrollTo(scrollX, scrollY);
}
// 高亮特定關(guān)鍵詞
public static void highlightText(TextView textView, String keyword, int color) {
String text = textView.getText().toString();
SpannableString spannable = new SpannableString(text);
Pattern pattern = Pattern.compile(Pattern.quote(keyword));
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
spannable.setSpan(
new ForegroundColorSpan(color),
matcher.start(),
matcher.end(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
}
textView.setText(spannable);
}
// 為 TextView 添加圖標(biāo)
public static void setCompoundDrawable(TextView textView,
@DrawableRes int drawableRes,
int position) {
Drawable drawable = ContextCompat.getDrawable(textView.getContext(), drawableRes);
if (drawable != null) {
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
}
switch (position) {
case 0: // left
textView.setCompoundDrawables(drawable, null, null, null);
break;
case 1: // top
textView.setCompoundDrawables(null, drawable, null, null);
break;
case 2: // right
textView.setCompoundDrawables(null, null, drawable, null);
break;
case 3: // bottom
textView.setCompoundDrawables(null, null, null, drawable);
break;
}
}
}
13. 常見問題解決
13.1 文本顯示不全
<!-- 解決方案 -->
<TextView
android:layout_width="0dp" <!-- 使用 ConstraintLayout 時(shí) -->
android:layout_height="wrap_content"
android:maxLines="2"
android:ellipsize="end" />
13.2 鏈接點(diǎn)擊無效
// 需要設(shè)置 MovementMethod
textView.setMovementMethod(LinkMovementMethod.getInstance());
13.3 自定義字體內(nèi)存泄漏
// 使用 Application Context 或緩存 Typeface
public class FontCache {
private static Hashtable<String, Typeface> fontCache = new Hashtable<>();
public static Typeface get(String name, Context context) {
Typeface tf = fontCache.get(name);
if (tf == null) {
try {
tf = Typeface.createFromAsset(context.getAssets(), name);
fontCache.put(name, tf);
} catch (Exception e) {
return null;
}
}
return tf;
}
}
TextView 是 Android 開發(fā)中最基礎(chǔ)且功能豐富的組件之一,掌握其各種用法對于開發(fā)高質(zhì)量的 Android 應(yīng)用至關(guān)重要。