문자열 리소스에서 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로 반환됩니다. 그러나 그것을 String으로 변환하자마자 마술은 사라집니다.
— Thilo-Alexander Ginkel

답변:


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

5
기본적으로 사용되는 것과 일치하도록 textView의 스타일을 어떻게 설정 하시겠습니까?
— 안드로이드 개발자

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
건배, 내에서 나를 위해 일 onCreateDialog했다 DialogFragment. 그냥에서 클릭 할 수있는 코드를 설정했다 onStart주어진 showDialogFragment 호출하기 위해 부름받은
— PJL

5
이것은 링크가 아닌 전체 TextView를 클릭 할 수있게 만드는 것 같습니다.
— Kavi

1
원래 답변이 대화 상자를 시각적으로 망쳐 놓기 때문에 이것이 훨씬 더 나은 옵션이라는 데 동의합니다.
— hcpl

1
findViewById에 의해 리턴 된 뷰는 구현이 변경되지 않을 것이라는 보장이 없으므로 "instanceof TextView"로 점검해야합니다.
— Denis Gladkiy

6
다른 곳에서 지적 setMessage(R.string.something)했듯이을 사용하는 경우 명시 적으로 연결할 필요가 없습니다. create()호출하기 전에 AlertDialog 객체가 필요하지 않으며 show()(Builder 에서 호출 할 수 있음) show()대화 상자 객체를 반환 findViewById(android.R.id.message)하므로 체인 될 수 있습니다. 메시지보기가 TextView가 아니고 간결한 공식이있는 경우를 대비하여 try-catch로 모두 래핑하십시오.
— Pierre-Luc Paour

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

2
사실입니다. 두 메소드 (Html.fromHtml 및 strings.xml의 HTML 태그)를 결합하면 작동하지 않습니다.
— JerabekJakub

오래 전부터 fromHtml은 더 이상 사용되지 않습니다.
— Menasheh

: 당신은 여전히 fromHtml 사용할 수 있습니다 developer.android.com/reference/android/text/... 간단히 사용), 지능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

기본과 같이 스크롤되지 않습니다.
— Meow Cat 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을 클릭 가능한 URL로 표시합니다.


5

나는 현재 답변에 실제로 만족하지 않았습니다. AlertDialog를 사용하여 href 스타일에서 클릭 가능한 하이퍼 링크를 원할 때 중요한 두 가지가 있습니다.

  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

@ bk138 onStart ()에서 .setMovementMethod ()를 호출하면 링크를 클릭 할 수있게됩니다.
— tronman

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 참조)을 참조하십시오 . 자바 코드의 관련 부분 :

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에서이 작업을 수행하는 방법을 알려주시겠습니까?
— 토마스 윌리엄

미안 해요. 나는 Kotlin
— Javier Castellanos Cruz를
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.