Vínculos con varios clics en TextView en Android

Estoy intentando agregar varios enlaces en una vista de texto similar a lo que Google y Flipboard han hecho a continuación con sus Términos y condiciones y la Política de privacidad que se muestra en la captura de pantalla a continuación:

Hasta ahora me he topado con este enfoque

TextView.setText (Html.fromHtml (myHtml); textView.setMovementMethod (LinkMovementMethod.getInstance ());

Donde myHtml es un href.

Pero no me da el control que necesito por ejemplo para lanzar un fragmento, etc

¿Alguna idea de cómo lograr esto en los dos ejemplos a continuación?

Flipboard términos y condiciones ver

Vista de términos y condiciones de Google

Puede utilizar Linkify ( android.text.Spannable , java.util.regex.Pattern , java.lang.String )

String termsAndConditions = getResources().getString(R.string.terms_and_conditions); String privacyPolicy = getResources().getString(R.string.privacy_policy); legalDescription.setText( String.format( getResources().getString(R.string.message), termsAndConditions, privacyPolicy) ); legalDescription.setMovementMethod(LinkMovementMethod.getInstance()); Pattern termsAndConditionsMatcher = Pattern.compile(termsAndConditions); Linkify.addLinks(legalDescription, termsAndConditionsMatcher, "terms:"); Pattern privacyPolicyMatcher = Pattern.compile(privacyPolicy); Linkify.addLinks(legalDescription, privacyPolicyMatcher, "privacy:"); 

Y luego puede utilizar el esquema para iniciar una actividad, por ejemplo, agregando el esquema en el AndroidManifest :

 <intent-filter> <category android:name="android.intent.category.DEFAULT" /> <action android:name="android.intent.action.VIEW" /> <data android:scheme="terms" /> <data android:scheme="privacy" /> </intent-filter> 

Si desea realizar una acción personalizada, puede establecer el filtro de intenciones en su actividad actual, que tendrá un único modo de inicio.

Esto hará que onNewIntent se dispare donde puede hacer sus acciones personalizadas:

 @Override protected void onNewIntent(final Intent intent) { ... if (intent.getScheme().equals(..)) { .. } } 

Creo que estoy un poco tarde para compartir esto, pero he conseguido lo mismo con SpannableStringBuilder .

Basta con inicializar el TextView que desea agregar 2 o más oyentes y luego pasarlo al siguiente método que he creado:

 private void customTextView(TextView view) { SpannableStringBuilder spanTxt = new SpannableStringBuilder( "I agree to the "); spanTxt.append("Term of services"); spanTxt.setSpan(new ClickableSpan() { @Override public void onClick(View widget) { Toast.makeText(getApplicationContext(), "Terms of services Clicked", Toast.LENGTH_SHORT).show(); } }, spanTxt.length() - "Term of services".length(), spanTxt.length(), 0); spanTxt.append(" and"); spanTxt.setSpan(new ForegroundColorSpan(Color.BLACK), 32, spanTxt.length(), 0); spanTxt.append(" Privacy Policy"); spanTxt.setSpan(new ClickableSpan() { @Override public void onClick(View widget) { Toast.makeText(getApplicationContext(), "Privacy Policy Clicked", Toast.LENGTH_SHORT).show(); } }, spanTxt.length() - " Privacy Policy".length(), spanTxt.length(), 0); view.setMovementMethod(LinkMovementMethod.getInstance()); view.setText(spanTxt, BufferType.SPANNABLE); } 

Y en su XML, use android:textColorLink para agregar color de enlace personalizado de su elección. Me gusta esto:

  <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" android:textColorLink="#C36241" /> //#C36241 - Rust 

Y esto se parece a esto:

Introduzca aquí la descripción de la imagen

Espero que ayude a alguien. 🙂

Aquí está mi solución:

Primero tenemos que tener enlaces en nuestro TextView:

  1. Aquí está mi TextView en la disposición del xml, no agregue ningunos acoplamientos que manejan parámetros.

     <TextView android:id="@+id/sign_up_privacy" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/terms_and_privacy"/> 
  2. En el archivo de cadenas, he añadido el texto del recurso con etiquetas html

     <string name="terms_and_privacy">By signing up you agree to our <a href="terms:">Terms of Service</a> and <a href="privacy:">Privacy Policy.</a></string> 
  3. En onCreateView, establezca LinkMovementMethod en TextView

     TextView privacyTextView = (TextView) root.findViewById(R.id.sign_up_privacy); privacyTextView.setMovementMethod(LinkMovementMethod.getInstance()); 

Ahora los enlaces de TextView son clicables.

En segundo lugar, necesitamos manejar estos clics:

  1. En mi archivo de manifiesto, agregué el filtro de intenciones para "términos" y "privacidad" y el modo de inicio de instancia única

     <activity android:name=".MyActivity" android:launchMode="singleInstance"> <intent-filter> <category android:name="android.intent.category.DEFAULT"/> <action android:name="android.intent.action.VIEW"/> <data android:scheme="terms"/> <data android:scheme="privacy"/> </intent-filter> </activity> 
  2. En MyActivity, anule onNewIntent para capturar privacidad y términos intentos

     @Override protected void onNewIntent(Intent intent) { if (intent.getScheme().equalsIgnoreCase(getString("terms"))) { //handle terms clicked } else if (intent.getScheme().equalsIgnoreCase(getString("privacy"))) { //handle privacy clicked } else { super.onNewIntent(intent); } } 

Una solución fácil para esto sería utilizar múltiples etiquetas. Uno para cada enlace y otro para el texto.

 [TermsOfServiceLabel][andLabel][PrivacyPolicy] 

¿O es necesario que sólo use una etiqueta?

Con Textoo , esto se puede lograr como:

Res / values ​​/ strings.xml:

 <resources> <string name="str_terms_and_privacy">By signing up you agree to our <a href="terms:">Terms of Service</a> and <a href="privacy:">Privacy Policy.</a></string> </resources> 

Res / layout / myActivity.xml:

 <TextView android:id="@+id/view_terms_and_privacy" android:text="@string/str_terms_and_privacy" /> 

Java / myPackage / MyActivity.java:

 public class MyActivity extends Activity { ... protected void onCreate(Bundle savedInstanceState) { ... TextView termsAndPrivacy = Textoo .config((TextView) findViewById(R.id.view_terms_and_privacy)) .addLinksHandler(new LinksHandler() { @Override public boolean onClick(View view, String url) { if ("terms:".equals(url)) { // Handle terms click return true; // event handled } else if ("privacy:".equals(url)) { // Handle privacy click return true; // event handled } else { return false; // event not handled. continue default processing ie launch web browser and display the link } } }) .apply(); ... } ... } 

Este enfoque tiene las ventajas de que:

  • Mantenga el texto externalizado como recurso de cadena. Facilita la localización de tu aplicación.
  • Puede manejar el evento de clic directamente usando LinksHandler y no es necesario definir un filtro de intenciones adicional
  • Código más simple y legible

Esto está funcionando para mí:

En xml:

 <TextView android:id="@+id/tv_by_continuing_str" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="8dp" android:layout_marginLeft="8dp" android:layout_marginRight="8dp" android:textSize="15sp" tools:text="Test msg 1 2, 3" android:textColor="@color/translucent_less_white3" android:textColorLink="@color/white" android:gravity="center|bottom" android:layout_above="@+id/btn_privacy_continue" /> 

En strings.xml

 < string name="by_continuing_str2">< ! [ CDATA[By continuing to use this app, you agree to our <a href="https://go.test.com" style="color:gray"/> Privacy Statement </a> and <a href="https://go.test.com" style="color:gray"/>Services Agreement.]]>< / string> 

En la actividad:

 TextView tv_by_continuing = (TextView) findViewById(R.id.tv_by_continuing); tv_by_continuing.setText(Html.fromHtml(getString(R.string.by_continuing_str2))); tv_by_continuing.setMovementMethod(LinkMovementMethod.getInstance()); 
  • Eclipse ADT Bundle: error grave, no se puede iniciar
  • Memoria requerida para campos 'cortos' en Dalvik?
  • El campo ADT no está configurado
  • Motor ligero ligero androide de la plantilla
  • Métodos estáticos o Singletons rendimiento-sabio (Android)?
  • ¿Cuál es la diferencia entre `opencv.android.JavaCameraView` y` opencv.android.NativeCameraView`
  • Reemplazar el nuevo método dexlib2 fallando
  • El método getWindow () no está definido para el tipo AlertDialog.Builder
  • ¿Cómo pasar la referencia (no serializable) de una actividad a otra?
  • Problema de autenticación de LinkedIn en eclipse
  • Cómo reemplazar la etiqueta <br \ />
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.