Android TextView 的基本使用方法和常用功能

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)重要。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容