80,475
社区成员
发帖
与我相关
我的任务
分享
public class MainActivity extends AppCompatActivity{
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView)findViewById(R.id.word);
textView.setText(string2);
SpannableStringBuilder s = new SpannableStringBuilder(textView.getText());
textView.setText(s, TextView.BufferType.SPANNABLE);
getEachParagraph(textView);
textView.setMovementMethod(LinkMovementMethod.getInstance());
//textView.setMovementMethod(ScrollingMovementMethod.getInstance());
}
//paragraph
public void getEachParagraph(TextView textView) {
Spannable spans = (Spannable) textView.getText();
Integer[] indices = getIndices(
textView.getText().toString().trim(), '\n');
int start = 0;
int end = 0;
// recycle
//System.out.println("length of indices: " + indices.length);
//System.out.println("length of spans: " + spans.length());
for (int i = 0; i <= indices.length; i++) {
System.out.println("indices index: " + i);
//System.out.println("start of beginning: " + start);
ClickableSpan clickSpan = getClickableSpan(i);
//setSpan
end = (i < indices.length ? indices[i] : spans.length());
spans.setSpan(clickSpan, start, end,
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
//System.out.println("end of ending: " + end);
start = end + 1;
}
//改变选中文本的高亮颜色
//textView.setHighlightColor(Color.parseColor("#0c83bd"));
}
//array
public static Integer[] getIndices(String s, char c) {
int pos = s.indexOf(c, 0);
List<Integer> indices = new ArrayList<Integer>();
while (pos != -1) {
indices.add(pos);
pos = s.indexOf(c, pos + 1);
}
return (Integer[]) indices.toArray(new Integer[0]);
}
//click
private ClickableSpan getClickableSpan(final int i) {
return new ClickableSpan() {
@Override
public void onClick(View widget) {
System.out.println("i: " + i);
TextView tv = (TextView) widget;
String s = tv
.getText()
.subSequence(tv.getSelectionStart(),
tv.getSelectionEnd()).toString();
Log.e("onclick--:", s);
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setColor(Color.BLACK);
ds.setUnderlineText(false);
}
};
}
}
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
if (mTouchSlop == 0) {
mTouchSlop = ViewConfiguration.get(widget.getContext()).getScaledTouchSlop();
}
//ClickableSpan[] links;
int action = event.getAction();
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[] links = buffer.getSpans(off, off, ClickableSpan.class);
switch (action) {
case MotionEvent.ACTION_DOWN:
clickCount++;
mIsMoved = false;
//设置拖拽状态
super.onTouchEvent(widget, buffer, event);
if (links.length != 0) {
Selection.setSelection(buffer,
buffer.getSpanStart(links[0]),
buffer.getSpanEnd(links[0]));
return true;
} else {
Selection.removeSelection(buffer);
}
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(event.getX() - mDownX) > mTouchSlop ||
Math.abs(event.getY() - mDownY) > mTouchSlop) {
mIsMoved = true;
}
clickCount = 0;
break;
case MotionEvent.ACTION_UP:
//清除拖拽状态
super.onTouchEvent(widget, buffer, event);
//ClickableSpan[] links = buffer.getSpans(off, off, ClickableSpan.class);
//如果滑动,则不触发点击事件
if (!mIsMoved && links.length != 0 && clickCount == 2) {
links[0].onClick(widget);
clickCount = 0;
return true;
} else {
Selection.removeSelection(buffer);
}
break;
default:
}
return super.onTouchEvent(widget, buffer, event);
}
textView.setMovementMethod(MyMovement.getInstance());
package my.study;
import android.text.Layout;
import android.text.NoCopySpan;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.method.MovementMethod;
import android.text.method.ScrollingMovementMethod;
import android.text.style.ClickableSpan;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
public class MyMovement extends ScrollingMovementMethod {
private static final int CLICK = 1;
private static final int UP = 2;
private static final int DOWN = 3;
@Override
public boolean canSelectArbitrarily() {
return true;
}
@Override
protected boolean handleMovementKey(TextView widget, Spannable buffer, int keyCode,
int movementMetaState, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
case KeyEvent.KEYCODE_ENTER:
if (KeyEvent.metaStateHasNoModifiers(movementMetaState)) {
if (event.getAction() == KeyEvent.ACTION_DOWN &&
event.getRepeatCount() == 0 && action(CLICK, widget, buffer)) {
return true;
}
}
break;
}
return super.handleMovementKey(widget, buffer, keyCode, movementMetaState, event);
}
@Override
protected boolean up(TextView widget, Spannable buffer) {
if (action(UP, widget, buffer)) {
return true;
}
return super.up(widget, buffer);
}
@Override
protected boolean down(TextView widget, Spannable buffer) {
if (action(DOWN, widget, buffer)) {
return true;
}
return super.down(widget, buffer);
}
@Override
protected boolean left(TextView widget, Spannable buffer) {
if (action(UP, widget, buffer)) {
return true;
}
return super.left(widget, buffer);
}
@Override
protected boolean right(TextView widget, Spannable buffer) {
if (action(DOWN, widget, buffer)) {
return true;
}
return super.right(widget, buffer);
}
private boolean action(int what, TextView widget, Spannable buffer) {
Layout layout = widget.getLayout();
int padding = widget.getTotalPaddingTop() +
widget.getTotalPaddingBottom();
int areaTop = widget.getScrollY();
int areaBot = areaTop + widget.getHeight() - padding;
int lineTop = layout.getLineForVertical(areaTop);
int lineBot = layout.getLineForVertical(areaBot);
int first = layout.getLineStart(lineTop);
int last = layout.getLineEnd(lineBot);
ClickableSpan[] candidates = buffer.getSpans(first, last, ClickableSpan.class);
int a = Selection.getSelectionStart(buffer);
int b = Selection.getSelectionEnd(buffer);
int selStart = Math.min(a, b);
int selEnd = Math.max(a, b);
if (selStart < 0) {
if (buffer.getSpanStart(FROM_BELOW) >= 0) {
selStart = selEnd = buffer.length();
}
}
if (selStart > last)
selStart = selEnd = Integer.MAX_VALUE;
if (selEnd < first)
selStart = selEnd = -1;
switch (what) {
case CLICK:
if (selStart == selEnd) {
return false;
}
ClickableSpan[] link = buffer.getSpans(selStart, selEnd, ClickableSpan.class);
if (link.length != 1)
return false;
link[0].onClick(widget);
break;
case UP:
int bestStart, bestEnd;
bestStart = -1;
bestEnd = -1;
for (int i = 0; i < candidates.length; i++) {
int end = buffer.getSpanEnd(candidates[i]);
if (end < selEnd || selStart == selEnd) {
if (end > bestEnd) {
bestStart = buffer.getSpanStart(candidates[i]);
bestEnd = end;
}
}
}
if (bestStart >= 0) {
Selection.setSelection(buffer, bestEnd, bestStart);
return true;
}
break;
case DOWN:
bestStart = Integer.MAX_VALUE;
bestEnd = Integer.MAX_VALUE;
for (int i = 0; i < candidates.length; i++) {
int start = buffer.getSpanStart(candidates[i]);
if (start > selStart || selStart == selEnd) {
if (start < bestStart) {
bestStart = start;
bestEnd = buffer.getSpanEnd(candidates[i]);
}
}
}
if (bestEnd < Integer.MAX_VALUE) {
Selection.setSelection(buffer, bestStart, bestEnd);
return true;
}
break;
}
return false;
}
@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[] links = buffer.getSpans(off, off, ClickableSpan.class);
if (links.length != 0) {
if (action == MotionEvent.ACTION_UP) {
links[0].onClick(widget);
} else if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(buffer,
buffer.getSpanStart(links[0]),
buffer.getSpanEnd(links[0]));
}
// return true;
} else {
Selection.removeSelection(buffer);
}
}
return super.onTouchEvent(widget, buffer, event);
}
@Override
public void initialize(TextView widget, Spannable text) {
Selection.removeSelection(text);
text.removeSpan(FROM_BELOW);
}
@Override
public void onTakeFocus(TextView view, Spannable text, int dir) {
Selection.removeSelection(text);
if ((dir & View.FOCUS_BACKWARD) != 0) {
text.setSpan(FROM_BELOW, 0, 0, Spannable.SPAN_POINT_POINT);
} else {
text.removeSpan(FROM_BELOW);
}
}
public static MovementMethod getInstance() {
if (sInstance == null)
sInstance = new MyMovement();
return sInstance;
}
private static MyMovement sInstance;
private static Object FROM_BELOW = new NoCopySpan.Concrete();
}