Abrir vínculos de TextView en otra actividad, no en el navegador predeterminado

Tener el textView con autoLinkMask establecido en Linkify.ALL , soy capaz de abrir los enlaces y el navegador muestra la página web.

Tengo que llamar a otra actividad que lo hará con su webView no dejar la aplicación.

Notas importantes:

  • cambiar el contenido textView no es una opción, necesito tener los enlaces mostrados como están con los esquemas que tienen,
  • hay mucho texto en el textView, no solo el enlace.

Miré a través de movementMethod y IntentFilters , podría perder algo, pero parece que no puede ayudar.

Por lo tanto, cualquier opción para interceptar el enlace tocado en el TextView para hacer algo con él no abrir el navegador?

Si desea mencionar esta pregunta de SO, por favor, dé algunos argumentos por qué causa no parece resolver el mismo problema que tengo.

Paso # 1: Cree su propia subclase de ClickableSpan que hace lo que quiere en su método onClick() (por ejemplo, llamado YourCustomClickableSpan )

Paso 2: Ejecute una conversión masiva de todos los objetos URLSpan para que YourCustomClickableSpan objetos YourCustomClickableSpan . Tengo una clase de utilidad para esto:

 public class RichTextUtils { public static <A extends CharacterStyle, B extends CharacterStyle> Spannable replaceAll(Spanned original, Class<A> sourceType, SpanConverter<A, B> converter) { SpannableString result=new SpannableString(original); A[] spans=result.getSpans(0, result.length(), sourceType); for (A span : spans) { int start=result.getSpanStart(span); int end=result.getSpanEnd(span); int flags=result.getSpanFlags(span); result.removeSpan(span); result.setSpan(converter.convert(span), start, end, flags); } return(result); } public interface SpanConverter<A extends CharacterStyle, B extends CharacterStyle> { B convert(A span); } } 

Lo usarías así:

 yourTextView.setText(RichTextUtils.replaceAll((Spanned)yourTextView.getText(), URLSpan.class, new URLSpanConverter())); 

con un URLSpanConverter personalizado como este:

 class URLSpanConverter implements RichTextUtils.SpanConverter<URLSpan, YourCustomClickableSpan> { @Override public URLSpan convert(URLSpan span) { return(new YourCustomClickableSpan(span.getURL())); } } 

para convertir todos los objetos YourCustomClickableSpan objetos YourCustomClickableSpan .

Hago el código de @ CommonsWare más elegante y claro añadiendo Click Listener que se puede agregar directamente en el mismo método que reemplaza Spans de URL.

  1. Defina YourCustomClickableSpan Class .

    public static class YourCustomClickableSpan extiende ClickableSpan {

      private String url; private OnClickListener mListener; public YourCustomClickableSpan(String url, OnClickListener mListener) { this.url = url; this.mListener = mListener; } @Override public void onClick(View widget) { if (mListener != null) mListener.onClick(url); } public interface OnClickListener { void onClick(String url); } } 
  2. Defina la RichTextUtils Class que manipulará el texto Spanned de su TextView.

    public static class RichTextUtils {

    public static <A extends CharacterStyle, B extends CharacterStyle> Spannable replaceAll(Spanned original, Class<A> sourceType, SpanConverter<A, B> converter, final ClickSpan.OnClickListener listener) {

      SpannableString result = new SpannableString(original); A[] spans = result.getSpans(0, result.length(), sourceType); for (A span : spans) { int start = result.getSpanStart(span); int end = result.getSpanEnd(span); int flags = result.getSpanFlags(span); result.removeSpan(span); result.setSpan(converter.convert(span, listener), start, end, flags); } return (result); } public interface SpanConverter<A extends CharacterStyle, B extends CharacterStyle> { B convert(A span, ClickSpan.OnClickListener listener); } 

    }

  3. Defina la URLSpanConverter class que hará el código real de reemplazo de URLSpan con su Span personalizado.

    public static class URLSpanConverter implementa RichTextUtils.SpanConverter {

     @Override public ClickSpan convert(URLSpan span, ClickSpan.OnClickListener listener) { return (new ClickSpan(span.getURL(), listener)); } 

    }

  4. Uso

    TextView textView = ((TextView) this.findViewById (R.id.your_id)); textView.setText ("your_text"); Linkify.addLinks (contentView, Linkify.ALL);

     Spannable formattedContent = UIUtils.RichTextUtils.replaceAll((Spanned)textView.getText(), URLSpan.class, new UIUtils.URLSpanConverter(), new UIUtils.ClickSpan.OnClickListener() { @Override public void onClick(String url) { // Call here your Activity } }); textView.setText(formattedContent); 

Tenga en cuenta que he definido todas las clases aquí como estática para que pueda poner directamente información de su clase Util y luego referencia fácilmente desde cualquier lugar.

Sólo para compartir una solución alternativa utilizando Textoo que acabo de crear:

  TextView yourTextView = Textoo .config((TextView) findViewById(R.id.your_text_view)) .addLinksHandler(new LinksHandler() { @Override public boolean onClick(View view, String url) { if (showInMyWebView(url)) { // // Your custom handling here // return true; // event handled } else { return false; // continue default processing ie launch browser app to display link } } }) .apply(); 

Bajo el capó de la biblioteca reemplazar URLSpan en la TextView con la aplicación ClickableSpan personalizado que despachar los eventos de clic al usuario suministrado LinksHandler (s). El mecanismo es muy similar a la solución de @commonsWare. Sólo paquete en un API de nivel superior para que sea más fácil de usar.

Creo que la respuesta de David Hedlund a sí mismo es el camino a seguir. En mi caso, tenía un TextView que contenía contenido SMS de la bandeja de entrada del usuario y quería manejar el comportamiento de barbecho:

  1. Si se encuentra una URL WEB, entonces lo enlazamos y manejamos el clic dentro de la aplicación.
  2. Si se encuentra el NÚMERO DE TELÉFONO, entonces conéctelo y maneje el clic que muestra un selector para que el usuario elija si llama al número o agregalo a la libreta de direcciones (todo dentro de la aplicación)

Para lograr esto utilicé la respuesta enlazada de esta manera:

 TextView tvBody = (TextView)findViewById(R.id.tvBody); tvBody.setText(messageContentString); // now linkify it with patterns and scheme Linkify.addLinks(tvBody, Patterns.WEB_URL, "com.my.package.web:"); Linkify.addLinks(tvBody, Patterns.PHONE, "com.my.package.tel:"); 

Ahora en el manifiesto:

 <activity android:name=".WebViewActivity" android:label="@string/web_view_activity_label"> <intent-filter> <category android:name="android.intent.category.DEFAULT" /> <action android:name="android.intent.action.VIEW"/> <data android:scheme="com.duckma.phonotto.web"/> </intent-filter> </activity> ... <activity android:name=".DialerActivity" android:label="@string/dialer_activity_label"> <intent-filter> <category android:name="android.intent.category.DEFAULT" /> <action android:name="android.intent.action.VIEW"/> <data android:scheme="com.duckma.phonotto.tel"/> </intent-filter> </activity> <activity android:name=".AddressBook" android:label="@string/address_book_activity_label"> <intent-filter> <category android:name="android.intent.category.DEFAULT" /> <action android:name="android.intent.action.VIEW"/> <data android:scheme="com.duckma.phonotto.tel"/> </intent-filter> </activity> 

Y funciona muy bien para mí, cuando el usuario hace clic en un número de teléfono el selector se mostrará con la opción de marcador / libreta de direcciones. En las actividades llamadas use getIntent().getData() para encontrar la Url pasada con los datos en ella.

Que hacer esto:

  TextView textView=(TextView) findViewById(R.id.link); textView.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent intent=new Intent(YourActivityName.this,WebActivity.class); startActivity(intent); } }); 

onCreate de WebActivity Clase:

 WebView webView=(WebView) findViewById(R.id.web); webView.loadUrl("http://www.google.co.in"); 

Añada esto bajo vista de texto en xml:

 android:clickable="true" 
  • Android: autoLink para números de teléfono no siempre funciona
  • Activar onContextMenu cuando la detección de vínculo automático está presente
  • Android enlaza sin primer carácter
  • Android Linkify enlaces textColor ignorado, estilo CSS anula posible?
  • Selección de TextView con Spannable y LinkMovementMethod
  • Cómo procesar textview para HTML y Linkify
  • Android LinkMovementMethod en XML?
  • AutoLink = "todos" la característica de TextView Android
  • Android - autoLink
  • Android autolink es demasiado agresivo
  • Vincular inconsistencia
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.