/**
* @ 对象
* Created by swing on 2019/7/2 0002.
*/
public class AUser {
public AUser() {
}
public AUser(String callNickName, String callPid) {
this.callNickName = callNickName;
this.callPid = callPid;
}
/**
* callNickName : string
* callPid : string
*/
private String callNickName;
private String callPid;
public String getCallNickName() {
return callNickName;
}
public void setCallNickName(String callNickName) {
this.callNickName = callNickName;
}
public String getCallPid() {
return callPid;
}
public void setCallPid(String callPid) {
this.callPid = callPid;
}
}
/**
* EditText的@处理 未处理剪裁复制时的逻辑
* Created by swing on 2019/6/26 0026.
*/
public class SuperTextWatcher implements android.text.TextWatcher {
public static final String ISEDITTEXTINPUTA = "isEditTextInputA";
public static final String NAME = "name";
public static final String ID = "id";
private static String a = "@";
private static String startDevider = "" + a;
private static String endDevider = " ";
private Activity activity;
private EditText editText;
private int requestCode;
private SpannableString spnableInfo;
private List aUsers;
public SuperTextWatcher(Activity activity, EditText editText, List aUsers) {
this.activity = activity;
this.editText = editText;
this.aUsers = aUsers;
}
/**
* @param start: 字符串中即将发生修改的位置。
* @param count: 字符串中即将被修改的文字的长度。如果是新增的话则为0。
* @param after: 被修改的文字修改之后的长度。如果是删除的话则为0。
*/
@Override
public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
if (spnableInfo == null) {
spnableInfo = getASpan(activity, new SpannableString(charSequence), aUsers);
}
//如果光标在用户名中间输入时将光标移动至结尾
String previousString = charSequence.toString().substring(0, start);
String nextString = charSequence.toString().substring(start, charSequence.length());
int previousStartIndex = previousString.lastIndexOf(startDevider);
int previousEndIndex = previousString.lastIndexOf(endDevider);
int nextStartIndex = nextString.indexOf(startDevider);
int nextEndIndex = nextString.indexOf(endDevider);
if (editText != null
&& previousStartIndex != -1
&& previousStartIndex > previousEndIndex
&& nextEndIndex != -1
&& (nextStartIndex == -1 || nextEndIndex < nextStartIndex)) {
editText.setText(spnableInfo);
editText.setSelection(spnableInfo.length());
}
//如果删除字符时是用户名则删除用户名(包含开始结束符)
if (count > 0 && after == 0) {
String subString = charSequence.toString().substring(0, start);
if (subString.contains(startDevider)) {
int lastStart = subString.lastIndexOf(startDevider);
int lastEnd = subString.lastIndexOf(endDevider);
if (charSequence.toString().lastIndexOf(endDevider) == start - endDevider.length() + 1
&& (lastEnd == -1 || lastEnd < lastStart)) {
if (editText != null && spnableInfo != null) {
//暂时只能删除最后一个,随机删除待处理
editText.setText(spnableInfo.subSequence(0, lastStart));
editText.setSelection(editText.getText().toString().length());
if (!aUsers.isEmpty()) {
aUsers.remove(aUsers.size() - 1);
}
}
onInputTextAdelete(subString.lastIndexOf(startDevider));
}
}
}
}
/**
* @param start: 有变动的字符串的序号
* @param before: 被改变的字符串长度,如果是新增则为0。
* @param count: 添加的字符串长度,如果是删除则为0。
*/
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
if (count == 1 && before == 0) {
String subString = charSequence.toString().substring(start, start + count);
if (subString.contains(a)) {
onInputTextA(start);
}
}
}
@Override
public void afterTextChanged(Editable editable) {
}
/**
* @param start 输入@的位置
*/
public void onInputTextA(int start) {
toActivity(activity, "/myself/MyAttentionActivity", 1100);
}
/**
* @param end 删除@的位置
*/
public void onInputTextAdelete(int end) {
}
/**
* 输入@后跳转目标
*
* @param activity 源
* @param url 目标
*/
public void toActivity(Activity activity, String url, int requestCode) {
this.requestCode = requestCode;
if (this.activity == null)
this.activity = activity;
ARouter.getInstance()
.build(url)
.withBoolean(ISEDITTEXTINPUTA, true)
.withTransition(ActivityHelper.getNextActivityAnimShow(), ActivityHelper.getCurrentActivityAnimShow())
.navigation(activity, requestCode);
}
/**
* 回退响应结果
*/
public void onActivityResult(int requestCode, @Nullable Intent data) {
if (this.requestCode == requestCode) {
onAttentionActivityResult(data);
} else if (requestCode == 800) {
if (editText != null)
editText.setSelection(editText.getText().toString().length());
}
}
/**
* 关注人列表页回退响应结果
*/
private void onAttentionActivityResult(@Nullable Intent data) {
String name = "";
String id = "";
if (data.hasExtra(NAME))
name = data.getStringExtra(NAME);
if (data.hasExtra(ID))
id = data.getStringExtra(ID);
String content = editText.getText().toString();
for (AUser aUser : aUsers) {
if (aUser.getCallPid().equals(id)) {
if (content.endsWith(a)) {
content = content.substring(0, content.length() - 1);
spnableInfo = new SpannableString(content);
}
SpannableString nameSpannableString = getASpan(activity, spnableInfo, aUsers);
editText.setText(nameSpannableString);
editText.setMovementMethod(LinkMovementMethod.getInstance());
editText.setSelection(nameSpannableString.length());
return;
}
}
aUsers.add(new AUser(name, id));
SpannableString nameSpannableString = getSpan(content, name);
editText.setText(nameSpannableString);
editText.setMovementMethod(LinkMovementMethod.getInstance());
editText.setSelection(nameSpannableString.length());
}
private SpannableString getSpan(String content, String name) {
if (content.endsWith(a)) {
content = content.substring(0, content.length() - 1);
}
String nameA = startDevider + name + endDevider;
content = content + nameA;
spnableInfo = new SpannableString(content);
getASpan(activity, spnableInfo, aUsers);
return spnableInfo;
}
/**
* 跳转他人个人页面
*
* @param activity 源
* @param url 目标
*/
private static void toOtherPeopleActivity(Activity activity, String url, String id, int requestCode) {
ARouter.getInstance().build(url)
.withString(ID, id)
.navigation(activity, requestCode);
}
/**
* 对字符串添加@特效
*
* @param spnableInfo 原始文本
* @param aUsers 人员列表
*/
public static SpannableString getASpan(Activity activity, SpannableString spnableInfo, @NonNull List aUsers) {
String content = spnableInfo.toString();
if (content.endsWith(a))
content = content.substring(0, content.lastIndexOf(a));
int index = 0;
int dividerStart = content.indexOf(startDevider);
int dividerEnd = content.indexOf(endDevider);
if (dividerStart == -1 || dividerEnd == -1) {
spnableInfo.setSpan(null, index, spnableInfo.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spnableInfo.setSpan(new ForegroundColorSpan(Color.parseColor("#FF333333")), index, spnableInfo.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return spnableInfo;
}
for (int i = 0; i < Integer.MAX_VALUE; i++) {
spnableInfo.setSpan(null, index, dividerStart, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spnableInfo.setSpan(new ForegroundColorSpan(Color.parseColor("#FF333333")), index, dividerStart, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spnableInfo.setSpan(null, dividerStart, dividerStart + startDevider.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spnableInfo.setSpan(new ForegroundColorSpan(Color.parseColor("#FF2274D0")), dividerStart, dividerStart + startDevider.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
//aUsers的顺序必须是文本中@的顺序,可使用name判断增加匹配度
spnableInfo.setSpan(new AClickableSpan(activity, aUsers.size() > i ? aUsers.get(i) : null), dividerStart + startDevider.length(), dividerEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spnableInfo.setSpan(new ForegroundColorSpan(Color.parseColor("#FF2274D0")), dividerStart + startDevider.length(), dividerEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spnableInfo.setSpan(null, dividerEnd, dividerEnd + endDevider.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spnableInfo.setSpan(new ForegroundColorSpan(Color.parseColor("#FF2274D0")), dividerEnd, dividerEnd + endDevider.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
index = dividerEnd + endDevider.length();
if (index >= spnableInfo.length()) {
break;
}
content = spnableInfo.toString().substring(index);
dividerStart = content.indexOf(startDevider);
if (dividerStart == -1) {
break;
}
dividerEnd = content.substring(dividerStart).indexOf(endDevider) + dividerStart;
dividerStart = dividerStart + index;
dividerEnd = dividerEnd + index;
}
return spnableInfo;
}
public List getaUsers() {
return aUsers;
}
public void setaUsers(List aUsers) {
this.aUsers = aUsers;
}
static class AClickableSpan extends ClickableSpan {
private AUser aUser;
private Activity activity;
public AClickableSpan(Activity activity, AUser aUser) {
this.aUser = aUser;
this.activity = activity;
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
}
@Override
public void onClick(View widget) {
if (aUser != null && aUser.getCallPid() != null)
toOtherPeopleActivity(activity, "/myself/OtherPeopleActivity", aUser.getCallPid(), 800);
}
}
}