如何从字符串资源获得 AlertDialog 中的可单击超链接?

我试图实现的是在消息文本中有一个由 AlertDialog显示的可点击的超链接。虽然 AlertDialog实现高兴地下划线和着色任何超链接(在传递给 Builder.setMessage的字符串资源中使用 <a href="...">定义)提供的链接不会变得可点击。

我当前使用的代码如下:

new AlertDialog.Builder(MainActivity.this).setTitle(
R.string.Title_About).setMessage(
getResources().getText(R.string.about))
.setPositiveButton(android.R.string.ok, null)
.setIcon(R.drawable.icon).show();

我希望避免使用 WebView仅仅显示文本片段。

88131 次浏览

我通过在 XML 资源中指定警告框并加载。例如,请参见在 Chandler QE.java末尾附近被实例化的 Xml(请参见 ABOUT _ URL id)。Java 代码的相关部分:

LayoutInflater inflater =
(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = (View) inflater.inflate(R.layout.about, null);


new AlertDialog.Builder(ChandlerQE.this)
.setTitle(R.string.about)
.setView(view)

JFTR,这是我花了一段时间想出来的解决方案:

View view = View.inflate(MainActivity.this, R.layout.about, null);
TextView textView = (TextView) view.findViewById(R.id.message);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(R.string.Text_About);
new AlertDialog.Builder(MainActivity.this).setTitle(
R.string.Title_About).setView(view)
.setPositiveButton(android.R.string.ok, null)
.setIcon(R.drawable.icon).show();

从 Android 源代码中借用的对应的 about. xml 片段如下所示:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollView" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:paddingTop="2dip"
android:paddingBottom="12dip" android:paddingLeft="14dip"
android:paddingRight="10dip">
<TextView android:id="@+id/message" style="?android:attr/textAppearanceMedium"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:padding="5dip" android:linksClickable="true" />
</ScrollView>

重要的部分是将 linksClickable 设置为 true 和 setMovementMethod (LinkMovementMethod.getInstance ())。

如果您只在对话框中显示一些文本和 URL [ s ] ,那么解决方案可能更简单

public static class MyOtherAlertDialog {


public static AlertDialog create(Context context) {
final TextView message = new TextView(context);
// i.e.: R.string.dialog_message =>
// "Test this dialog following the link to dtmilano.blogspot.com"
final SpannableString s =
new SpannableString(context.getText(R.string.dialog_message));
Linkify.addLinks(s, Linkify.WEB_URLS);
message.setText(s);
message.setMovementMethod(LinkMovementMethod.getInstance());


return new AlertDialog.Builder(context)
.setTitle(R.string.dialog_title)
.setCancelable(true)
.setIcon(android.R.drawable.ic_dialog_info)
.setPositiveButton(R.string.dialog_action_dismiss, null)
.setView(message)
.create();
}
}

如图所示 Http://picasaweb.google.com/lh/photo/up29wtqek_zuz-llvre9wq?feat=directlink

Alert dialog with clickable links

我结合了上面讨论的一些选项,得出了这个适合我的函数。将结果传递给对话框生成器的 SetView ()方法。

public ScrollView LinkifyText(String message)
{
ScrollView svMessage = new ScrollView(this);
TextView tvMessage = new TextView(this);


SpannableString spanText = new SpannableString(message);


Linkify.addLinks(spanText, Linkify.ALL);
tvMessage.setText(spanText);
tvMessage.setMovementMethod(LinkMovementMethod.getInstance());


svMessage.setPadding(14, 2, 10, 12);
svMessage.addView(tvMessage);


return svMessage;
}

而不是..。

AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.setTitle(R.string.my_title);
dialogBuilder.setMessage(R.string.my_text);

我现在用:

AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.setTitle(R.string.my_title);
TextView textView = new TextView(this);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(R.string.my_text);
dialogBuilder.setView(textView);

我不太喜欢当前最流行的答案,因为它显著改变了对话框中消息的格式。

这里有一个解决方案,它将链接您的对话框文本,而不会改变文本样式:

    // Linkify the message
final SpannableString s = new SpannableString(msg); // msg should have url to enable clicking
Linkify.addLinks(s, Linkify.ALL);


final AlertDialog d = new AlertDialog.Builder(activity)
.setPositiveButton(android.R.string.ok, null)
.setIcon(R.drawable.icon)
.setMessage( s )
.create();


d.show();


// Make the textview clickable. Must be called after show()
((TextView)d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());

实际上,如果您想简单地使用字符串而不处理所有视图,最快的方法是查找消息 textview 并链接它:

d.setMessage("Insert your cool string with links and stuff here");
Linkify.addLinks((TextView) d.findViewById(android.R.id.message), Linkify.ALL);

这将使得 <a href>标记也被突出显示。请注意,我只是在 Emmby 的代码中添加了几行。所以要归功于他

final AlertDialog d = new AlertDialog.Builder(this)
.setPositiveButton(android.R.string.ok, null)
.setIcon(R.drawable.icon)
.setMessage(Html.fromHtml("<a href=\"http://www.google.com\">Check this link out</a>"))
.create();
d.show();
// Make the textview clickable. Must be called after show()
((TextView)d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());

如果给定的字符串包含,所有上面的答案将不会删除 html 标记等,我试图删除所有的标记,这对我来说很好

AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setTitle("Title");


LayoutInflater inflater = (LayoutInflater) ctx.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog, null);


TextView text = (TextView) layout.findViewById(R.id.text);
text.setMovementMethod(LinkMovementMethod.getInstance());
text.setText(Html.fromHtml("<b>Hello World</b> This is a test of the URL <a href=http://www.example.com> Example</a><p><b>This text is bold</b></p><p><em>This text is emphasized</em></p><p><code>This is computer output</code></p><p>This is<sub> subscript</sub> and <sup>superscript</sup></p>";));
builder.setView(layout);
AlertDialog alert = builder.show();

自定义对话框将类似于;

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
>


<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#FFF"
/>
</LinearLayout>

上面的代码将删除所有的 html 标记,并显示示例为 Click able URL 所有其他指定的 html 格式文本。

我对目前的答案不是很满意。如果你想要一个带有 AlertDialog 的 href 风格的可点击超链接,有两点很重要:

  1. 将内容设置为 View,而不是使用 setMessage(…),因为只有视图允许单击 HTML 内容
  2. 设置正确的运动方法(setMovementMethod(…))

下面是一个最简单的例子:

Xml

<string name="dialogContent">
Cool Links:\n
<a href="http://stackoverflow.com">Stackoverflow</a>\n
<a href="http://android.stackexchange.com">Android Enthusiasts</a>\n
</string>

MyActivity.java

…
public void showCoolLinks(View view) {
final TextView textView = new TextView(this);
textView.setText(R.string.dialogContent);
textView.setMovementMethod(LinkMovementMethod.getInstance()); // this is important to make the links clickable
final AlertDialog alertDialog = new AlertDialog.Builder(this)
.setPositiveButton("OK", null)
.setView(textView)
.create();
alertDialog.show()
}
…

我已经检查了很多问题和答案,但它不工作。我自己做的。这是 MainActivity.java 上的代码片段。

private void skipToSplashActivity()
{


final TextView textView = new TextView(this);
final SpannableString str = new SpannableString(this.getText(R.string.dialog_message));


textView.setText(str);
textView.setMovementMethod(LinkMovementMethod.getInstance());


....
}

将此标记放在 res 值 String.xml 上

<string name="dialog_message"><a href="http://www.nhk.or.jp/privacy/english/">NHK Policy on Protection of Personal Information</a></string>

最简单的方法:

final AlertDialog dlg = new AlertDialog.Builder(this)
.setTitle(R.string.title)
.setMessage(R.string.message)
.setNeutralButton(R.string.close_button, null)
.create();
dlg.show();
// Important! android.R.id.message will be available ONLY AFTER show()
((TextView)dlg.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());

如果您使用的是 DialogFragment,这个解决方案应该会有所帮助。

public class MyDialogFragment extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {


// dialog_text contains "This is a http://test.org/"
String msg = getResources().getString(R.string.dialog_text);
SpannableString spanMsg = new SpannableString(msg);
Linkify.addLinks(spanMsg, Linkify.ALL);


AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle(R.string.dialog_title)
.setMessage(spanMsg)
.setPositiveButton(R.string.ok, null);
return builder.create();
}


@Override
public void onStart() {
super.onStart();


// Make the dialog's TextView clickable
((TextView)this.getDialog().findViewById(android.R.id.message))
.setMovementMethod(LinkMovementMethod.getInstance());
}
}

这就是我的解决办法。它创建一个普通的链接,不涉及 html 标记,也不可见任何 URL。它也保持了设计的完整性。

SpannableString s = new SpannableString("This is my link.");
s.setSpan(new URLSpan("http://www.google.com"), 11, 15, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);


AlertDialog.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder = new AlertDialog.Builder(this, android.R.style.Theme_Material_Dialog_Alert);
} else {
builder = new AlertDialog.Builder(this);
}


final AlertDialog d = builder
.setPositiveButton("CLOSE", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Do nothing, just close
}
})
.setNegativeButton("SHARE", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Share the app
share("Subject", "Text");
}
})
.setIcon(R.drawable.photo_profile)
.setMessage(s)
.setTitle(R.string.about_title)
.create();


d.show();


((TextView)d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());

对我来说,创建隐私政策对话框的最佳解决方案是:

    private void showPrivacyDialog() {
if (!PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean(PRIVACY_DIALOG_SHOWN, false)) {


String privacy_pol = "<a href='https://sites.google.com/view/aiqprivacypolicy/home'> Privacy Policy </a>";
String toc = "<a href='https://sites.google.com/view/aiqprivacypolicy/home'> T&C </a>";
AlertDialog dialog = new AlertDialog.Builder(this)
.setMessage(Html.fromHtml("By using this application, you agree to " + privacy_pol + " and " + toc + " of this application."))
.setPositiveButton("ACCEPT", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit().putBoolean(PRIVACY_DIALOG_SHOWN, true).apply();
}
})
.setNegativeButton("DECLINE", null)
.setCancelable(false)
.create();


dialog.show();
TextView textView = dialog.findViewById(android.R.id.message);
textView.setLinksClickable(true);
textView.setClickable(true);
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
}

检查工作示例: 应用程序链接

最简单和最短的方法是这样的

对话框中的 Android 链接

((TextView) new AlertDialog.Builder(this)
.setTitle("Info")
.setIcon(android.R.drawable.ic_dialog_info)
.setMessage(Html.fromHtml("<p>Sample text, <a href=\"http://google.nl\">hyperlink</a>.</p>"))
.show()
// Need to be called after show(), in order to generate hyperlinks
.findViewById(android.R.id.message))
.setMovementMethod(LinkMovementMethod.getInstance());

这是我使用的简单方法

在 Strings.xml 中使用字符串

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="credits_title">Credits</string>
<string name="confirm">OK</string>
<string name="credits">All rights reserved.
<a href="https://google.com">Source</a>
</string>
</resources>

Xml 中的维度

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<dimen name="margin_8dp">8dp</dimen>
<dimen name="margin_32dp">32dp</dimen>
</resources>

帮助对话框类

public class MessageHelper {


public static void showCreditsDialog(Context context) {


AlertDialog alertDialog = new AlertDialog.Builder(context).create();
alertDialog.setTitle(R.string.credits_title);
TextView textView = new TextView(context);
int padding = (int) context.getResources().getDimension(R.dimen.margin_32dp);
int topPadding = (int) context.getResources().getDimension(R.dimen.margin_8dp);
textView.setPadding(padding, topPadding, padding, 0);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(R.string.credits);
alertDialog.setView(textView);


alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, context.getResources().getString(R.string.confirm),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
alertDialog.show();
}
}

怎么用

MessageHelper.showCreditsDialog(this); // this is the context

预览

enter image description here

简单的 Kotlin 实现

字符串资源:

<string name="foo"><a href="https://www.google.com/">some link</a></string>

密码:

AlertDialog.Builder(context)
.setMessage(R.string.foo)
.show()
.apply {
findViewById<TextView>(android.R.id.message)
?.movementMethod = LinkMovementMethod.getInstance()
}

在 AlertDialog 中可单击的超链接

 /*Dialog Agreement*/
private fun agreed() {
if (agreed != "yes") {
val inflater: LayoutInflater = this.layoutInflater
val dialogView: View = inflater.inflate(R.layout.dialog_agreed, null)
val btnAccept: TextView = dialogView.findViewById(R.id.btn_accept)
val btnDecline: TextView = dialogView.findViewById(R.id.btn_decline)
val txtMessage: TextView = dialogView.findViewById(R.id.txt_message)
btnAccept.setOnClickListener {
//Saving data to preference manager
val sharedPref = getSharedPreferences("Janta24", Context.MODE_PRIVATE)
val editor = sharedPref.edit()
editor.putString("agreed", "yes")
editor.apply()
alertDialog.dismiss()
}
btnDecline.setOnClickListener {
finish()
}
txtMessage.text = Html.fromHtml(
"We have revised our<a href=\"http://app.janta24.in/term.html\">Terms of Use</a> & " +
"<a href=\"http://app.janta24.in/privacy.html\">Privacy Policy</a> " +
"By accepting, you agreed to our updated terms and policies. Please take few minutes to read and understand them."
)
txtMessage.movementMethod = LinkMovementMethod.getInstance()
val dialogBuilder: AlertDialog.Builder = AlertDialog.Builder(this)
dialogBuilder.setOnDismissListener { }
dialogBuilder.setView(dialogView)
dialogBuilder.setCancelable(false)
alertDialog = dialogBuilder.create()
alertDialog.show()
}
}