문자열 리소스에서 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.