After a long and time consuming search, I can't find a component that can select text in textview for android API level <=11. I have written this component that may be of help to you :
public class SelectableTextView extends TextView {
public static int _SelectedBackgroundColor = 0xffA6D4E1;
public static int _SelectedTextColor = 0xff000000;
private OnTouchListener lastOnTouch;
protected int textOffsetStart;
protected int textOffsetEnd;
private OnLongClickListener lastOnLongClick;
protected boolean longCliked;
protected boolean isDowned;
protected int textSelectedEnd;
protected int textSelectedStart;
private static SelectableTextView lastInstance;
public SelectableTextView(Context context) {
super(context);
}
public void setTextIsSelectable(boolean selectable) {
// TODO:ANDROID3
// if:androidversion>=3
// super.setTextIsSelectable(selectable);
// else
super.setLongClickable(true);
super.setOnLongClickListener(getSelectableLongClick());
super.setOnTouchListener(getSelectableOnTouch());
}
private OnLongClickListener getSelectableLongClick() {
return new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
longCliked = true;
if (lastOnLongClick != null) {
lastOnLongClick.onLongClick(v);
}
return true;
}
};
}
@Override
public void setOnTouchListener(OnTouchListener l) {
super.setOnTouchListener(l);
this.lastOnTouch = l;
}
@Override
public void setOnLongClickListener(OnLongClickListener l) {
super.setOnLongClickListener(l);
this.lastOnLongClick = l;
}
private OnTouchListener getSelectableOnTouch() {
return new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
if (lastInstance == null)
lastInstance = SelectableTextView.this;
if (lastInstance != null && lastInstance != SelectableTextView.this) {
lastInstance.clean();
lastInstance = SelectableTextView.this;
}
int offset = getOffset(event);
if ((offset < textOffsetEnd && offset > textOffsetStart)
|| (offset > textOffsetEnd && offset < textOffsetStart)) {
if (textOffsetEnd - offset > offset - textOffsetStart)
textOffsetStart = textOffsetEnd;
} else {
clean();
textOffsetStart = offset;
}
isDowned = true;
} else if (isDowned && longCliked && action == MotionEvent.ACTION_MOVE) {
selectTextOnMove(event);
} else if (action == MotionEvent.ACTION_UP) {
isDowned = false;
longCliked = false;
}
if (lastOnTouch != null)
lastOnTouch.onTouch(v, event);
return false;
}
};
}
private void selectTextOnMove(MotionEvent event) {
int offset = getOffset(event);
if (offset != Integer.MIN_VALUE) {
String text = getText().toString();
SpannableStringBuilder sb = new SpannableStringBuilder(text);
BackgroundColorSpan bgc = new BackgroundColorSpan(_SelectedBackgroundColor);
ForegroundColorSpan textColor = new ForegroundColorSpan(_SelectedTextColor);
int start = textOffsetStart;
textOffsetEnd = offset;
int end = offset;
if (start > end) {
int temp = start;
start = end;
end = temp;
}
int[] curectStartEnd = curectStartEnd(text, start, end);
start = curectStartEnd[0];
end = curectStartEnd[1];
SelectableTextView.this.textSelectedStart = start;
SelectableTextView.this.textSelectedEnd = end;
sb.setSpan(bgc, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
sb.setSpan(textColor, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
setText(sb);
}
}
private int[] curectStartEnd(String text, int start, int end) {
int length = text.length();
while (start < length && start > 0 && text.charAt(start) != ' ') {
start--;
}
while (end < length && text.charAt(end) != ' ') {
end++;
}
return new int[] { start, end };
}
private int getOffset(MotionEvent event) {
Layout layout = getLayout();
if (layout == null)
return Integer.MIN_VALUE;
float x = event.getX() + getScrollX();
float y = event.getY() + getScrollY();
int line = layout.getLineForVertical((int) y);
int offset = layout.getOffsetForHorizontal(line, x);
return offset;
}
protected void clean() {
if (this.getText() != null) {
this.setText(this.getText().toString());
textSelectedStart = 0;
textSelectedEnd = 0;
}
}
@Override
public int getSelectionStart() {
return textSelectedStart;
}
@Override
public int getSelectionEnd() {
return textSelectedEnd;
}
}
getOffset
get the selected offset of text that Touched user for using this component set these attributes:
SelectableTextView textView1 = new SelectableTextView(context);
textView1.setClickable(false);
textView1.setCursorVisible(false);
textView1.setOnTouchListener(getOnTextTouch());//new after text select touch
textView1.setEnabled(this.selectable);
textView1.setTextIsSelectable(this.selectable);
Can anyone upgrade this component?