在开发中遇到的问题是需要在edittext中输入@符号后自动在输入框的下面出现选择窗口,之后待选项是根据@符号之后的内容来动态变化的。
刚开始的想法是使用一个开源的东西:https://github.com/kpbird/chips-edittext-library
但是出现的问题太多,没解决,之后的想法是在输入@字符之后打开一个popwindow,然后在popwindow中的editText中输入keyword来与服务器端动态交互list显示数据,但是感觉体验不好,虽然有功能但不好,然后就继续使用popwindow,动态的去获取@之后的word,去匹配之后修改适配器来达到动态。
比较关键的地方
1、editText监听:
editText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
if (b) {
String s_temp = s.toString();
int indexOf = s_temp.toString().lastIndexOf("@");
if (indexOf != -1) {
String substring = s_temp.substring(indexOf + 1,
s_temp.length());
keyWord = substring;
if (!keyWord.equals("")) {
new ShowPopWindow().execute(keyWord);
initPopWindow();
mPop.showAsDropDown(editText);
}
}
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
if (s.length() > 0) {
int pos = s.length() - 1;
char c = s.charAt(pos);
if (c == '@') {
b = true;
curr = pos;
}
}
}
});
2、popwindow初始化:
private void initPopWindow() {
if (mPop == null) {
mPop = new PopupWindow(layout, LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
}
if (mPop.isShowing()) {
mPop.dismiss();
}
}
3、异步的数据刷新:
private class ShowPopWindow extends
AsyncTask<String, Void, ArrayList<UserSuggest>> {
@Override
protected ArrayList<UserSuggest> doInBackground(String... params) {
ArrayList<UserSuggest> atUserSync;
if (BaseApplication.mNetWorkState) {
SearchSuggestAction action = new SearchSuggestAction(
CreateNewWeibo.this);
atUserSync = action.atUserSync(params[0]);
} else {
atUserSync = null;
}
return atUserSync;
}
@Override
protected void onPostExecute(ArrayList<UserSuggest> result) {
// TODO Auto-generated method stub
if (result != null) {
mListItems.clear();
mListItems.addAll(result);
adapter.notifyDataSetChanged();
}
}
}
4、adapter的动作处理:
@Override
public View getView(final int position, View convertView,
ViewGroup parent) {
PopHolder holder;
if (convertView == null) {
holder = new PopHolder();
convertView = LayoutInflater.from(CreateNewWeibo.this).inflate(
R.layout.pop_for_at_item, null);
holder.nick_name = (TextView) convertView
.findViewById(R.id.pop_for_at_tv);
convertView.setTag(holder);
} else {
holder = (PopHolder) convertView.getTag();
}
holder.nick_name.setText(mListItems.get(position).nickname);
convertView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
String temp = editText.getText().toString();
String body = "@" + mListItems.get(position).nickname+" ";
// SpannableStringBuilder style = new SpannableStringBuilder(
// body); // 将str字符串载入SpannableStringBuilder对象中
// style.setSpan(new ForegroundColorSpan(Color.BLUE), 0,
// body.length() ,
// Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
editText.setText(temp.substring(0, curr) + body);
Linkify.addLinks(editText, USER_PATTERN, String.format(
"%s/?%s=", Defs.USER_SCHEME, Defs.USER_NAME), null,
USER_FILTER);
b = false;
mPop.dismiss();
curr = 0;
editText.setSelection(editText.getText().length());
}
});
return convertView;
}
在最后选中之后的处理中还是有问题,我的比较不好的解决办法是在body后面加了一个空格,但是这个办法不好,目前能想到的好点的办法是将每次选中的人保存到一个list或者map中,在最后处理时,SpannableStringBuilder中可以指定每一个选中对象的位子,更好的添加样式:
这个是测试Demo:
import java.util.ArrayList;
public class StringDemo {
public static void main(String[] args) {
String s = "dfdfdff@yangbo@637829yfdss@杨博kfdfkgfd看看";
ArrayList<String> at_users = new ArrayList<String>();
at_users.add("@yangbo");
at_users.add("@637829y");
at_users.add("@杨博");
for (int i = 0; i < at_users.size(); i++) {
int st = s.indexOf(at_users.get(i));
int en = at_users.get(i).length() + st;
System.out.println(at_users.get(i)+" start="+st+" end="+en);
}
String substring = s.substring(7, 14);
System.out.println(substring);
// int indexOf = s.toString().lastIndexOf("@");
// String substring = s.substring(indexOf + 1, s.length());
// System.out.println("s=" + s);
// System.out.println(substring.equals(""));
// System.out.println("substring=" + substring);
}
}
打印结果:
@yangbo start=7 end=14
@637829y start=14 end=22
@杨博 start=26 end=29
@yangbo
但是问题来了,当string中有多个同样的人出现时在循环中只能处理第一次出现的位置,所以就可能需要去进行字符串不断的截取比对处理。
希望大家能给出更好的解决方式。