文字列リソースからAlertDialogのクリック可能なハイパーリンクを取得するにはどうすればよいですか?


134

私が達成しようとしているのは、によって表示されるメッセージテキストにクリック可能なハイパーリンクを含めることですAlertDialog。一方でAlertDialog、実装は喜んで下線や色のハイパーリンク(使用して定義された<a href="...">文字列リソースにはに渡されたBuilder.setMessage)供給のリンクがクリック可能になりません。

私が現在使用しているコードは次のようになります。

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テキストスニペットを表示するためだけに使用することは避けたいです。


こんにちは!宣言された結果を実際に達成しますか(「ハイパーリンクに下線を付けて、ハイパーリンクに色を付けます」)。どの文字列値を渡しますか?
Maksym Gontar

1
はい、重要なのは、メッセージを文字列リソースに表示することです。Resources.getText(...)は、HTML形式を保持したままandroid.text.Spannedとして返します。しかし、それを文字列に変換するとすぐに、魔法は消えます。
Thilo-Alexander Ginkel、2010年

回答:


128

ダイアログにいくつかのテキストとURLのみを表示している場合、おそらく解決策はより簡単です。

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

クリック可能なリンクを含む警告ダイアログ


1
おそらく、レイアウトファイルを作成し、それを膨らませて、ビューとして使用したいと思うでしょう。
Jeffrey Blattman、2012年

5
デフォルトで使用されているスタイルと一致するように、textViewのスタイルをどのように設定しますか?
Android開発者

3
次に、エラーが発生しますCalling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
ViliusK

207

ダイアログ内のメッセージのフォーマットが大幅に変更されるため、現在最も人気のある回答はあまり好きではありませんでした。

以下は、テキストのスタイルを変更せずにダイアログテキストをリンクするソリューションです。

    // 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());

5
乾杯、内から私のために働きましonCreateDialogDialogFragment。DialogFragmentを呼び出すために呼び出されたクリック可能なコードを設定onStartするshow必要がありました
PJL

5
これにより、リンクだけではなく、TextView全体がクリック可能になります...これを回避する方法はありますか?
カビ2012年

1
元の答えはダイアログを視覚的に混乱させるため、これははるかに優れたオプションであることに同意します。
hcpl 2012年

1
findViewByIdによって返されるビューは、「instanceof TextView」でチェックする必要があります。実装が変更されないという保証はありません。
Denis Gladkiy 2014年

6
他の場所で指摘したように、を使用する場合setMessage(R.string.something)、明示的にリンクする必要はありません。またcreate()、AlertDialogオブジェクトを呼び出す前に必要なくshow()(Builderで呼び出すことができます)、show()ダイアログオブジェクトを返すため、findViewById(android.R.id.message)をチェーンできます。メッセージビューがTextViewではなく、簡潔な定式化がある場合に備えて、すべてをtry-catchでラップします。
Pierre-Luc Paour 14

50

これにより、<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());

10
strings.xmlでhtmlを使用する場合、Html.fromHtmlを使用する必要はありません。setMessage(R.string.cool_link)使用<string name="cool_link"><a href="http://www.google.com">Check this link out</a></string>
idbrii '06 / 06/17

2
それは本当です。両方のメソッド(Html.fromHtmlとstrings.xmlのHTMLタグ)を組み合わせると機能しません。
JerabekJakub 14

しばらくしてfromHtmlは非推奨になりましたが、今はどうですか?
Menasheh

引き続きfromHtmlを使用できます:developer.android.com/reference/android/text/…、int)単に使用するHtml.fromHtml("string with links", Html.FROM_HTML_MODE_LEGACY)
BVB

2
setMovementMethod()ここで重要な部分です。それ以外の場合、URLをクリックできません。
scai

13

実際、すべてのビューを処理せずに単に文字列を使用したい場合、最も速い方法はメッセージのテキストビューを見つけてリンクすることです:

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

12

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())を実行することです。


ありがとう、これで問題は解決しました。私の場合、それは必要だったsetLinksClickable(true)(私はそれがすでにそうだったと思う)必要はありませんでしたがsetMovementMethod(...)、すべての違いを作り出しました。
LarsH 2016年

10

の代わりに ...

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);

ねえ、あなたのソルンは動作します。リンクをクリックしてもテキストビュー全体が点滅する理由を知っていますか?
aimango 2012年

デフォルトのようにスクロールしません。
ニャー猫2012年

7

最も簡単な方法:

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());

6

上記のすべての答えは、などの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();

そしてcustom_dialogは次のようになります。

<?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タグを削除し、指定されたhtml形式のテキスト内の他のすべての例をクリック可能URLとして表示します。


5

現在の答えには本当に満足していませんでした。AlertDialogを使用してhrefスタイルのクリック可能なハイパーリンクが必要な場合、2つの重要な点があります。

  1. ビューsetMessage(…)だけがクリック可能なHTMLコンテンツを許可するため、コンテンツをではなく、ビューとして設定します。
  2. 正しい移動方法を設定(setMovementMethod(…)

以下は、機能する最小限の例です。

strings.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()
}

3

多くの質問と回答を確認しましたが、うまくいきません。私はそれを自分でやりました。これは、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 \ values \ String.xmlに配置します

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

2

上記で説明したオプションのいくつかを組み合わせて、この機能を使用できるようにしました。結果をダイアログビルダーの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;
}

2

を使用している場合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());
    }
}

SpannableStringをダイアログのメッセージとして設定すると、リンクは強調表示されますが、クリックできません。
bk138 2017年

@ bk138 onStart()で.setMovementMethod()を呼び出すと、リンクがクリック可能になります。
トロンマン2017年

2

私にとってプライバシーポリシーダイアログを作成する最善の解決策は次のとおりです。

    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());
    }
}

実際の例を確認してください:アプリのリンク


1

これを行うには、XMLリソースでアラートボックスを指定し、それをロードします。たとえば、ChandlerQE.javaの終わり近くでインスタンス化されるabout.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)

リンクが死んでいる、あなたはそれを修正できますか?
Bijoy Thangaraj

1

これが私の解決策です。これは、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());

1
ありがとう、setSpan(URL、startPoint、endPoint、Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)を追加するだけです。ここで、startPointとendPointは、クリックして強調表示される単語です
Manish

0

最も簡単で最短の方法はこのようなものです

ダイアログの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());

Kotlinでこれを行う方法を教えていただけますか?
トーマスウィリアムズ

ごめんなさい。コトリンがわかりません
ハビエルカステ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.