Bir dize kaynağından AlertDialog'da tıklanabilir köprüleri nasıl alabilirim?


134

Başarmaya çalıştığım şey, bir .tarafından görüntülenen mesaj metninde tıklanabilir köprülere sahip olmaktır AlertDialog. İken AlertDialoguygulama mutlu Altıçizgili ve renkleri herhangi köprüler (kullanılarak tanımlanır <a href="...">dize kaynak aktarılan Builder.setMessage) verilen bağlantılar tıklanabilir hale gelmez.

Şu anda kullandığım kod şuna benziyor:

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

WebViewBir metin parçacığını görüntülemek için a kullanmaktan kaçınmak istiyorum .


Selam! Bildirilen sonuçları gerçekten elde ediyor musunuz ("herhangi bir köprünün altını mutlu bir şekilde çizer ve renklendirir")? Hangi dize değerini iletiyorsunuz?
Maksym Gontar

1
Evet, anahtar mesajın, Resources.getText (...) HTML biçimlendirmesini koruyarak android.text.Spanned olarak döndürdüğü bir dize kaynağında görüntülenmesini sağlamaktır. Onu bir String'e dönüştürdüğünüz anda, sihir kaybolur.
Thilo-Alexander Ginkel

Yanıtlar:


128

Diyaloğunuzda yalnızca bazı metinler ve URL'ler gösteriyorsanız, çözüm belki de daha basittir

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

Burada gösterildiği gibi http://picasaweb.google.com/lh/photo/up29wTQeK_zuz-LLvre9wQ?feat=directlink

Tıklanabilir bağlantılar içeren uyarı iletişim kutusu


1
muhtemelen bir düzen dosyası oluşturmak ve onu şişirmek ve görünüm olarak kullanmak istersiniz.
Jeffrey Blattman

5
TextView stilini varsayılan olarak kullanılanla eşleşecek şekilde nasıl ayarlarsınız?
android geliştiricisi

3
Ardından, hata alıyorumCalling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
ViliusK

207

Şu anda en popüler yanıtı gerçekten beğenmedim çünkü iletişim kutusundaki mesajın biçimini önemli ölçüde değiştirdi.

Metin stilini başka türlü değiştirmeden diyalog metninizi birbirine bağlayacak bir çözüm:

    // 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
Şerefe, içinden benim için çalıştı onCreateDialoga DialogFragment. DialogFragment'ı çağırmak için çağrılan onStartverilen tıklanabilir kodu ayarlamak showzorunda kaldım
PJL

5
Bu, yalnızca bağlantıların aksine tüm TextView'ı tıklanabilir hale getiriyor gibi görünüyor ... Bunun etrafında herhangi bir yol var mı?
Kavi

1
Orijinal yanıt iletişim kutusunu görsel olarak bozduğu için bunun çok daha iyi bir seçenek olduğuna katılıyorum.
hcpl

1
FindViewById tarafından döndürülen görünüm, uygulamanın değişmeyeceğine dair bir garanti olmadığından "TextView örneği" ile kontrol edilmelidir.
Denis Gladkiy

6
Başka bir yerde belirtildiği gibi, kullanılıyorsa setMessage(R.string.something), açıkça bağlantı kurmak gerekli değildir. create()Çağrı yapmadan önce AlertDialog nesnesine de gerek yoktur show()(Builder'da çağrılabilir) ve show()diyalog nesnesini döndürdüğü için findViewById(android.R.id.message)zincirlenebilir. Mesaj görünümünün bir TextView olmaması ve kısa bir formülasyonunuz olması durumunda hepsini bir dene-yakalamaya sarın.
Pierre-Luc Paour

50

Bu, <a href>etiketlerin de vurgulanmasını sağlamalıdır . Lütfen emmby'nin koduna birkaç satır eklediğimi unutmayın. bu yüzden ona şükret

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'de html kullanırsanız, Html.fromHtml kullanmanız gerekmez. setMessage(R.string.cool_link)ile çalışır<string name="cool_link"><a href="http://www.google.com">Check this link out</a></string>
idbrii

2
Bu doğru. Her iki yöntemi de (strings.xml'deki Html.fromHtml ve HTML etiketi) birleştirdiğinizde çalışmaz.
JerabekJakub

Bir süredir ve fromHtml kullanımdan kaldırıldı, şimdi ne olacak?
Menasheh

Html'den kullanmaya devam edebilirsiniz: developer.android.com/reference/android/text/… , int) Basitçe kullanınHtml.fromHtml("string with links", Html.FROM_HTML_MODE_LEGACY)
BVB

2
setMovementMethod()buradaki önemli kısımdır, aksi takdirde URL tıklanabilir olmayacaktır.
scai

13

Aslında, tüm görünümlerle uğraşmadan bir dizeyi kullanmak istiyorsanız, en hızlı yol mesaj metni görünümünü bulmak ve onu bağlamaktır:

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

12

JFTR, işte bir süre sonra anladığım çözüm:

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 kaynaklarından bir parça olarak ödünç alınan karşılık gelen about.xml şu şekilde görünür:

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

Önemli kısımlar, linksClickable'ı true ve setMovementMethod (LinkMovementMethod.getInstance ()) olarak ayarlamaktır.


Teşekkür ederim, bu benim için sorunu çözdü. Benim durumumda gerekli değildi setLinksClickable(true)(sanırım zaten öyleydi), ama setMovementMethod(...)her şeyi değiştirdi.
LarsH

10

Onun yerine ...

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

... şimdi kullanıyorum:

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

Hey, soln çalışıyorsun. Bağlantıya tıklandığında tüm metin görünümünün neden yanıp söndüğünü biliyor musunuz?
aimango

Varsayılanın yaptığı gibi kaymaz.
Miyav Kedi 2012

7

En basit yol:

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

Yukarıdaki cevapların tümü, vb. Gibi html etiketini kaldırmaz, eğer verilen dize içeriyorsa, tüm etiketleri kaldırmaya çalıştım ve bu benim için iyi çalışıyor

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

ve custom_dialog şöyle olacaktır;

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

Yukarıdaki kod, tüm html etiketini kaldıracak ve Örnek olarak, belirtilen html biçimlendirme metnindeki diğerlerinin tümü Tıklanabilir URL olarak gösterilecektir.


5

Mevcut cevaplardan gerçekten memnun değildim. Bir AlertDialog ile href tarzında tıklanabilir köprüler istediğinizde önemli olan iki şey vardır:

  1. setMessage(…)Yalnızca Görünümler tıklanabilir HTML içeriğine izin verdiğinden, içeriği Görünüm olarak ayarlayın, ile değil
  2. Doğru hareket yöntemini ayarlayın ( setMovementMethod(…))

İşte çalışan asgari bir örnek:

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

Birçok soru ve cevabı kontrol ettim ama işe yaramıyor. Ben kendim yaptım. Bu, MainActivity.java'daki kod parçacığıdır.

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

    ....
}

Bu etiketi res \ values ​​\ String.xml'ye yerleştirin

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

2

Benim için çalışan bu işlevi bulmak için yukarıda tartışılan seçeneklerden bazılarını birleştirdim. sonucu iletişim kutusu oluşturucunun SetView () yöntemine iletin.

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

Bir kullanıyorsanız DialogFragment, bu çözüm yardımcı olmalıdır.

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'i iletişim kutusunun mesajı olarak ayarlarsanız, bağlantı vurgulanır, ancak tıklanamaz.
bk138

@ bk138 onStart () içindeki .setMovementMethod () çağrısı, bağlantıyı tıklanabilir yapan şeydir.
tronman

2

Benim için gizlilik politikası iletişim kutusu oluşturmanın en iyi çözümü şudur:

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

çalışan örneği kontrol edin: uygulama bağlantısı


1

Bunu bir XML kaynağındaki uyarı kutusunu belirleyip yükleyerek yapıyorum. Örneğin bakınız about.xml sonuna yakın örneği alır (ABOUT_URL id bakınız) ChandlerQE.java . Java kodunun ilgili bölümleri:

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)

bağlantı öldü, düzeltebilir misin?
Bijoy Thangaraj

1

Bu benim çözümüm. Html etiketleri içermeyen ve görünür hiçbir URL olmadan normal bir bağlantı oluşturur. Aynı zamanda tasarımı sağlam tutar.

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
Teşekkürler, sadece setSpan (URL, startPoint, endPoint, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) eklemek için. Burada startPoint ve endPoint, tıklandığında vurgulanacak olan kelimelerdir
Manish

0

En kolay ve en kısa yol böyledir

İletişim kutusundaki Android bağlantısı

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

Bunu Kotlin'de nasıl yapacağımı bana söyleyebilir misin?
Thomas Williams

Üzgünüm. Kotlin'i bilmiyorum
Javier Castellanos Cruz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.