下面列出了android.text.Editable#length ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void highlightInConference(String nick) {
final Editable editable = this.binding.textinput.getText();
String oldString = editable.toString().trim();
final int pos = this.binding.textinput.getSelectionStart();
if (oldString.isEmpty() || pos == 0) {
editable.insert(0, nick + ": ");
} else {
final char before = editable.charAt(pos - 1);
final char after = editable.length() > pos ? editable.charAt(pos) : '\0';
if (before == '\n') {
editable.insert(pos, nick + ": ");
} else {
if (pos > 2 && editable.subSequence(pos - 2, pos).toString().equals(": ")) {
if (NickValidityChecker.check(conversation, Arrays.asList(editable.subSequence(0, pos - 2).toString().split(", ")))) {
editable.insert(pos - 2, ", " + nick);
return;
}
}
editable.insert(pos, (Character.isWhitespace(before) ? "" : " ") + nick + (Character.isWhitespace(after) ? "" : " "));
if (Character.isWhitespace(after)) {
this.binding.textinput.setSelection(this.binding.textinput.getSelectionStart() + 1);
}
}
}
}
private void end(Editable output, Class kind, Object repl, boolean paragraphStyle) {
Object obj = getLast(output, kind);
// start of the tag
int where = output.getSpanStart(obj);
// end of the tag
int len = output.length();
output.removeSpan(obj);
if (where != len) {
// paragraph styles like AlignmentSpan need to end with a new line!
if (paragraphStyle) {
output.append("\n");
len++;
}
output.setSpan(repl, where, len, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (HtmlTextView.DEBUG) {
Log.d(HtmlTextView.TAG, "where: " + where);
Log.d(HtmlTextView.TAG, "len: " + len);
}
}
@Override
public void handleTag(boolean opening, String tag, Editable output,
XMLReader xmlReader) {
processAttributes(xmlReader);
if(tag.equalsIgnoreCase("span")){
if(opening){
startSpan(tag, output, xmlReader);
}else{
endSpan(tag, output, xmlReader);
attributes.clear();
}
}else if (tag.toLowerCase(Locale.getDefault()).equals("img")) {
// 处理标签<img>
// 获取长度
if (null != mImgClickListener) {
int len = output.length();
// 获取图片地址
ImageSpan[] images = output.getSpans(len - 1, len, ImageSpan.class);
String imgURL = images[0].getSource();
// 使图片可点击并监听点击事件
output.setSpan(new ClickableImage(imgURL), len - 1, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
public void setText(Editable text, int flag) {
if (flag == 1) {
// this.text = text;
if (editor != null)
editor.setText(text);
return;
}
int length = 0;
if (text != null) {
length = text.length();
}
replaceText(0, length, text);
setDirty(false);
}
@Override
public void afterTextChanged(Editable s) {
if (s.length() == 0) {
showErrorToolTip(mUsernameErrorTooltip,
getString(R.string.message_account_username_mandatory));
} else {
mUsernameErrorTooltip.setVisibility(View.GONE);
}
}
private static void end(Editable text, Class<?> kind, Object... replaces) {
int len = text.length();
Object obj = getLast(text, kind);
int where = text.getSpanStart(obj);
text.removeSpan(obj);
if (where != len) {
for (Object replace : replaces) {
text.setSpan(replace, where, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return;
}
@Override //文本改变后
public void afterTextChanged(Editable s) {
//判断是不是群聊
if (isFromChatRoom) {
mAtManager.afterTextChanged(s);
//根据当前是删除了字段或者新写字段来判断是否开启@界面
if (!canShowAtActivity) {
canShowAtActivity = true;
return;
}
//根据当前光标判断 并且还是"@" 才可开启AtListActivity
//里面应该相关群成员列表
// int atIndex = edit_msg.getSelectionStart();
// if (atIndex > 0) {
// String at = s.subSequence(atIndex - 1, atIndex).toString();
// if (at.equals("@")) {
// Intent intent = new Intent(PbChatActivity.this, AtListActivity.class);
// intent.putExtra("jid", jid);
// startActivityForResult(intent, AT_MEMBER);
// }
// }
} else {
//todo:向对方发送当前正在输入的状态
//判断字段长度大于0 防止刚发送消息后,清空msg时调用了本方法
if (s.length() > 0) {
chatingPresenter.sendTypingStatus();
}
// //consult消息发送到的是一个无效的虚拟帐号 所以暂时不做typing
// if (TextUtils.isEmpty(realUser)) {
//
//// chatingPresenter.sendTypingStatus();
// }
}
}
private static int insertAtEnd(EditTextSelectionState selectionState,
CharSequence textToInsert) {
Editable editableText = selectionState.getEditText().getEditableText();
int insertPos = editableText.length();
editableText.append(textToInsert);
return insertPos;
}
@Override
public void afterTextChanged(Editable editable) {
if (editable.length() > 0) {
showEditClear();
} else {
hideEditClear();
hideSwipLoading();
mSearchPresenter.unsubscribe();
mRecyclerViewSearch.setEmpty();
mSearchListAdapter.mData = null;
mSearchListAdapter.notifyDataSetChanged();
showSearchHistory();
mSearchPresenter.queryHistory();
}
}
private void sendCurrentText() {
if (!mDummyMode) {
return;
}
Editable content = getEditable();
if (content != null) {
final int N = content.length();
if (N == 0) {
return;
}
if (N == 1) {
// If it's 1 character, we have a chance of being
// able to generate normal key events...
if (mKeyCharacterMap == null) {
mKeyCharacterMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
}
char[] chars = new char[1];
content.getChars(0, 1, chars, 0);
KeyEvent[] events = mKeyCharacterMap.getEvents(chars);
if (events != null) {
for (int i=0; i<events.length; i++) {
if (DEBUG) Log.v(TAG, "Sending: " + events[i]);
sendKeyEvent(events[i]);
}
content.clear();
return;
}
}
// Otherwise, revert to the special key event containing
// the actual characters.
KeyEvent event = new KeyEvent(SystemClock.uptimeMillis(),
content.toString(), KeyCharacterMap.VIRTUAL_KEYBOARD, 0);
sendKeyEvent(event);
content.clear();
}
}
@Override
public void afterTextChanged(Editable s) {
if (s.length() > 0 && !labelShown) {
labelShown = true;
getAnimator().start();
} else if (s.length() == 0 && labelShown) {
labelShown = false;
getAnimator().reverse();
}
}
@Override
public void afterTextChanged(Editable s) {
mEditTextCallback.changeErrorView();
mEditTextCallback.toggleLineColorOnError(false);
if (s.length() == 0) {
mEditTextCallback.saveIdentificationNumber("");
}
}
@Override
public void afterTextChanged(Editable s)
{
// disable buttons if there is no title
boolean enabled = s == null || s.length() != 0;
mSaveButton.setEnabled(enabled);
mSaveAndNextButton.setEnabled(enabled);
}
@Nullable
protected CharSequence getWordInCursor() {
int pos = getSelectionStart();
if (pos == -1) return "";
Editable editableText = getEditableText();
int start = pos, end = pos;
while (start > 0 && Character.isLetterOrDigit(editableText.charAt(start))) start--;
while (end < editableText.length() && Character.isLetterOrDigit(editableText.charAt(start)))
end++;
return editableText.subSequence(start, end);
}
private void findClose(char open, int selEnd) {
Log.d(TAG, "findClose() called with: open = [" + open + "], selEnd = [" + selEnd + "]");
Editable text = editText.getText();
int cursor = selEnd + 1;
int count = 1;
char close = getClose(open);
boolean find = false;
while (cursor < text.length()) {
char chatAtCursor = text.charAt(cursor);
if (chatAtCursor == open) {
count++;
} else if (chatAtCursor == close) {
count--;
}
if (count == 0) {
find = true;
break;
}
cursor++;
}
BracketSpan[] spans = text.getSpans(0, text.length(), BracketSpan.class);
for (BracketSpan span : spans) {
text.removeSpan(span);
}
text.setSpan(new BracketSpan(codeTheme.getBracketColor(),
codeTheme.getTextColor()), selEnd, selEnd + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (find) {
text.setSpan(new BracketSpan(codeTheme.getBracketColor(),
codeTheme.getTextColor()), cursor, cursor + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
private void executeAT() {
// It seem that MTK devices doesn't need "\r" but QC devices do.
// We need a device-type check here, perhaps: gsm.version.ril-impl.
Editable cmd = mAtCommand.getText();
if (cmd != null && cmd.length() != 0) {
Log.d(TAG, mTAG + "ExecuteAT: attempting to send: " + cmd.toString());
if (getSerialDevice() != null) {
mCommandTerminal.send(cmd.toString(), new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message message) {
if (message.obj instanceof List) {
// Fixme: unchecked cast
List<String> lines = ((List<String>) message.obj);
StringBuffer response = new StringBuffer();
for (String line : lines) {
response.append(line);
response.append('\n');
}
if (response.length() != 0) {
mAtResponse.append(response);
}
} else if (message.obj instanceof IOException) {
mAtResponse.append("IOException: " + ((IOException) message.obj).getMessage() + "\n");
}
}
}.obtainMessage());
}
}
}
private void formatMask(final Editable editable, int start, boolean deletion) {
start = clearPlaceholders(editable, start);
if (start == -1) {
return;
}
if (deletion
&& start == editable.length()
&& ((mMode == MODE_MASK && mEmptyPlaceholder == 0)
|| (mMode == MODE_HINT && mHintText == null))) {
return;
}
int indexInStyle = start + rangeCountEscapeChar(start);
int indexInText = start;
int selectionIndex = -1;
boolean nextCharIsText = false;
final int styleLength = mFormatStyle.length();
while (indexInStyle < styleLength) {
char charInStyle = mFormatStyle.charAt(indexInStyle);
if (!nextCharIsText && isMaskChar(charInStyle)) {
if (indexInText >= editable.length()) {
if (mMode == MODE_MASK) {
if (mEmptyPlaceholder != 0) {
editable.insert(indexInText, String.valueOf(mEmptyPlaceholder));
editable.setSpan(
new EmptyPlaceholderSpan(),
indexInText,
indexInText + 1,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
indexInText += 1;
indexInStyle += 1;
} else {
break;
}
} else {
if (mHintText == null) {
break;
}
editable.insert(
indexInText, mHintText.subSequence(indexInText, indexInText + 1));
editable.setSpan(
new HintPlaceholderSpan(
mHintColor == Color.TRANSPARENT
? getCurrentHintTextColor()
: mHintColor),
indexInText,
indexInText + 1,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
indexInText += 1;
indexInStyle += 1;
}
} else if (isMismatchMask(charInStyle, editable.charAt(indexInText))) {
editable.delete(indexInText, indexInText + 1);
} else {
indexInText += 1;
indexInStyle += 1;
}
} else if (!nextCharIsText && charInStyle == ESCAPE_CHAR) {
nextCharIsText = true;
indexInStyle += 1;
} else {
editable.insert(indexInText, String.valueOf(charInStyle));
editable.setSpan(
new PlaceholderSpan(),
indexInText,
indexInText + 1,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
nextCharIsText = false;
indexInText += 1;
indexInStyle += 1;
if (selectionIndex == -1 || indexInText == selectionIndex + 1) {
selectionIndex = indexInText;
}
}
}
if (deletion && start == 0 && selectionIndex != -1) {
editable.setSpan(
SELECTION_SPAN, selectionIndex, selectionIndex, Spanned.SPAN_MARK_MARK);
}
}
private void start(Editable text, Object mark) {
int len = text.length();
text.setSpan(mark, len, len, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
private Editable highlight(Editable e) {
try {
int length = e.length();
// don't use e.clearSpans() because it will
// remove too much
clearSpans(e, length);
if (length == 0) {
return e;
}
if (errorLine > 0) {
Matcher m = PATTERN_LINE.matcher(e);
for (int i = errorLine; i-- > 0 && m.find(); ) {
// {} because analyzers don't like for (); statements
}
e.setSpan(
new BackgroundColorSpan(colorError),
m.start(),
m.end(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (ShaderEditorApp.preferences.disableHighlighting() &&
length > 4096) {
return e;
}
for (Matcher m = PATTERN_NUMBERS.matcher(e); m.find(); ) {
e.setSpan(
new ForegroundColorSpan(colorNumber),
m.start(),
m.end(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
for (Matcher m = PATTERN_PREPROCESSOR.matcher(e); m.find(); ) {
e.setSpan(
new ForegroundColorSpan(colorKeyword),
m.start(),
m.end(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
for (Matcher m = PATTERN_KEYWORDS.matcher(e); m.find(); ) {
e.setSpan(
new ForegroundColorSpan(colorKeyword),
m.start(),
m.end(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
for (Matcher m = PATTERN_BUILTINS.matcher(e); m.find(); ) {
e.setSpan(
new ForegroundColorSpan(colorBuiltin),
m.start(),
m.end(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
for (Matcher m = PATTERN_COMMENTS.matcher(e); m.find(); ) {
e.setSpan(
new ForegroundColorSpan(colorComment),
m.start(),
m.end(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
} catch (IllegalStateException ex) {
// raised by Matcher.start()/.end() when
// no successful match has been made what
// shouldn't ever happen because of find()
}
return e;
}
List<RichEditorBlock> getContent() {
List<RichEditorBlock> richEditorBlockList = new ArrayList<>();
Editable editableTmp = mRichEditText.getEditableText();
if (editableTmp.length() <= 0) {
return richEditorBlockList;
}
String editTextContent = mRichEditText.getEditableText().toString();
//为了代码容易处理,如果文本末尾不是'\n',则强制在末尾增加一个回车
if (editTextContent.charAt(editableTmp.length() - 1) != '\n') {
editTextContent += "\n";
}
Editable editable = mRichEditText.getEditableText();
int editTextLen = editTextContent.length();
// 先获取所有\n的位置
List<Integer> enterCharPosList = new ArrayList<>();
for (int i = 0; i < editTextLen; i++) {
if (editTextContent.charAt(i) == '\n') {
enterCharPosList.add(i);
}
}
int enterCharSize = enterCharPosList.size();
// 通过换行符(\n)来遍历每个段落,每个段落处理一个段落样式和多个行内样式
for (int i = 0; i < enterCharSize; i++) {
// 段落的起始位置
int blockStart = i == 0 ? 0 : enterCharPosList.get(i - 1) + 1;
int enterCharPos = enterCharPosList.get(i);
// 先处理段落样式, 包含普通文本、标题、引用、BlockImageSpan
BlockImageSpan[] blockImageSpans = editable.getSpans(enterCharPos - 1, enterCharPos, BlockImageSpan.class);
if (blockImageSpans.length > 0) {
// 说明当前段落是ImageSpan, 没有行内样式
BlockImageSpan blockImageSpan = blockImageSpans[0];
IBlockImageSpanObtainObject spanObtainObject = blockImageSpan.getBlockImageSpanVm().getSpanObject();
richEditorBlockList.add(
getRichEditorBlock(
spanObtainObject.getType(), null, spanObtainObject, null
)
);
continue;
}
// 当前段落文本
String blockTextContent;
if (i == 0) {
// 第一段就是普通文本
blockTextContent = editTextContent.substring(0, enterCharPos);
} else {
blockTextContent = editTextContent.substring(enterCharPosList.get(i - 1) + 1, enterCharPos);
}
IBlockSpan[] blockSpans = editable.getSpans(enterCharPos - 1, enterCharPos, IBlockSpan.class);
if (blockSpans.length > 0) {
IBlockSpan blockSpan = blockSpans[0];
richEditorBlockList.add(
getRichEditorBlock(
blockSpan.getType(), blockTextContent, null, getInlineStyleEntities(blockStart, enterCharPos)
)
);
continue;
}
// TODO 后续有新增Block类型再说
// 剩下的就是普通文本(可能包含行内样式)
richEditorBlockList.add(
getRichEditorBlock(
RichTypeEnum.BLOCK_NORMAL_TEXT, blockTextContent, null, getInlineStyleEntities(blockStart, enterCharPos)
)
);
}
return richEditorBlockList;
}