2012-02-14 10 views
8

Ho un TextView con ClickableSpan in quanto sia layout_height che layout_width è wrap_content.Comportamento strano ClickableSpan: chiamato onClick() quando si fa clic su spazio vuoto

Quando il testo in TextView non è troppo lungo, funziona correttamente. Quando il testo è abbastanza lungo da richiedere 2 righe, funziona anche bene ma ha un comportamento strano.

cioè quando ho cliccato su uno spazio vuoto del secondo riga (non riempire con ancora un testo, ma parte di TextView), il ClickableSpanonClick() callback viene chiamata.

Non me lo aspetto, ho fatto clic solo sullo spazio vuoto ma non sul testo con spanning. Anche se non influisce molto, voglio sapere cosa c'è dietro.

I impostare il ClickableSpan con il codice di seguito:

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

Il TextViewOnTouchListener:

class TextViewOnTouchListener implements OnTouchListener{ 

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

Il TestClickableSpan:

class TestClickableSpan extends ClickableSpan{ 

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

Hai risolto questo? –

+0

@KiranKumar guarda la mia risposta sotto – dor506

risposta

9

sono riuscito a risolverlo estendendo LinkMovementMethod e controllo se l'evento tattile di fset è uguale o superiore alla lunghezza del testo:

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

Questo è brillante, grazie! Una cosa a cui prestare attenzione è che è necessario sovrascrivere la funzione statica getInstance(), altrimenti verrà comunque restituita un'istanza del LinkMovementMethod sottostante. Ho perso un po 'di tempo cercando di capirlo, quindi spero di salvare qualcun altro dal mal di testa. – martinp

+2

@ dor506 Ti amo! Grazie mille. – Dogcat

+0

@martinp grazie amico, ho perso tempo anche lì. L'onTouchEvent di LinkMovementMethod continuava a essere chiamato e mi aveva confuso. – Mallika

Problemi correlati