2012-02-14 3 views
8

J'ai un TextView avec ClickableSpan en ce que les deux layout_height et layout_width est wrap_content.Comportement étrange de ClickableSpan: onClick() appelé en cliquant sur espace vide

Lorsque le texte dans TextView dans pas trop longtemps, il fonctionne très bien. Lorsque le texte est assez long pour qu'il prenne 2 lignes, il fonctionne également bien mais a un comportement étrange.

qui est quand je clique sur le deuxième espace vide de la ligne (pas remplir avec du texte encore, mais une partie de TextView), le rappel ClickableSpanonClick() est appelée.

Je ne m'attends pas à cela car j'ai cliqué uniquement sur l'espace vide mais pas sur le texte. Bien que cela n'affecte pas beaucoup, je veux savoir ce qu'il y a derrière.

Je mis le ClickableSpan avec le code ci-dessous:

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()); 

Le TextViewOnTouchListener:

class TextViewOnTouchListener implements OnTouchListener{ 

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

Le TestClickableSpan:

class TestClickableSpan extends ClickableSpan{ 

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

Avez-vous trouvé la solution? –

+0

@KiranKumar vérifier ma réponse ci-dessous – dor506

Répondre

9

j'ai réussi à le résoudre en étendant LinkMovementMethod, et le contrôle si l'événement tactile de fset est égal ou supérieur à la longueur du texte:

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

Ceci est génial, merci! Une chose à surveiller est que vous aurez besoin de surcharger la fonction static getInstance(), sinon vous aurez toujours une instance de LinkMovementMethod sous-jacente. J'ai perdu un peu de temps à essayer de comprendre cela, alors j'espère que j'ai sauvé quelqu'un d'autre mal à la tête. – martinp

+2

@ dor506 Je t'aime! Merci beaucoup. – Dogcat

+0

@martinp remercie l'homme, j'ai aussi perdu du temps là-bas. Le onTouchEvent de LinkMovementMethod a continué à être appelé et m'a confus. – Mallika

Questions connexes