package com.datdo.mobilib.util;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.view.MotionEvent;
import android.widget.TextView;
/**
* <pre>
* A movement method that detects links in {@link TextView}.
* Also support callback methods when link is clicked.
* This class is used together with {@link MblLinkRecognizer}
* </pre>
*/
public class MblLinkMovementMethod extends LinkMovementMethod {
private static final long LONG_CLICK_DELAY = 500;
private boolean mLongClickDetected = false;
private MblLinkMovementMethodCallback mCallback;
public static interface MblLinkMovementMethodCallback {
/**
* <pre>
* Invoked when link is clicked.
* </pre>
*/
public void onLinkClicked(String link);
/**
* <pre>
* Invoked when {@link TextView} is long-clicked.
* </pre>
*/
public void onLongClicked();
}
public MblLinkMovementMethod(MblLinkMovementMethodCallback callback) {
super();
mCallback = callback;
}
private Runnable mOnLongClickAction = new Runnable() {
@Override
public void run() {
mLongClickDetected = true;
}
};
// return true --> should handle event as long click
private boolean listenLongClick(MotionEvent event) {
if (mLongClickDetected) {
if ( event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP ) {
mLongClickDetected = false; // this is the end of long click
}
if (mCallback != null) {
mCallback.onLongClicked();
}
return true;
} else {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
MblUtils.getMainThreadHandler().postDelayed(mOnLongClickAction, LONG_CLICK_DELAY);
} else if ( event.getAction() == MotionEvent.ACTION_CANCEL ||
event.getAction() == MotionEvent.ACTION_UP ) {
MblUtils.getMainThreadHandler().removeCallbacks(mOnLongClickAction);
}
return false;
}
}
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
int action = event.getAction();
if (!listenLongClick(event)) {
if (action == MotionEvent.ACTION_UP) {
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) {
String linkString = buffer.toString().substring(buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0]));
if (mCallback != null) {
mCallback.onLinkClicked(linkString);
}
Selection.removeSelection(buffer);
return false;
}
}
}
return false;
}
}