Android: Linkify TextView

Tengo textview que necesito para enlazar. Esto es lo que estoy haciendo …

TextView text = (TextView) view.findViewById(R.id.name); text.setText("Android...Update from Android"); Pattern pattern = Pattern.compile("Android"); String scheme = "www.android.com"; Linkify.addLinks(text, pattern, scheme); 

La vista de texto se muestra correctamente con el texto “Android … Actualización de Android”, pero me enfrentan dos problemas.

1) Mi cadena de texto tiene dos instancias de la cadena “Android”. Entonces, ambos textos están vinculados. Solo quiero vincular la primera aparición. ¿Cómo debo hacerlo?

2) Cuando hago clic en el texto linkfy, abre el navegador, pero la URL es extraña. La URL que intenta abrir es “www.comandroid”. No sé qué está yendo mal aquí. El texto “android” en la URL está siendo reemplazado. ¿Estoy haciendo algo mal cuando enlace el texto?

Cualquier ayuda será muy apreciada.

La manera más fácil es poner AutoLink en el diseño XML.

  android:autoLink="web" 

Creé un método estático que hace esto simplemente:

 /** * Add a link to the TextView which is given. * * @param textView the field containing the text * @param patternToMatch a regex pattern to put a link around * @param link the link to add */ public static void addLink(TextView textView, String patternToMatch, final String link) { Linkify.TransformFilter filter = new Linkify.TransformFilter() { @Override public String transformUrl(Matcher match, String url) { return link; } }; Linkify.addLinks(textView, Pattern.compile(patternToMatch), null, null, filter); } 

Y el OP podría usarlo simplemente:

 addLink(text, "^Android", "http://www.android.com"); 

No tengo mucha experiencia con Linkify. Hasta ahora, todo lo que he querido hacer es convertir URL en el texto en enlaces, que se maneja automáticamente con una versión diferente de addLinks .

Sin embargo, la expresión regular que está utilizando para que coincida con “Android” se puede cambiar para que coincida solo con la que inicia la cadena ajustando su expresión regular:

 Pattern pattern = Pattern.compile("^Android"); 

Observe la adición de ‘^’. Esto le dice al emparejador de expresiones regulares que solo coincida con el patrón ‘Android’ cuando inicia la cadena. Si eso funciona con tus cuerdas, entonces genial. Si tiene otros casos en los que la palabra que desea vincular no está al principio de la línea, necesitará explorar algunas expresiones regulares. Recomiendo este sitio para aprender más regular-expressions.info

Si desea abrir todas las URL que contiene el texto, puede hacerlo …

  TextView textview=(TextView)findViewById(R.id.text); textview.setText("Android....Update from android...www.android.com"); Linkify.addLinks(textview, Linkify.WEB_URLS); textview.setMovementMethod(LinkMovementMethod.getInstance()); 

Puede funcionar para todas las urls.

Aquí de la respuesta de Shawns y del comentario de SpunkerBaba he salido con esta clase de ayuda. Esto evita que el agregado doble de lo que está cambiando se agregue a su url.

 package com.your.package; public class Linkify { /** * @param textView * textView who's text you want to change * @param linkThis * a regex of what text to turn into a link * @param toThis * the url you want to send them to */ public static void addLinks(TextView textView, String linkThis, String toThis) { Pattern pattern = Pattern.compile(linkThis); String scheme = toThis; android.text.util.Linkify.addLinks(textView, pattern, scheme, new MatchFilter() { @Override public boolean acceptMatch(CharSequence s, int start, int end) { return true; } }, new TransformFilter() { @Override public String transformUrl(Matcher match, String url) { return ""; } }); } } 

Uso:

  Linkify.addLinks(profileTextView, "BlundellApps.com", "http://www.BlundellApps.com"); 

Creo que lo que realmente necesitas es algo tan simple como:

 final TextView textView = ((BodyViewHolder) holder).textView; textView.setText(text); Linkify.addLinks(textView, Linkify.WEB_URLS); // I would do this only during view creation, btw. 

Está rastreando una URL específicamente. Algunas personas sugieren usar Linkigy.ALL, pero usted no quiere esto:

 public static final int ALL = WEB_URLS | EMAIL_ADDRESSES | PHONE_NUMBERS | MAP_ADDRESSES; 

Además, otras personas sugieren sumr:

 textview.setMovementMethod(LinkMovementMethod.getInstance()); 

después de agregar las reglas de enlace, pero addLinks ya lo hace en su interior 😉

¡Aclamaciones!

Problema resuelto. La solución al primer problema es la respuesta proporcionada por Ian Leslie. La solución al segundo problema es la siguiente. El comportamiento de la API “Linkify.addLinks” es tal que, agrega la cadena que desea vincular al final de la url. Por ejemplo, si desea vincular el texto “Android” con “www.android.com”. La URL final es “www.android.comAndroid”, que no es lo que necesitaba. Así que usé

 public static final void addLinks (TextView text, Pattern p, String scheme, Linkify.MatchFilter matchFilter, Linkify.TransformFilter transformFilter) TransformFilter transformFilter = new TransformFilter() { public final String transformUrl(final Matcher match, String url) { return ""; } }; 

La api transformFilter devuelve una cadena nula. Entonces mi url final es “www.android.com”

 TextView noteView = (TextView) findViewById(R.id.noteview); noteView.setText(someContent); Linkify.addLinks(noteView, Linkify.ALL); 

Para Koltin con expresión lambda, sería como esto

 val pattern = Pattern.compile(link.title) Linkify.addLinks(view, pattern, null, null, { matcher, url -> link.href })