Android仿微信@好友功能 輸入@跳轉(zhuǎn)、刪除整塊
最近在做聊天功能的時候,有一個需求是仿照微信做@好友的功能,本來以為挺簡單,但是做到這塊的時候,發(fā)現(xiàn)和想象的有點(diǎn)不一樣,什么整塊刪除,塊可編輯,總之,加個@的功能很簡單,但是要做和微信的一樣還是費(fèi)了一些功夫,下面是一個demo僅供參考,防止遺忘
先上個效果圖

就是這么個功能
1. 分析需求
輸入@跳轉(zhuǎn)到聯(lián)系人界面,選中一個或者多個好友返回到當(dāng)前界面
按退格鍵刪除整塊內(nèi)容
塊內(nèi)的內(nèi)容可編輯,編輯完了之后將不附帶@功能,只是單純的文字
2. 開始編碼
既然是文本輸入首先繼承EditText自定義一個控件
public class MsgEditText extends AppCompatEditText {
public MsgEditText(Context context) {
super(context);
}
public MsgEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MsgEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
到底從哪里開始入手呢,首先完成變成塊的需求,
無意中看到這個項(xiàng)目https://github.com/g707175425/CloudEditText ,他是這么寫的
private void generateOneSpan(Spannable spannableString, UnSpanText unSpanText) {
//生成一個TextView
View spanView = getSpanView(getContext(), unSpanText.showText.toString(), getMeasuredWidth());
//再將TextView轉(zhuǎn)換為一個圖片
BitmapDrawable bitmpaDrawable = (BitmapDrawable) UIUtils.convertViewToDrawable(spanView);
bitmpaDrawable.setBounds(0, 0, bitmpaDrawable.getIntrinsicWidth(), bitmpaDrawable.getIntrinsicHeight());
//最后將這個圖片放到Span里,
MyImageSpan what = new MyImageSpan(bitmpaDrawable, unSpanText.showText.toString(),unSpanText.returnText);
final int start = unSpanText.start;
final int end = unSpanText.end;
spannableString.setSpan(what, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
//設(shè)置一個Span
spannableString.setSpan(touchableSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
看到這里我們就記得了一個關(guān)于SpanableString的用法,它可以設(shè)置圖片,可以隨意的設(shè)置文字的背景的前景,等等一系列比較酷炫的效果,而且只需要一個TextView,如果需要深入了解Span,可自行百度和Google,關(guān)于Span的進(jìn)階用法,于是就有了下面的實(shí)現(xiàn)
//這個是需要成塊刪除的內(nèi)容
private class MyTextSpan extends MetricAffectingSpan {
private String showText;
private long userId;
//userId是為了適應(yīng)需求,如果不需要請自行去掉
public MyTextSpan(String showText, long userId) {
this.showText = showText;
this.userId = userId;
}
public String getShowText() {
return showText;
}
public long getUserId() {
return userId;
}
@Override
public void updateMeasureState(TextPaint p) {
}
@Override
public void updateDrawState(TextPaint tp) {
}
}
//這個是非整塊刪除的內(nèi)容,當(dāng)然你如果想也是可以刪除的
private class UnSpanText {
int start;
int end;
String returnText;
UnSpanText(int start, int end, String returnText) {
this.start = start;
this.end = end;
this.returnText = returnText;
}
}
剛開始我是這么寫的
//外部調(diào)用一個增加Span的方法
public void addSpan(String showText, String returnText, long userId) {
getText().append(showText);
SpannableString spannableString = new SpannableString(getText());
makeSpan(spannableString, new UnSpanText(spannableString.length() - showText.length(), spannableString.length(), showText, returnText), userId);
setText(spannableString);
setSelection(spannableString.length());
}
//生成一個需要整體刪除的Span
private void makeSpan(Spannable sps, UnSpanText unSpanText, long userId) {
MyTextSpan what = new MyTextSpan(unSpanText.returnText, userId);
int start = unSpanText.start;
int end = unSpanText.end;
sps.setSpan(what, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
寫到現(xiàn)在這個整塊添加已經(jīng)做好了,下面開始做整塊刪除,剛開始的時候我是模仿上面的CloudEditText寫的,但我發(fā)現(xiàn)好像會用各種問題,于是想了一種方法
@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
super.onTextChanged(text, start, lengthBefore, lengthAfter);
//向前刪除一個字符,@后的內(nèi)容必須大于一個字符,可以在后面加一個空格
if (lengthBefore == 1 && lengthAfter == 0) {
MyTextSpan[] spans = getText().getSpans(0, getText().length(), MyTextSpan.class);
for (MyTextSpan myImageSpan : spans) {
if (getText().getSpanEnd(myImageSpan) == start && !text.toString().endsWith(myImageSpan.getShowText())) {
getText().delete(getText().getSpanStart(myImageSpan), getText().getSpanEnd(myImageSpan));
break;
}
}
}
}
上面的意思就是,如果你在EditText中執(zhí)行刪除一個字符的時候,判斷前面一個是否是一個Span,如果是自定義的Span就把Span一同刪除,關(guān)于這個,我可是測試可各種操作才定為這樣的
最后是獲取需要@的人員名單
//獲取用戶Id列表,這只是個參考,可根據(jù)需求修改
public String getUserIdString() {
MyTextSpan[] spans = getText().getSpans(0, getText().length(), MyTextSpan.class);
StringBuilder builder = new StringBuilder();
for (MyTextSpan myTextSpan : spans) {
String realText = getText().toString().substring(getText().getSpanStart(myTextSpan), getText().getSpanEnd(myTextSpan));
String showText = myTextSpan.getShowText();
if (realText.equals(showText)) {
builder.append(myTextSpan.getUserId()).append(",");
}
}
if (!TextUtils.isEmpty(builder.toString())) {
builder.deleteCharAt(builder.length() - 1);
}
return builder.toString();
}
最后我就大方的放個地址你們自己看吧
https://github.com/ddssingsong/AtFriend
總結(jié)
以上所述是小編給大家介紹的Android仿微信@好友功能 輸入@跳轉(zhuǎn)、刪除整塊,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
很詳細(xì)的android序列化過程Parcelable
這篇文章主要為大家詳細(xì)介紹了很詳細(xì)的android序列化過程Parcelable,代碼注釋很詳細(xì),感興趣的小伙伴們可以參考一下2016-08-08
android開發(fā)基礎(chǔ)教程—文件存儲功能實(shí)現(xiàn)
文件存儲功能在實(shí)現(xiàn)數(shù)據(jù)讀寫時會頻繁使用到,接下來介紹文件存儲功能的實(shí)現(xiàn),感興趣的朋友可以了解下2013-01-01

