2013-07-20 5 views
6

Ho una vista testuale con una stringa html con ancore. Quando faccio clic sulla vista testo che voglio chiamare, ad esempio, un metodo chiamato A, e quando faccio clic su un collegamento nella vista testo, voglio chiamare un metodo chiamato B. Ho capito, ma ho un problema: quando clicco su un link, metodo B è chiamato, ma viene chiamato anche il metodo A. Come posso essere sicuro che solo il metodo B, e non B e A, vengono chiamati quando faccio clic su un collegamento?Textview onclicklistener con collegamenti

Il mio codice:

for (int i = 0; i < ingevoegd.length(); i++) { 
     JSONObject soortingevoegd = ingevoegd.getJSONObject(i); 
     String type = soortingevoegd.getString("type");   
     if (type.equals("Vis")) { 
      String link = "<a href = 'com.aquariumzoeken.pro://Soortweergave?selected=" 
        + naam + "&type=Vis" + "'>" + naam + "</a>"; 
      text = text.replaceAll(naam, link); 
     } 
    } 

    TextView texttv = (TextView) v.findViewById(R.id.textviewer); 


    texttv.setText(Html.fromHtml(text)); 
    texttv.setMovementMethod(LinkMovementMethod.getInstance()); 

E il TextView onclicklistener:

texttv.setOnClickListener(new View.OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      try { 

       switchToEditMode sw = new switchToEditMode(); 
      } catch (JSONException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

     } 
    }); 

Grazie in anticipo, Simon

+0

Hai provato consentendo 'Android: autoLink = "web" per la' TextView e non attaccare il LinkMovement? Penso che dovrebbe funzionare. – Slartibartfast

+0

Purtroppo non funziona. I miei collegamenti non sono cliccabili in questo modo. – Simon

+0

Puoi allegare uno screenshot, trovo difficile visualizzare il layout e perché hai due eventi collegati, c'è spazio vuoto altrove nella TV e questo è dove hai bisogno del Metodo B? – Slartibartfast

risposta

5

Si potrebbe provare a modificare l'onClickListener come accennato qui: Control onclicklistener in autolink enabled textview

texttv.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View v) { 
          if(texttv.getSelectionStart()==-1&&texttv.getSelectionEnd()==-1){ 

         // Method B 

          } 

        } 
       }); 

Fondamentalmente controllare dove e quando i collegamenti di inizio e fine e solo se si arent sul collegamento ipertestuale, quindi chiamare il metodo B, altrimenti si spara comunque Un sui link Ma questa è solo una soluzione Credo

Documenti qui : http://developer.android.com/reference/android/text/Selection.html#getSelectionEnd(java.lang.CharSequence)

+1

non funziona neanche. Il metodo B non viene chiamato quando si fa clic sulla vista testo – Simon

+0

guarda a questo se non funziona http://stackoverflow.com/a/41603171/5873832 –

0

Dopo aver studiato il codice sorgente, ho concluso che non esiste un buon modo per farlo, ma probabilmente la scelta migliore è un metodo di spostamento personalizzato. Qualcosa di simile a questo:

class MyMovementMethod extends LinkMovementMethod { 

    // Most of this code copied from 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); 

      ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); 

      if (link.length != 0) { 
       if (action == MotionEvent.ACTION_UP) { 
        link[0].onClick(widget); 
       } else if (action == MotionEvent.ACTION_DOWN) { 
        Selection.setSelection(buffer, 
             buffer.getSpanStart(link[0]), 
             buffer.getSpanEnd(link[0])); 
       } 
       return true; 
      } else { 
       Selection.removeSelection(buffer); 
       // NEW CODE - call method B 
       B(); 
      } 
     } 

     return Touch.onTouchEvent(widget, buffer, event); 
    } 

} 

Poi invece di chiamare LinkMovementMethod.getInstance(), creare un MyMovementMethod invece.

8

Faccio l'hack per te, prova questo codice!

SPIEGAZIONE:

1.use personalizzato ClickableSpan per gestire cliccare su URL.

2.clickablespan gestirà l'evento click prima della vista testo, crea un flag quando viene fatto clic su un collegamento.

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    TextView textView = (TextView) findViewById(R.id.main_text); 
    textView.setMovementMethod(LinkMovementMethod.getInstance()); 

    CharSequence charSequence = textView.getText(); 
    SpannableStringBuilder sp = new SpannableStringBuilder(charSequence); 

    URLSpan[] spans = sp.getSpans(0, charSequence.length(), URLSpan.class); 

    for (URLSpan urlSpan : spans) { 
     MySpan mySpan = new MySpan(urlSpan.getURL()); 
     sp.setSpan(mySpan, sp.getSpanStart(urlSpan), 
       sp.getSpanEnd(urlSpan), Spannable.SPAN_EXCLUSIVE_INCLUSIVE); 
    } 

    textView.setText(sp); 

    textView.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      // 2.if clicking a link 
      if (!isClickingLink) { 
       Log.w("log", "not clicking link"); 
      } 
      isClickingLink = false; 
     } 
    }); 
} 


private boolean isClickingLink = false; 

private class MySpan extends ClickableSpan { 

    private String mUrl; 

    public MySpan(String url) { 

     super(); 
     mUrl = url; 
    } 

    @Override 
    public void onClick(View widget) { 

     isClickingLink = true; 
     // 1. do url click 
    } 

} 
+0

Ha funzionato come un fascino. Grazie! Aggiungerò solo che ho Android: autoLink = "web | phone | email" nel mio TextView xml e nel MySpan onClick ho dovuto aggiungere un intento per andare all'URL. –

+0

Grazie mille questo ha funzionato per me – Pruthviraj

+0

Ho provato questo e ottengo l'errore: "URLSpan: Actvity non è stato trovato per l'intento". – trans

0

scrivere questo codice in ClickableSpan

ClicableSpan.onClick(View v){ 
    yourTextView.setOnClickListener(null); 
    /* do your own click 
    */ 
    yourTextView.setOnClickListener(your listener); 
}