Bagaimana saya bisa mendapatkan hyperlink yang dapat diklik di AlertDialog dari sumber daya string?


134

Apa yang saya coba capai adalah memiliki hyperlink yang dapat diklik dalam teks pesan yang ditampilkan oleh AlertDialog. Sementara AlertDialogimplementasi dengan senang hati menggarisbawahi dan mewarnai hyperlink apa pun (didefinisikan menggunakan <a href="...">sumber daya yang diteruskan ke string Builder.setMessage) yang disediakan tautan tidak menjadi dapat diklik.

Kode yang saya gunakan saat ini terlihat seperti ini:

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

Saya ingin menghindari menggunakan WebViewhanya menampilkan cuplikan teks.


Hai! Apakah Anda benar-benar mencapai hasil yang dinyatakan ("dengan senang hati menggarisbawahi dan mewarnai hyperlink")? Nilai string apa yang Anda lewatkan?
Maksym Gontar

1
Ya, kuncinya adalah memiliki pesan untuk ditampilkan dalam sumber daya string, yang Resources.getText (...) kembali sebagai android.text. Direncanakan mempertahankan format HTML. Namun, segera setelah Anda mengonversinya menjadi sebuah String, sihirnya lenyap.
Thilo-Alexander Ginkel

Jawaban:


128

Jika Anda hanya menampilkan beberapa teks dan URL dalam dialog Anda, mungkin solusinya lebih sederhana

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

Seperti yang ditunjukkan di sini http://picasaweb.google.com/lh/photo/up29wTQeK_zuz-LLvre9wQ?feat=directlink

Dialog peringatan dengan tautan yang dapat diklik


1
Anda mungkin ingin membuat file tata letak dan mengembang dan menggunakannya sebagai tampilan.
Jeffrey Blattman

5
Bagaimana Anda mengatur gaya textView agar sesuai dengan yang digunakan secara default?
pengembang android

3
Lalu, saya mendapatkan kesalahanCalling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
ViliusK

207

Saya tidak terlalu menyukai jawaban yang paling populer saat ini karena itu secara signifikan mengubah format pesan dalam dialog.

Berikut adalah solusi yang akan menautkan teks dialog Anda tanpa mengubah gaya teks:

    // 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
Ceria, Bekerja untuk saya dari dalam onCreateDialogdari DialogFragment. Hanya harus menetapkan kode yang dapat diklik pada onStartdiberikan yang showtelah dipanggil untuk memohon DialogFragment
PJL

5
Ini tampaknya membuat seluruh TextView dapat diklik sebagai lawan dari hanya tautan ... Ada cara lain untuk mengatasi ini?
Kavi

1
Saya setuju ini adalah pilihan yang jauh lebih baik karena jawaban aslinya mengacaukan dialog secara visual.
hcpl

1
Tampilan dikembalikan oleh findViewById harus diperiksa dengan "instanceof TextView", karena tidak ada jaminan bahwa implementasi tidak akan berubah.
Denis Gladkiy

6
Seperti yang ditunjukkan di tempat lain, jika menggunakan setMessage(R.string.something), tidak perlu untuk secara eksplisit menghubungkan. Ini juga tidak perlu ke create()objek AlertDialog sebelum memanggil show()(dapat dipanggil pada Builder), dan karena itushow() mengembalikan objek dialog, maka findViewById(android.R.id.message)bisa dirantai. Bungkus semuanya dalam try-catch kalau-kalau tampilan pesan bukan TextView, dan Anda memiliki formulasi ringkas.
Pierre-Luc Paour

50

Ini juga harus membuat <a href>tag untuk disorot. Harap dicatat bahwa saya baru saja menambahkan beberapa baris ke kode emmby. begitu memuji dia

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
Jika Anda menggunakan html di strings.xml, Anda tidak perlu menggunakan Html.fromHtml. setMessage(R.string.cool_link)bekerja dengan<string name="cool_link"><a href="http://www.google.com">Check this link out</a></string>
idbrii

2
Itu benar. Ketika Anda menggabungkan kedua metode (Html.fromHtml dan tag HTML di strings.xml) itu tidak berfungsi.
JerabekJakub

Sudah lama dan fromHtml sudah usang, sekarang apa?
Menasheh

Anda masih dapat menggunakan fromHtml: developer.android.com/reference/android/text/… , int) Cukup gunakanHtml.fromHtml("string with links", Html.FROM_HTML_MODE_LEGACY)
BVB

2
setMovementMethod()adalah bagian penting di sini, jika tidak URL tidak akan dapat diklik.
scai

13

Sebenarnya, jika Anda hanya ingin menggunakan string tanpa berurusan dengan semua tampilan, cara tercepat adalah menemukan textview pesan dan menautkannya:

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

12

JFTR, inilah solusi yang saya temukan setelah beberapa waktu:

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

About.xml yang sesuai dipinjam sebagai fragmen dari sumber Android terlihat seperti ini:

<?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>

Bagian-bagian penting adalah pengaturan linksClickable ke true dan setMovementMethod (LinkMovementMethod.getInstance ()).


Terima kasih, ini menyelesaikan masalah untuk saya. Dalam kasus saya, itu tidak perlu setLinksClickable(true)(saya kira sudah), tetapi setMovementMethod(...)membuat semua perbedaan.
LarsH

10

Dari pada ...

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

... Saya sekarang menggunakan:

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

Hei, perusahaanmu bekerja. apakah Anda tahu mengapa seluruh tampilan teks berkedip saat mengklik tautan?
aimango

Itu tidak gulir seperti yang default.
Kucing Meow 2012

7

Cara termudah:

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

Semua jawaban di atas tidak akan menghapus tag html seperti, dll jika string yang diberikan berisi, saya mencoba untuk menghapus semua tag, dan ini berfungsi dengan baik untuk saya

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

dan custom_dialog akan seperti;

<?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>

Kode di atas akan menghapus semua tag html dan menampilkan Contoh sebagai URL yang dapat diklik, semua yang lain dalam teks format html yang ditentukan.


5

Saya tidak benar-benar puas dengan jawaban saat ini. Ada dua hal yang penting ketika Anda ingin hyperlink yang dapat diklik dalam gaya href dengan AlertDialog:

  1. Tetapkan konten sebagai Tampilan dan bukan dengan setMessage(…), karena hanya Tampilan yang memungkinkan konten HTML yang dapat diklik
  2. Setel metode gerakan yang benar ( setMovementMethod(…))

Berikut adalah contoh minimal yang berfungsi:

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

Saya sudah memeriksa banyak pertanyaan dan jawaban, tetapi tidak berhasil. Saya melakukannya sendiri. Ini adalah cuplikan kode di 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());

    ....
}

Letakkan tag ini di 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

Saya menggabungkan beberapa opsi yang dibahas di atas untuk menghasilkan fungsi yang sesuai untuk saya. meneruskan hasilnya ke metode SetView () pembangun dialog.

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

Jika Anda menggunakan DialogFragment, solusi ini akan membantu.

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

Jika Anda mengatur SpannableString sebagai pesan dialog, tautan disorot, tetapi tidak dapat diklik.
bk138

@ bk138 Panggilan ke .setMovementMethod () di onStart () adalah apa yang membuat tautan dapat diklik.
tronman

2

Bagi saya solusi terbaik untuk membuat dialog kebijakan privasi adalah:

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

periksa contoh yang berfungsi: tautan aplikasi


1

Saya melakukan ini dengan menetapkan kotak peringatan di sumber XML dan memuatnya. Lihat misalnya about.xml (lihat id ABOUT_URL) yang akan dipakai di akhir ChandlerQE.java . Bagian yang relevan dari kode 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)

tautan sudah mati, bisakah Anda memperbaikinya?
Bijoy Thangaraj

1

Ini solusi saya. Ini membuat tautan normal tanpa melibatkan tag html dan tanpa URL apa pun yang terlihat. Itu juga membuat desain tetap utuh.

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
Terima kasih, Hanya untuk menambahkan setSpan (URL, startPoint, endPoint, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE). Di sini startPoint dan endPoint adalah kata-kata yang akan disorot untuk mengklik
Manish

0

Cara termudah dan terpendek adalah seperti ini

Tautan Android dalam dialog

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

Bisakah Anda memberi tahu saya cara melakukan ini di Kotlin?
Thomas Williams

Saya menyesal. Saya tidak tahu Kotlin
Javier Castellanos Cruz
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.