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
Post a Comment