android - Can a TextView be selectable AND contain links? -


i've run problem textview. can make selectable using settextisselectable(true), when enable links clicked via setmovementmethod(linkmovementmethod.getinstance()), no longer selectable.

please note, don't mean making raw links clickable, rather making actual words clickable loading textview html markup using settext(html.fromhtml("<a href='http://stackoverflow.com'>hello world!</a>")).

oakes's answer cause exception on double tap on textview

java.lang.indexoutofboundsexception: setspan (-1 ... -1) starts before 0...

i looked @ ontouchevent impletentation in linkmovementmethod , found removes selection when textview doesn't contain link. in case selection starts empty value , application crash when user try change it.

... 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); } ... 

so override ontouchevent method, , works fine.

public class custommovementmethod extends linkmovementmethod {     @override     public boolean canselectarbitrarily () {         return true;     }      @override     public void initialize(textview widget, spannable text) {         selection.setselection(text, text.length());     }      @override     public void ontakefocus(textview view, spannable text, int dir) {         if ((dir & (view.focus_forward | view.focus_down)) != 0) {             if (view.getlayout() == null) {                 // shouldn't null, sensible if is.                 selection.setselection(text, text.length());             }         } else {             selection.setselection(text, text.length());         }     }      @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;             }         }          return touch.ontouchevent(widget, buffer, event);     } } 

hope helpful someone.


Comments

Popular posts from this blog

monitor web browser programmatically in Android? -

Shrink a YouTube video to responsive width -

wpf - PdfWriter.GetInstance throws System.NullReferenceException -