写在前面:
最近心态有点暴
工程项目中,有个功能,发布功能,发布View可以选择@好友列表进行对应格式显示,直接上图
效果就是类似这个了。选择好友后,回调过来直接在页面显示对应格式、并且点击删除按钮,直接删除刚才的完整@好友的字段(注意,不是一个个文字删除)
好了。直接上源码:
* Desc:@联系人 整块删除 不可编辑
*
* Author:
* Date: 2018-09-13
* Copyright: Copyright (c) 2010-2018
* Company:
* Updater:
* Update Time:
* Update Comments:
*/
public class ContactEditText extends AppCompatAutoCompleteTextView {
private int itemPadding;
private String content = "";
public ContactEditText(Context context) {
super(context);
init();
}
public ContactEditText(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ContactEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
itemPadding = dip2px(getContext(), 3);
}
@Override
protected void onSelectionChanged(int selStart, int selEnd) {
MyImageSpan[] spans = getText().getSpans(0, getText().length(), MyImageSpan.class);
for (MyImageSpan myImageSpan : spans) {
if (getText().getSpanEnd(myImageSpan) - 1 == selStart) {
selStart = selStart + 1;
setSelection(selStart);
break;
}
}
super.onSelectionChanged(selStart, selEnd);
}
private void flushSpans() {
Editable editText = getText();
Spannable spannableString = new SpannableString(editText);
MyImageSpan[] spans = spannableString.getSpans(0, editText.length(), MyImageSpan.class);
List texts = getAllTexts(spans, editText);
for (UnSpanText unSpanText : texts) {
if (!TextUtils.isEmpty(unSpanText.showText.toString().trim())) {
generateOneSpan(spannableString, unSpanText);
}
}
setText(spannableString);
setSelection(spannableString.length());
}
private List getAllTexts(MyImageSpan[] spans, Editable edittext) {
List texts = new ArrayList<>();
int start;
int end;
CharSequence text;
List sortStartEnds = new ArrayList<>();
sortStartEnds.add(0);
for (MyImageSpan myImageSpan : spans) {
sortStartEnds.add(edittext.getSpanStart(myImageSpan));
sortStartEnds.add(edittext.getSpanEnd(myImageSpan));
}
sortStartEnds.add(edittext.length());
Collections.sort(sortStartEnds);
for (int i = 0; i < sortStartEnds.size(); i = i + 2) {
start = sortStartEnds.get(i);
end = sortStartEnds.get(i + 1);
text = edittext.subSequence(start, end);
if (!TextUtils.isEmpty(text)) {
// TODO: 2018/9/13 这里的ID为测试id
texts.add(new UnSpanText(start, end, text, "-1"));
}
}
return texts;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_DOWN) {
// flushSpans();//文字转换成图片块 这里是自动联想的功能,可根据需求进行添加
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
protected void performFiltering(CharSequence text, int keyCode) {
Log.d("dds", "performFiltering" + text + ":" + keyCode);
super.performFiltering(text, keyCode);
}
//添加一个Span
public void addSpan(PatRecordUserBean userBean) {
String showText = userBean.getUserName();
String showId = userBean.getUserId();
getText().append(showText);
SpannableString spannableString = new SpannableString(getText());
generateOneSpan(spannableString, new UnSpanText(spannableString.length() - showText.length(), spannableString.length(), showText, showId));
setText(spannableString);
setSelection(spannableString.length());
}
public void insertSpan(PatRecordUserBean userBean) {//根据位置插入
String showText = userBean.getUserName();
String showId = userBean.getUserId();
Editable editable = getText();
int start = getSelectionStart();
int end = start + showText.length();
editable.insert(start, showText);
SpannableString spannableString = new SpannableString(getText());
generateOneSpan(spannableString, new UnSpanText(start, end, showText, showId));
setText(spannableString);
setSelection(end);
}
public void insertText(String insertData) {//插入文案信息
if (null != insertData) {
CharSequence charSequence = insertData;
Editable editable = getText();
int start = getSelectionStart();
int end = start + charSequence.length();
editable.insert(start, charSequence);
}
}
private void generateOneSpan(Spannable spannableString, UnSpanText unSpanText) {
//文字转图片
View spanView = getSpanView(getContext(), unSpanText.showText.toString(), getMeasuredWidth());
BitmapDrawable bitmapDrawable = (BitmapDrawable) convertViewToDrawable(spanView);
bitmapDrawable.setBounds(0, 0, bitmapDrawable.getIntrinsicWidth(), bitmapDrawable.getIntrinsicHeight());
MyImageSpan what = new MyImageSpan(bitmapDrawable, unSpanText.showText.toString(), unSpanText.showId);
final int start = unSpanText.start;
final int end = unSpanText.end;
spannableString.setSpan(what, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
public Drawable convertViewToDrawable(View view) {
int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
view.measure(spec, spec);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
c.translate(-view.getScrollX(), -view.getScrollY());
view.draw(c);
view.setDrawingCacheEnabled(true);
Bitmap cacheBmp = view.getDrawingCache();
Bitmap viewBmp = cacheBmp.copy(Bitmap.Config.ARGB_8888, true);
cacheBmp.recycle();
view.destroyDrawingCache();
return new BitmapDrawable(viewBmp);
}
public View getSpanView(Context context, String text, int maxWidth) {
TextView view = new TextView(context);
// view.setMaxWidth(maxWidth);
// view.setText(text);
// view.setEllipsize(TextUtils.TruncateAt.END);
// view.setSingleLine(true);
view.setText(text);
//设置文字框背景色
// view.setBackgroundResource(R.drawable.shape_corner_rectangle);
//view.setBackgroundResource(R.drawable.shape_corner_rectangle);
view.setTextSize(getTextSize());
//设置文字颜色
//view.setTextColor(getCurrentTextColor());
view.setTextColor(Color.WHITE);
FrameLayout frameLayout = new FrameLayout(context);
frameLayout.setPadding(itemPadding, itemPadding, itemPadding, itemPadding);
frameLayout.addView(view);
return frameLayout;
}
private class UnSpanText implements Serializable {
int start;
int end;
CharSequence showText;
String showId;
UnSpanText(int start, int end, CharSequence showText, String showId) {
this.start = start;
this.end = end;
this.showText = showText;
this.showId = showId;
}
}
public class MyImageSpan extends ImageSpan implements Serializable {
private String showText;
public String getShowId() {
return showId;
}
public void setShowId(String showId) {
this.showId = showId;
}
private String showId;
public MyImageSpan(Drawable d, String showText, String showId) {
super(d);
this.showText = showText;
this.showId = showId;
}
public String getShowText() {
return showText;
}
}
/**
* dip转换px
*/
public static int dip2px(Context context, int dip) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dip * scale + 0.5f);
}
public void resumeSpanText(String oldString, ArrayList str) {//恢复草稿标题数据
int contentStart = 0;
int contentEnd;
int tmpCutStart;
int tmpCutEnd;
if (str.size() == 0) {
insertText(oldString);
return;
}
for (int i = 0; i < str.size(); i++) {
Matcher matcher = matchStringByRegularExpression(oldString, str.get(i).getUserName());
if (matcher != null) {
int start = matcher.start();
int end = matcher.end();
contentEnd = start;//裁剪的结尾
content = oldString.substring(contentStart, contentEnd);
contentStart = end;
Log.d("数据", ">>>>" + start + ">>>" + end + ">>>" + content);
if (!TextUtils.isEmpty(content)) {
insertText(content);
}
addSpan(str.get(i));
}
}
if (getText().length() < oldString.length()) {
String substring = oldString.substring(getText().length(), oldString.length());
if (!TextUtils.isEmpty(substring)) {
insertText(substring);
}
}
}
public static Matcher matchStringByRegularExpression(String parent, String child) {
Pattern p = Pattern.compile(child);
Matcher m = p.matcher(parent);
while (m.find()) {
return m;
}
return null;
}
public ArrayList getFinalSpan() {//获取最终的@好友的用户Bean数据
ArrayList patRecordUserBeans = new ArrayList<>();
Editable editText = getText();//这里不能使用toString()。否则格式会被重置。
Spannable spannableString = new SpannableString(editText);
MyImageSpan[] spans = spannableString.getSpans(0, editText.length(), MyImageSpan.class);
if (spans == null || spans.length == 0) {
return patRecordUserBeans;
} else {
for (int i = 0; i < spans.length; i++) {
PatRecordUserBean bean = new PatRecordUserBean();
bean.setUserId(spans[i].getShowId());
bean.setUserName(spans[i].getShowText());
patRecordUserBeans.add(bean);
}
return patRecordUserBeans;
}
}
}
实体类
/**
* Desc:@好友功能实体类
*
* Author:
* Date: 2018-09-13
* Copyright: Copyright (c) 2010-2018
* Company:
* Updater:
* Update Time:
* Update Comments:
*/
public class PatRecordUserBean implements Serializable {
private String userId;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
private String userName;
}
知道你们不喜欢看源码,直接看用法吧
1.当前页面有保存草稿功能,如果需要恢复上一次的草稿数据,直接调用
ArrayList oldUserBean = draftPatRecordParamJson.getUserSpan();
if (oldUserBean != null) {
editTitle.resumeSpanText(videoTitle, oldUserBean);
}
2.设置监听、我这里是最大只能60个字符
editTitle.addTextChangedListener(new TextWatcher() {
private CharSequence temp;
private int starts, end;
private int deleteIndex;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int lengthBefore, int lengthAfter) {
temp = s;
if (lengthAfter == 1 && "@".equals(String.valueOf(s.charAt(start))) && s.length() <= 60) {
//这里可以直接跳转选择好友的页面
editTitle.getText().delete(s.length() - 1, s.length());
} else if (lengthBefore == 1 && lengthAfter == 0) { //向前删除一个字符,@后的内容必须大于一个字符,可以在后面加一个空格
}
}
@Override
public void afterTextChanged(Editable s) {//变化
if (temp.length() > 60) {
ToastUtils.showShort(R.string.patrecord_public_title_word_count);
s.delete(editTitle.getSelectionStart() - 1, editTitle.getSelectionStart());
}
}
});
3.选择好友后、onActivityForResult进行数据显示
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PatRecordConstant.PatRecordParamsType.PAT_COVER) {
if (resultCode == PatRecordConstant.PatRecordParamsType.PAT_FRIEND_CODE) {
friendName = "@" + data.getStringExtra(PatRecordConstant.PatRecordParamsType.Pat_PUBLIC_FRIEND_NAME) + "";
friendId = data.getStringExtra(PatRecordConstant.PatRecordParamsType.Pat_PUBLIC_FRIEND_NAME_ID) + "";
ArrayList finalSpan = editTitle.getFinalSpan();
for (int i = 0; i < finalSpan.size(); i++) {
PatRecordUserBean patRecordUserBean = finalSpan.get(i);
String userId = patRecordUserBean.getUserId();
if (!TextUtils.isEmpty(friendId) && userId.equals(friendId)) {
return;
}
}
if (editTitle.getText().length() + friendName.length() <= 60) {
PatRecordUserBean userBean = new PatRecordUserBean();
userBean.setUserName(friendName);
userBean.setUserId(friendId);
editTitle.insertSpan(userBean);//插入数据(@好友的数据)
} else {
ToastUtils.showShort(R.string.patrecord_public_title_word_count);
}
}
}
}
好了,我发现大家都一样,一般网上找解决方案。只要结果。不要过程的,其实我也一样。
但是总要学习,总要进步,毕竟家里没矿~~
有问题留言沟通,并且点个喜欢,点个收藏之类的,项目中有参考了其他同志的项目,因为写的有点久,这里我也找不出项目地址了。有介意的同志联系我