2012-02-14 10 views
8

Tengo TextView con ClickableSpan en que tanto layout_height como layout_width son wrap_content.Comportamiento extraño de ClickableSpan: se hace clic en onClick() al hacer clic en espacio vacío

Cuando el texto en TextView no es demasiado largo, funciona bien. Cuando el texto es lo suficientemente largo para que tome 2 líneas, también funciona bien, pero tiene un comportamiento extraño.

que es cuando hice clic en el espacio vacío de la segunda línea (no llena con el texto todavía, pero parte de TextView), el ClickableSpanonClick() devolución de llamada.

No espero esto ya que hice clic en el espacio vacío solamente pero no en el texto distribuido. Aunque no afecta mucho, quiero saber qué hay detrás.

que establezca la ClickableSpan con código de abajo:

TextView tv = (TextView) findViewById(R.id.text); 
tv.setText("TEXT TEXT TEXT TEXT"); 
SpannableStringBuilder ssb = new SpannableStringBuilder(); 
ssb.append(tv.getText()); 
ssb.setSpan(new TestClickableSpan(), ssb.length()-5, ssb.length(), 0); 
tv.setText(ssb); 
tv.setMovementMethod(LinkMovementMethod.getInstance()); 
tv.setOnTouchListener(new TextViewOnTouchListener()); 

El TextViewOnTouchListener:

class TextViewOnTouchListener implements OnTouchListener{ 

     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      Log.d("TextView", "onTouch"); 
      return false; 
     }  
} 

El TestClickableSpan:

class TestClickableSpan extends ClickableSpan{ 

     @Override 
     public void onClick(View arg0) { 
      Log.d("ClickableSpan", "Confirm OnClick: "+arg0.toString()); 
     }  
    } 
+0

¿Has resuelto esto? –

+0

@KiranKumar echa un vistazo a mi respuesta a continuación – dor506

Respuesta

9

que lograron resolverlo mediante la extensión de LinkMovementMethod y verificación si el evento táctil de fset es igual o mayor que la longitud del texto:

public class MovementMethod extends LinkMovementMethod { 

    @Override 
    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) { 
     int action = event.getAction(); 

     if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) { 
      int x = (int) event.getX(); 
      int y = (int) event.getY(); 

      x -= widget.getTotalPaddingLeft(); 
      y -= widget.getTotalPaddingTop(); 

      x += widget.getScrollX(); 
      y += widget.getScrollY(); 

      Layout layout = widget.getLayout(); 
      int line = layout.getLineForVertical(y); 
      int off = layout.getOffsetForHorizontal(line, x); 

      if (off >= widget.getText().length()) { 
       // Return true so click won't be triggered in the leftover empty space 
       return true; 
      } 
     } 

     return super.onTouchEvent(widget, buffer, event); 
    } 
} 
+3

Esto es brillante, gracias! Una cosa que debo tener en cuenta es que también deberá sobrescribir la función estática getInstance(), de lo contrario, se le devolverá una instancia del LinkMovementMethod subyacente. Perdí algo de tiempo tratando de resolver eso, así que espero poder salvar a alguien más de un dolor de cabeza. – martinp

+2

@ dor506 ¡Te amo! Muchas gracias. – Dogcat

+0

@martinp gracias, también perdí el tiempo allí. Se siguió llamando al Evento onTouch de LinkMovementMethod y me confundió. – Mallika

Cuestiones relacionadas