在Android中,有没有办法使AlertDialog
中的文本"可选择"或"可复制"? 或者我必须使用其他小部件来替代AlertDialog
?
有几种方法可以实现此目的。但首先,要更改对话框的外观,您需要使用 AlertDialog.Builder
-class 来创建自定义对话框。然后,可以通过添加自己的 View
来填充它。
以下是三种实现可选文本的方法:
自API-Level 11(Android 3.0)以来, TextView
具有一个名为setTextIsSelectable()
的方法,该方法看起来与我下面详细介绍的操作类似。
// The TextView to show your Text
TextView showText = new TextView(this);
showText.setText("Some selectable text goes here.");
showText.setTextIsSelectable(true);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
// Build the Dialog
builder.setView(showText)
.setTitle("Selectable text")
.setCancelable(true)
.show();
这种解决方案的问题是,它只能在运行 Android 3.0 及更高版本的设备上工作,而其他两种解决方案也可以在 Android 1.5 上使用(我使用的是 Android 2.2)。
由于标记文本的目的(大多数情况下)是为了复制它,因此您可以简单地为 TextView
添加一个 onLongClickListener
或一个简单的 onClickListener
(您最喜欢的那个),并将其显示文本复制到系统剪贴板中。
这是一个简单的示例:
// Get our tools
AlertDialog dialog;
AlertDialog.Builder builder;
// The TextView to show your Text
TextView showText = new TextView(this);
showText.setText("Some selectable text goes here.");
// Add the Listener
showText.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// Copy the Text to the clipboard
ClipboardManager manager =
(ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
TextView showTextParam = (TextView) v;
manager.setText( showTextParam.getText() );
// Show a message:
Toast.makeText(v.getContext(), "Text in clipboard",
Toast.LENGTH_SHORT)
.show();
return true;
}
});
// Build the Dialog
builder = new AlertDialog.Builder(this);
builder.setView(showText);
dialog = builder.create();
// Some eye-candy
dialog.setTitle("Selectable text");
dialog.setCancelable(true);
dialog.show();
这个例子将把系统剪贴板中显示的所有文本复制下来。
EditText
看起来像TextView
由于在Android 3.0之前的版本上,没有一个真正简单的方法可以使TextView
的文本可选。因此,您可以使用一个EditText
(默认情况下具有可选择的文本),并使其看起来像一个TextView
。
这需要一些XML布局(以获取TextView
的样式),但可能会为您提供最本地的外观和体验:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- Make the EditText look like a TextView -->
<EditText android:id="@+id/showText"
style="?android:attr/textViewStyle"
android:background="@null"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
// Get our tools
AlertDialog dialog;
AlertDialog.Builder builder;
// The EditText to show your Text
LayoutInflater inflater =
(LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.dialog,
(ViewGroup) this.findViewById(R.id.showText));
EditText showText = (EditText) layout.findViewById(R.id.showText);
showText.setText("Some selectable text goes here.");
// Build the Dialog
builder = new AlertDialog.Builder(this);
builder.setView(layout);
dialog = builder.create();
// Some eye-candy
dialog.setTitle("Selectable text");
dialog.setCancelable(true);
dialog.show();
结果可能会添加一些自定义和视觉效果 ;)
希望这给你提供了如何完成此任务的想法。现在已经晚了,该睡觉了。
这个方法有点巧妙,因为它假定您知道默认的AlertDialog布局(请参见在哪里可以找到默认的AlertDialog布局xml文件?),但是如果您想走这条路,您可以按照以下步骤进行:
alertDialog.show();
try {
TextView textView = (TextView)dialog.getWindow().getDecorView().findViewById(android.R.id.message);
textView.setTextIsSelectable(true);
}
catch(Exception e) {
// Oups!
}
我知道这是一个老问题,但这是我迄今为止使用过的最佳解决方案:
//..... creating the AlertDialog and showing it.
dialog.show();
// after showing it, we fetch the message TextView container
View messageView = dialog.findViewById(android.R.id.message);
if (messageView instanceof TextView) {
((TextView) messageView).setTextIsSelectable(true);
}
如果您正在使用MaterialAlertDialog,您可以轻松更新样式。
materialAlertDialogTheme
设置为MyMaterialAlertDialog
。 <style name="MyActivityOrDialogTheme" parent="Theme.Material3.DayNight.NoActionBar">
...
<item name="materialAlertDialogTheme">@style/MyMaterialAlertDialog</item>
...
</style>
materialAlertDialogBodyTextStyle
设置为MyMaterialAlertDialogBodyTextStyle
。 <style name="MyMaterialAlertDialog" parent="ThemeOverlay.Material3.MaterialAlertDialog">
<item name="materialAlertDialogBodyTextStyle">@style/MyMaterialAlertDialogBodyTextStyle</item>
</style>
android:textIsSelectable
属性更新为 true
。 <style name="MyMaterialAlertDialogBodyTextStyle" parent="MaterialAlertDialog.Material3.Body.Text">
<item name="android:textIsSelectable">true</item>
</style>
findViewById(android.R.id.message)
解决方案对于MaterialAlertDialog
不起作用。 - Smart Coding