77import android .text .Spannable ;
88import android .text .method .LinkMovementMethod ;
99import android .text .method .MovementMethod ;
10+ import android .view .GestureDetector ;
1011import android .view .Gravity ;
1112import android .view .MotionEvent ;
1213import android .widget .TextView ;
@@ -21,11 +22,12 @@ public class LinkTouchMovementMethod extends LinkMovementMethod {
2122 private static volatile LinkMovementMethod sInstance ;
2223 private ClickSpan mClickSpan ;
2324 private float mClickDownX , mClickDownY ;
24- private Path mPath = new Path ();
25- private RectF mRectF = new RectF ();
26- private Rect mRect = new Rect ();
25+ private final Path mPath = new Path ();
26+ private final RectF mRectF = new RectF ();
27+ private final Rect mRect = new Rect ();
2728 private int mClickSpanStart ;
2829 private int mClickSpanEnd ;
30+ private GestureDetector mGestureDetector ;
2931
3032 private LinkTouchMovementMethod () {
3133 }
@@ -41,36 +43,40 @@ public static MovementMethod getInstance() {
4143 }
4244
4345 @ Override
44- public boolean onTouchEvent (final TextView textView , Spannable spannable , MotionEvent event ) {
45- if (event . getAction () == MotionEvent . ACTION_DOWN ) {
46- mClickSpan = getPressedSpan (textView , spannable , event );
47- if ( mClickSpan != null ) {
48- mClickSpanStart = spannable . getSpanStart ( mClickSpan );
49- mClickSpanEnd = spannable . getSpanEnd ( mClickSpan );
50- calcWordCenter ( textView , mClickSpanStart , mClickSpanEnd );
51- }
52- } else if ( event . getAction () == MotionEvent . ACTION_MOVE ) {
53- ClickSpan touchedSpan = getPressedSpan ( textView , spannable , event );
54- if ( mClickSpan != null && touchedSpan != mClickSpan ) {
55- mClickSpan = null ;
56- }
57- } else {
58- if ( mClickSpan != null ) {
59- if ( event . getAction () == MotionEvent . ACTION_UP ) {
60- //click callback
61- mClickSpan . onClick ( textView ,
62- textView . getText (). subSequence ( mClickSpanStart , mClickSpanEnd ). toString () ,
63- mClickDownX ,
64- mClickDownY ,
65- spannable ,
66- mClickSpanStart ,
67- mClickSpanEnd ) ;
46+ public boolean onTouchEvent (final TextView textView , final Spannable spannable , MotionEvent event ) {
47+ if (mGestureDetector == null ) {
48+ mGestureDetector = new GestureDetector (textView . getContext (). getApplicationContext (), new GestureDetector . SimpleOnGestureListener () {
49+ @ Override
50+ public boolean onSingleTapUp ( MotionEvent e ) {
51+ mClickSpan = getPressedSpan ( textView , spannable , e );
52+ if ( mClickSpan != null ) {
53+ mClickSpanStart = spannable . getSpanStart ( mClickSpan );
54+ mClickSpanEnd = spannable . getSpanEnd ( mClickSpan );
55+ //word center
56+ calcWordCenter ( textView , mClickSpanStart , mClickSpanEnd );
57+ //click callback
58+ mClickSpan . onClick (
59+ textView ,
60+ textView . getText (). subSequence ( mClickSpanStart , mClickSpanEnd ). toString (),
61+ mClickDownX ,
62+ mClickDownY ,
63+ spannable ,
64+ mClickSpanStart ,
65+ mClickSpanEnd
66+ );
67+ }
68+ textView . invalidate ();
69+ return true ;
6870 }
69- mClickSpan = null ;
70- }
71+ });
72+ }
73+ final boolean handled = mGestureDetector .onTouchEvent (event );
74+ if (event .getAction () == MotionEvent .ACTION_UP || event .getAction () == MotionEvent .ACTION_CANCEL ) {
75+ //Be sure to clean up, otherwise memory leaks.
76+ mClickSpan = null ;
77+ mGestureDetector = null ;
7178 }
72- textView .invalidate ();
73- return true ;
79+ return handled ;
7480 }
7581
7682 private ClickSpan getPressedSpan (TextView textView , Spannable spannable , MotionEvent event ) {
0 commit comments