textView.setTextIsSelectable(true) 在小米手機正常顯示選中/複製菜單,但在三星手機(One UI)無反應。
setTextIsSelectable 於 **API 11 (Android 3.0)** 引入,早期版本無效。Editor 類:該類被標註 @hide,非公開 SDK,各廠商(三星、華為、OPPO、vivo)在 ROM 定制時**頻繁修改/替換** Editor 實現,導致行為不一致。Editor 邏輯被繞過或禁用。mEditor 失效:早期通過反射獲取 mEditor 再調用內部方法的方案,在 Android 4.x+ 不同廠商設備上普遍失敗(字段不存在/為 null/方法簽名變更)。android:textIsSelectable="true" XML 屬性(最穩)<TextView
android:id="@+id/tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:longClickable="true" />
XML 屬性在布局加載階段由系統初始化,比運行時調用 API 更早、更穩,受廠商魔改影響最小。
public class SelectableTextView extends androidx.appcompat.widget.AppCompatTextView {
public SelectableTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setTextIsSelectable(true);
setFocusable(true);
setFocusableInTouchMode(true);
setLongClickable(true);
// 關鍵:強制請求焦點,觸發選中模式
setOnLongClickListener(v -> {
v.requestFocus();
return false; // 讓系統繼續處理選中邏輯
});
}
}
Editor、支援自定義操作菜單(翻譯、搜索、分享)。webView.loadDataWithBaseURL(null, "" + htmlContent + "", "text/html", "UTF-8", null);
webView.setOnLongClickListener(v -> true); // 啟用 WebView 內建選中複製
| 機型/系統 | 原生 setTextIsSelectable | XML 屬性 | 自定義長按 | 第三方庫 |
|---|---|---|---|---|
| Pixel (原生 Android) | ✅ | ✅ | ✅ | ✅ |
| 小米 MIUI | ✅ | ✅ | ✅ | ✅ |
| 三星 One UI 4/5/6 | ❌/⚠️ | ✅ | ✅ | ✅ |
| 華為 EMUI/HarmonyOS | ⚠️ | ✅ | ✅ | ✅ |
| OPPO/vivo ColorOS/Funtouch | ⚠️ | ✅ | ✅ | ✅ |
setTextIsSelectable 是**脆弱的原生 API**,強依賴隱藏類 Editor,極易受廠商魔改影響。**首選 XML 屬性 android:textIsSelectable="true" + focusable 組合**;若仍失效,引入成熟第三方富文本庫徹底解決兼容性與功能擴展需求。不要在業務代碼中反射 Editor,維護成本極高且隨系統更新隨時失效。