web-dev-qa-db-fra.com

Comment créer des liens dans un TextView cliquable?

J'ai le TextView suivant défini:

<TextView Android:layout_width="wrap_content"
    Android:layout_height="wrap_content" Android:text="@string/txtCredits"
    Android:autoLink="web" Android:id="@+id/infoTxtCredits"
    Android:layout_centerInParent="true"
    Android:linksClickable="true"></TextView>

@string/txtCredits est une ressource chaîne contenant <a href="some site">Link text</a>.

Android met en surbrillance les liens dans TextView, mais ils ne répondent pas aux clics. Est-ce que quelqu'un peut me dire ce que je fais mal? Dois-je définir un onClickListener pour TextView dans mon activité pour quelque chose d'aussi simple que cela?

Cela ressemble à la façon dont je définis ma ressource de chaîne. Cela ne fonctionne pas:

<string name="txtCredits"><a href="http://www.google.com">Google</a></string>

Mais cela fait:

<string name="txtCredits">www.google.com</string>

Ce qui est une déception, car je préférerais de beaucoup montrer un lien texte plutôt que de montrer l’URL complète.

940
Richard

Enfoui dans les démos de l'API, j'ai trouvé la solution à mon problème:

Link.Java:

    // text2 has links specified by putting <a> tags in the string
    // resource.  By default these links will appear but not
    // respond to user input.  To make them active, you need to
    // call setMovementMethod() on the TextView object.

    TextView t2 = (TextView) findViewById(R.id.text2);
    t2.setMovementMethod(LinkMovementMethod.getInstance());

J'ai supprimé la plupart des attributs de mon TextView pour correspondre à ce qui était dans la démo.

<TextView
    Android:id="@+id/text2"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:text="@string/txtCredits"/>

Cela l'a résolu. Assez difficile à découvrir et à réparer.

Important: N'oubliez pas de supprimer autoLink="web" si vous appelez setMovementMethod().

1180
Richard

J'utilise uniquement Android:autoLink="web" et tout fonctionne bien. Un clic sur le lien ouvre le navigateur et affiche la page correcte.

Une chose que je peux deviner, c’est qu’une autre vue est au-dessus du lien. Quelque chose de transparent remplit tout le parent mais n’affiche rien au-dessus du lien. Dans ce cas, le clic va dans cette vue au lieu du lien.

502
Janusz

Après avoir passé du temps avec cela, j'ai constaté que:

  • Android:autoLink="web" fonctionne si vous avez des liens complets dans votre code HTML. Les éléments suivants seront surlignés en bleu et cliquables:
  • Du texte <a href="http://www.google.com">http://www.google.com</a>
  • Du texte http://www.google.com
  • view.setMovementMethod(LinkMovementMethod.getInstance()); fonctionnera avec les éléments suivants (sera mis en évidence et cliquable):
  • Du texte <a href="http://www.google.com">http://www.google.com</a>
  • Du texte http://www.google.com
  • Du texte <a href="http://www.google.com">Go to Google</a>

Notez que la troisième option comporte un lien hypertexte, mais que la description du lien (la partie située entre les balises) n’est pas un lien. Android:autoLink="web" fonctionne PAS avec de tels liens.

  • Android:autoLink="web" s'il est défini en XML remplacera view.setMovementMethod(LinkMovementMethod.getInstance()); (c'est-à-dire que les liens du troisième type seront mis en surbrillance, mais non cliquables).

La morale de l'histoire est d'utiliser view.setMovementMethod(LinkMovementMethod.getInstance()); dans votre code et assurez-vous de ne pas avoir Android:autoLink="web" dans votre présentation XML si vous voulez all les liens doivent être cliquables.

341
Jeshurun

Les solutions ci-dessus ne fonctionnaient pas pour moi, mais les suivantes fonctionnaient (et cela semble un peu plus propre).
Tout d’abord, dans la ressource chaîne, définissez vos chevrons d’ouverture de balises à l’aide du codage d’entités HTML, c’est-à-dire:

&lt;a href="http://www.google.com">Google&lt;/a>

et pas:

<a href="http://www.google.com">Google</a>

En général, encodez tous les chevrons de la chaîne. BTW, le lien doit commencer par http://

Puis (comme suggéré ici ) définissez cette option sur votre TextView:

 Android:linksClickable="true"

Enfin, dans le code, faites:

((TextView) findViewById(R.id.your_text_view)).setMovementMethod(LinkMovementMethod.getInstance());
((TextView) findViewById(R.id.your_text_view)).setText(Html.fromHtml(getResources().getString(R.string.string_with_links)));

C'est ça, pas de regex ou autre bidouillage manuel nécessaire.

92
Blazej Czapp

j'ai utilisé cela simplement

Linkify.addLinks(TextView, Linkify.ALL);

rend les liens cliquables étant donné ici

63
jai_b

Si vous souhaitez ajouter un lien de type HTML, il vous suffit de:

  • ajoutez une ressource de type HTML:

     <string name="link"><a href="https://www.google.pl/">Google</a></string>
    
  • ajoutez votre vue à la présentation avec AUCUNE configuration spécifique au lien:

     <TextView
        Android:id="@+id/link"
        Android:text="@string/link" />`
    
  • ajoutez par défaut ProgramMethod à votre TextView:

     mLink = (TextView) findViewById(R.id.link);
     if (mLink != null) {
       mLink.setMovementMethod(LinkMovementMethod.getInstance());
     }
    

C'est ça! Et oui, avoir des options telles que "autoLink" et "linksClickable" ne fonctionnant que sur des liens explicites (non encapsulés dans des balises html) m’est très trompeur pour moi aussi ...

60
vizZ

J'ai ajouté cette ligne au TextView: Android:autoLink="web"
Voici un exemple d'utilisation dans un fichier de mise en page.

layout.xml exemple

    <TextView
        Android:id="@+id/txtLostpassword"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="center"
        Android:autoLink="email"
        Android:gravity="center"
        Android:padding="20px"
        Android:text="@string/lostpassword"
        Android:textAppearance="?android:attr/textAppearanceSmall" />

    <TextView
        Android:id="@+id/txtDefaultpassword"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="center"
        Android:autoLink="web"
        Android:gravity="center"
        Android:padding="20px"
        Android:text="@string/defaultpassword"
        Android:textAppearance="?android:attr/textAppearanceSmall" />

string.xml

<string name="lostpassword">If you lost your password please contact <a href="mailto:[email protected]?Subject=Lost%20Password" target="_top">[email protected]</a></string>

<string name="defaultpassword">User Guide <a href="http://www.cleverfinger.com.au/user-guide/">http://www.cleverfinger.com.au/user-guide/</a></string>
45
Shanewaj

J'espère que cela vous aidera;

String value = "<html>Visit my blog <a href=\"http://www.maxartists.com\">mysite</a> View <a href=\"sherif-activity://myactivity?author=sherif&nick=king\">myactivity</a> callback</html>";
    TextView text = (TextView) findViewById(R.id.text);


    text.setText(Html.fromHtml(value));
    text.setMovementMethod(LinkMovementMethod.getInstance());
25
Bebin T.N

Seulement ce dont vous avez besoin pour ajouter ceci en mode texte en XML

<TextView
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:autoLink="web"/>
24
Ahmed Mostafa

Richard, la prochaine fois, vous devriez plutôt ajouter ce code sous TextView au format XML.

Android:autoLink="all"

Cela devrait être comme ça.

<TextView 
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content" 
    Android:text="@string/txtCredits"
    Android:id="@+id/infoTxtCredits"
    Android:autoLink="all"
    Android:linksClickable="true">
</TextView>

Vous n'avez pas besoin d'utiliser ce code (t2.setMovementMethod(LinkMovementMethod.getInstance());) pour rendre le lien cliquable.

En outre, voici la vérité: tant que vous définissez le autoLink et le linksClickable , n'oubliez pas d'ajouter ceci dans le fichier String.xml afin que le lien cliquable fonctionne.

<string name="txtCredits"><a href="http://www.google.com">Google</a></string>
19
David Dimalanta

La chose la plus simple qui a fonctionné pour moi est d’utiliser Linkify

TextView txt_Message = (TextView) view.findViewById(R.id.txt_message);
txt_Message.setText("This is link https://www.google.co.in/");
Linkify.addLinks(txt_Message, Linkify.WEB_URLS);

et il détectera automatiquement les URL Web à partir du texte dans la vue texte.

19
pks

Ce qui suit devrait fonctionner pour tous ceux qui recherchent une combinaison de texte et d'hyperlien au sein d'une application Android.

Dans string.xml:

<string name="applink">Looking for the regular Zesteve App? 
<a href="https://play.google.com/store/apps/details?id=zesteve.com.myapplication">Get it here</a>
</string>

Vous pouvez maintenant utiliser cette string dans n'importe quel View comme ceci:

<TextView
    Android:id="@+id/getapp"
    Android:layout_width="match_parent"
    Android:layout_height="50dp"
    Android:gravity="center"
    Android:textColor="@color/main_color_grey_600"
    Android:textSize="15sp"
    Android:text="@string/applink"/>

Maintenant, dans votre activité ou votre fragment, procédez comme suit:

TextView getapp =(TextView) findViewById(R.id.getapp);
getapp.setMovementMethod(LinkMovementMethod.getInstance());

À ce stade, vous n'avez pas besoin de définir Android:autoLink="web" ou Android:linksClickable="true" en utilisant cette approche.

J'espère que vous trouverez cela utile.

16
Asesha George

en utilisant linkify : Linkify prenez une morceau de texte et une expression régulière et transforme toutes les correspondances de regex dans le texte en liens cliquables

TextView textView = (TextView) findViewById(R.id.textView);
textView.setText("http://www.domain.com");
Linkify.addLinks(textView, Linkify.WEB_URLS);

N'oublie pas de

import Android.widget.TextView;
15
DeathRs

Voici un code d'une seule ligne Android pour que le téléphone et l'URL puissent être sélectionnés à partir de textView, quelles que soient la chaîne et les données. Vous n'avez pas besoin d'utiliser de balises HTML pour cela.

TextView textView = (TextView)findViewById(R.id.textView1);
textView.setText("some url is www.google.com phone 7504567890 another url lkgndflg.com ");

// Makes the textView's Phone and URL (hyperlink) select and go.
Linkify.addLinks(textView, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS);
14
Rahul Raina

J'ai remarqué que l'utilisation de Android:autoLink="web" ainsi

<TextView
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content" 
    Android:autoLink="web"/>

a fonctionné correctement pour les URL, mais comme j’avais une adresse électronique et un numéro de téléphone que je voulais également associer, j’ai fini par utiliser cette ligne Android:autoLink="all" comme ceci

<TextView
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content" 
        Android:autoLink="all"/>

et ça a fonctionné comme un charme.

12
aLearner

Assurez-vous de pas utiliser setAutoLinkMask(Linkify.ALL) lorsque setMovementMethod(LinkMovementMethod.getInstance()) et Html.fromHTML() sur des liens HTML correctement formatés (par exemple, <a href="http://www.google.com/">Google</a>).

11
elevenfive

Vous avez seulement besoin de ceci:

Android:autoLink="web"

Insérez cette ligne dans TextView, sur laquelle vous pouvez cliquer en référence au Web. Adresse URL définie en tant que texte de cette TextView.

Exemple:

 <TextView
    Android:id="@+id/textViewWikiURL"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:textSize="20sp"
    Android:textStyle="bold"
    Android:text="http://www.wikipedia.org/"
    Android:autoLink="web" />
9
Androdos

La réponse acceptée est correcte, MAIS cela signifie que les numéros de téléphone, les cartes, les adresses électroniques et les liens habituels, par exemple. http://google.com sans balises href ne sera plus cliquable car vous ne pouvez pas avoir de lien automatique dans le xml.

La seule solution complète que j'ai trouvée pour tout ce qui est cliquable est la suivante:

Spanned text = Html.fromHtml(myString);
URLSpan[] currentSpans = text.getSpans(0, text.length(), URLSpan.class);
SpannableString buffer = new SpannableString(text);
Linkify.addLinks(buffer, Linkify.ALL);
for (URLSpan span : currentSpans) {
    int end = text.getSpanEnd(span);
    int start = text.getSpanStart(span);
    buffer.setSpan(span, start, end, 0);
}
textView.setText(buffer);
textView.setMovementMethod(LinkMovementMethod.getInstance());

Et le TextView ne devrait PAS avoir Android:autolink. Il n'y a pas besoin de Android:linksClickable="true" non plus; c'est vrai par défaut.

8
Kelly McKinnon

Utilisez ceci...

TextView.setOnClickListener(new OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        // TODO Auto-generated method stub
                        Intent in=new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.Twitter.com/"));
                        startActivity(in);
                    }

                });

et ajouter la permission dans le fichier manifeste

<uses-permission Android:name="Android.permission.INTERNET"/>
8
Tej

Voici comment j'ai résolu les liens cliquables et visibles dans un TextView (par code)

private void setAsLink(TextView view, String url){
        Pattern pattern = Pattern.compile(url);
        Linkify.addLinks(view, pattern, "http://");
        view.setText(Html.fromHtml("<a href='http://"+url+"'>http://"+url+"</a>"));
    }
7
Dominic Bartl

Utilisez le code ci-dessous:

String html = "<a href=\"http://yourdomain.com\">Your Domain Name</a>"
TextView textview = (TextView) findViewById(R.id.your_textview_id);
textview.setMovementMethod(LinkMovementMethod.getInstance());
textview.setText(Html.fromHtml(html));
6
Phuc Tran

[Tested in Pre-Lollipop as well as in Lollipop and above]

Vous pouvez obtenir votre chaîne HTML à partir du backend ou de vos fichiers de ressources. Si vous placez votre texte en tant que chaîne de ressource, veillez à ajouter la balise CDATA:

<string name="your_text">![CDATA[...<a href="your_link">Link Title</a>  ...]]</string>

Ensuite, dans le code, vous devez obtenir la chaîne, l'affecter au format HTML et définir une méthode de déplacement de lien:

String yourText = getString(R.string.your_text);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
   textView.setText(Html.fromHtml(yourText, Html.FROM_HTML_MODE_COMPACT));
} else {
   textView.setText(Html.fromHtml(yourText));
}

try {
   subtext.setMovementMethod(LinkMovementMethod.getInstance());
} catch (Exception e) {
   //This code seems to crash in some Samsung devices.
   //You can handle this Edge case base on your needs.
}
6
Benny

Le problème est que vous essayez uniquement de faire correspondre les adresses "nues". des choses comme "www.google.com" ou " http://www.google.com ".

Courir votre texte à travers Html.fromHtml () devrait faire l'affaire. Vous devez le faire par programme, mais cela fonctionne.

5
Jeremy Logan

Le téléphone Autolink ne fonctionne pas pour moi. Ce qui suit a fonctionné comme un charme,

TextView tv = (TextView) findViewById(R.id.emergencynos);
String html2="<br><br>Fire - <b><a href=tel:997>997</a> </b></br></br>";        
tv.append(Html.fromHtml(html2));
tv.setMovementMethod(LinkMovementMethod.getInstance());
4
user1995307

Ajouter CDATA à votre ressource de chaîne

Strings.xml

<string name="txtCredits"><![CDATA[<a href=\"http://www.google.com\">Google</a>]]></string>
4
Akexorcist

J'utilise le lien automatique pour "souligner automatiquement" le texte, mais je viens de créer un "onClick" qui le gère. (J'ai rencontré ce problème moi-même)

        <TextView
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_marginRight="10dp"
            Android:textSize="18dp"
            Android:autoLink="all"
            Android:text="@string/Twitter"
            Android:onClick="Twitter"/>

public void Twitter (View view)
    {
        try
        {
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://Twitter.com/onaclovtech"));
            startActivity(browserIntent);

        }
        finally
        {
        }
    }

Ne nécessite aucune autorisation, car vous transmettez l'intention aux applications qui gèrent ces ressources (navigateur I.E.).

C'est ce qui a fonctionné pour moi. Bonne chance.

3
onaclov2000

Si vous utilisez TextView basé sur XML, vous ne devez répondre qu'à deux choses:

  1. Identifiez votre lien dans la chaîne, tel que "ceci est ma page Web". Vous pouvez l'ajouter en XML ou dans le code.

  2. Dans le XML qui a le TextView, ajoutez ces:


Android:linksClickable="true"

Android:autoLink="web"
3
codeFood

Gérer le texte de lien de lien Couleur également enter image description here

tv_customer_care_no.setLinkTextColor(getResources().getColor(R.color.blue));
  tv_customer_care_no.setText("For us to reach out to you, please fill the details below or contact our customer care at  18004190899 or visit our website http://www.dupont.co.in/corporate-links/contact-dupont.html ");
   Linkify.addLinks(tv_customer_care_no, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS);
   Linkify.addLinks(tv_customer_care_no, Linkify.ALL );
3
Keshav Gera

Je ne sais pas si cela vaut la peine d'ajouter une autre réponse, mais juste au cas où ...

J'ai dû chercher cela à quelques endroits mais j'ai finalement réussi à faire fonctionner cette version du code.

strings.xml:

<string name="name1">&lt;a href="http://www.google.com">link text1&lt;/a></string>
<string name="name2">&lt;a href="http://www.google.com">link text2&lt;/a></string>

myactivity.xml:

<TextView 
    Android:id="@+id/textview1"
    Android:layout_height="wrap_content"
    Android:layout_width="wrap_content"
    Android:layout_marginTop="5dp" />

<TextView 
    Android:id="@+id/textview2"
    Android:layout_height="wrap_content"
    Android:layout_width="wrap_content"
    Android:layout_marginTop="5dp" />

myactivty.Java (dans onCreate ()):

TextView tv1 = (TextView)findViewById(R.id.textview1);
TextView tv2 = (TextView)findViewById(R.id.textview2);

tv1.setText(Html.fromHtml(getResources().getString(R.string.name1)));
tv2.setText(Html.fromHtml(getResources().getString(R.string.name2)));
tv1.setMovementMethod(LinkMovementMethod.getInstance());
tv2.setMovementMethod(LinkMovementMethod.getInstance());

Cela créera deux hyperliens cliquables avec le texte link text1 et link text2 qui redirige l'utilisateur vers Google.

3
degausser

Créez une méthode d'extension sur SpannableString:

private fun SpannableString.setLinkSpan(text: String, url: String) {
    val textIndex = this.indexOf(text)
    setSpan(
        object : ClickableSpan() {
            override fun onClick(widget: View) {
                Intent(Intent.ACTION_VIEW).apply { data = Uri.parse(url) }.also { startActivity(it) }
            }
        },
        textIndex,
        textIndex + text.length,
        Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
    )
}

Utilisez-le pour rendre la chaîne dans votre TextView cliquable:

    myTextView.apply {
        movementMethod = LinkMovementMethod.getInstance()

        val googleUrl = "http://www.google.com"
        val microsoftUrl = "http://www.Microsoft.com"

        val google = "Google"
        val Microsoft = "Microsoft"

        val message = SpannableString("$google & $Microsoft").apply {
            setLinkSpan(google, googleUrl)
            setLinkSpan(Microsoft, microsoftUrl)
        }

        text = message
    }

Prendre plaisir!

enter image description here

2
farhanjk

Mon code était comme ça:

<TextView
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:id="@+id/link"
    Android:text="@string/forgot"
    Android:layout_marginTop="16dp"
    Android:gravity="center"
    Android:linksClickable="true"/>

Mon code Java ressemblait à ceci:

/*TextView action*/
        TextView textView = (TextView) findViewById(R.id.link);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
        textView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(LoginActivity.this,forgot.class));
            }
        });  

Cela pointe simplement le lien vers une autre activité. Mais ce lien est cliquable et fonctionne bien. Testé dans Android Studio 1.5 (Aperçu)

1
Ajay Kulkarni

Vous avez perdu tellement de temps à comprendre que vous deviez utiliser getText (R.string.wimporte) au lieu de getString (R.string.w importe) ...

Quoi qu'il en soit, voici comment j'ai fait fonctionner le mien. Avec plusieurs hyperliens dans la même vue de texte aussi.

    TextView termsTextView = (TextView) getActivity().findViewById(R.id.termsTextView);
    termsTextView.append("By registering your account, you agree to our ");
    termsTextView.append(getText(R.string.terms_of_service));
    termsTextView.append(", ");
    termsTextView.append(getText(R.string.fees));
    termsTextView.append(", and the ");
    termsTextView.append(getText(R.string.stripe_connected_account_agreement));

    termsTextView.setMovementMethod(LinkMovementMethod.getInstance());



            <TextView
                Android:layout_width="match_parent"
                Android:layout_height="wrap_content"
                Android:id="@+id/termsTextView"/>

exemple de chaîne

    <string name="stripe_connected_account_agreement"><a href="https://stripe.com/connect/account-terms">Stripe Connected Account Agreement</a></string>
1
luca992

Comme le databinding est terminé, j'aimerais partager ma solution pour textabinding DataVinding, qui prend en charge les balises HTML avec des liens cliquables.

Pour éviter de récupérer chaque textview et de leur fournir un support HTML à l'aide de From.html, nous étendons le TextView et plaçons la logique dans setText()

public class HtmlTextView extends TextView {

    public HtmlTextView(Context context) {
        super(context);
    }

    public HtmlTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public HtmlTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        super.setText(Html.fromHtml(text.toString()), type);
        this.setMovementMethod(LinkMovementMethod.getInstance());
    }
}

J'ai fait un Gist qui montre également un exemple d'entité et de vue pour l'utiliser.

0
Tapirboy