web-dev-qa-db-fra.com

Comment puis-je obtenir des liens hypertexte cliquables dans AlertDialog à partir d'une ressource chaîne?

Ce que j'essaie d'accomplir est d'avoir des hyperliens cliquables dans le texte du message affichés par un AlertDialog. Alors que l'implémentation AlertDialog souligne et colore avec bonheur tous les liens hypertexte (définis à l'aide de <a href="..."> dans la ressource chaîne transmise à Builder.setMessage) fournis, les liens ne deviennent pas cliquables.

Le code que j'utilise actuellement ressemble à ceci:

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

J'aimerais éviter d'utiliser une WebView pour simplement afficher un extrait de texte.

121

Si vous ne montrez que du texte et des URL [s] dans votre dialogue, la solution est peut-être plus simple.

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

Comme indiqué ici http://picasaweb.google.com/lh/photo/up29wTQeK_zuz-LLvre9wQ?feat=directlink

Alert dialog with clickable links

121

Je n’ai pas vraiment aimé la réponse la plus populaire à l’heure actuelle car elle modifie considérablement le format du message dans la boîte de dialogue.

Voici une solution qui va lier votre texte de dialogue sans changer le style du texte:

    // Linkify the message
    final SpannableString s = new SpannableString(msg);
    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());
193
emmby

Cela devrait faire en sorte que les balises <a href> soient mises en évidence. Veuillez noter que je viens d'ajouter quelques lignes au code d'emmby. alors crédit à lui

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

En fait, si vous voulez simplement utiliser une chaîne sans traiter toutes les vues, le moyen le plus rapide est de trouver le message textview et de le lier:

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

JFTR, voici la solution que j'ai trouvée après un certain temps:

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

Le about.xml correspondant emprunté sous forme de fragment à partir des sources Android ressemble à ceci:

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

Les parties importantes sont la définition de linksClickable sur true et sur setMovementMethod (LinkMovementMethod.getInstance ()).

12

Au lieu de ...

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

... J'utilise maintenant:

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

Toute la réponse ci-dessus ne supprimera pas les balises html comme, etc. si la chaîne donnée en contient, j'ai essayé de supprimer toutes les balises, et cela fonctionne très bien pour moi

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

et le custom_dialog serait comme;

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

Le code ci-dessus supprimera toutes les balises html et affichera Exemple comme URL cliquable tous les autres dans le texte de formatage HTML spécifié.

6
Lakshmanan

Je n'étais pas vraiment satisfait des réponses actuelles. Il y a deux choses importantes lorsque vous voulez des hyperliens cliquables dans le style href avec AlertDialog:

  1. Définissez le contenu en tant que vue et non pas avec setMessage(…), car seules les vues autorisent le contenu HTML cliquable
  2. Définir la méthode de mouvement correcte (setMovementMethod(…))

Voici un exemple de travail minimal:

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()
}
…
5
Flow

J'ai vérifié de nombreuses questions et réponses, mais cela ne fonctionne pas. Je l'ai fait moi-même. Ceci est l'extrait de code sur 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());

    ....
}

Placez cette balise sur 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>
3
Hiroto

Manière la plus simple:

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

Si vous utilisez un DialogFragment, cette solution devrait vous aider.

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

J'ai combiné certaines des options décrites ci-dessus pour créer cette fonction qui fonctionne pour moi. transmettez le résultat à la méthode SetView () du générateur de boîtes de dialogue.

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
Alex

Je le fais en spécifiant le champ d’alerte dans une ressource XML et en le chargeant. Voir par exemple le about.xml (voir l'identifiant ABOUT_URL) qui est instancié vers la fin de ChandlerQE.Java . Les parties pertinentes du code 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)
1
Heikki Toivonen

Pour moi, la meilleure solution pour créer un dialogue de politique de confidentialité est:

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

vérifier l'exemple de travail: lien app

0
Prakash Sharma

Ceci est ma solution. Il crée un lien normal sans balises HTML impliquées et sans aucune URL visible. Il conserve également la conception intacte.

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());
0
John T