概述
前几天测试提了一个bug,在ListView中添加留言信息,导致错乱的问题。实际上就是ListView需要添加一个EditText,复用导致错乱的问题,这个问题以前也遇到过。诸如,ListView嵌套EditText、CheckBox等焦点问题都会出现复用的错乱,其根源就是ViewHolder的复用问题。
说说上面的问题吧,保存item中EditText中的数据,导致数据复用的时候都给设置了值。我们在最外层存了一个Map
Map<Integer, String> edItem;
监听每个Item的输入(OnTextChangedListener),并在afterTextChanged()将值保存到Map中去。
holder.editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if ((edItem.size() == inputContainer.size())) {
// 添加一项控件
edItem.put(edindex, "edindex");
}
return false;
}
});
但是这里出现了一个问题,由于复用,导致,每一个Item都被赋值了,所以我们要解决这个问题得从源头阻断给EditText赋值,也就是在OnTextChange方法里面,我们判断一下,如果用户操作的是当前的Item,我们就给Map赋值,否则不赋值,或者赋值为空值。
所以这个时候我们要对EditText的触摸事件做监听:
editText.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
index = position;
}
return false;
}
});
然后我们在TextWatcher的onTextChanged判断一下:
public void onTextChanged(CharSequence text, int start, int before, int count) {
//如果该edittext有默认内容,还要在if那里进行过滤
if (index>=0 && text.length() > 0 &&index== position) {
mData.get(index).put("input", text.toString());
}
}
这样就解决了复用的问题,完整代码:
public class ListViewTestAdapter extends BaseAdapter {
private List<Map<String, String>> mData;
private LayoutInflater mInflater;
private Context mContext;
private int index = -1;
public ListViewTestAdapter(Context context, List<Map<String, String>> data) {
this.mContext = context;
this.mData = data;
this.mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
if (convertView == null) {
convertView = mInflater.inflate(R.layout.main_function_listitem3, null);
holder.title = (TextView) convertView.findViewById(R.id.txtTitle);
holder.editText = (EditText) convertView.findViewById(R.id.input);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
EditText editText = holder.editText;
editText.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
index = position;
}
return false;
}
});
editText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable editable) {
}
public void beforeTextChanged(CharSequence text, int start, int count, int after) {
}
public void onTextChanged(CharSequence text, int start, int before, int count) {
//如果该edittext有默认内容,还要在if那里进行过滤
if (index>=0 && text.length() > 0 && index == position ) {
mData.get(index).put("input", text.toString());
}
}
});
holder.title.setText(mData.get(position).get("title"));
holder.editText.setText(mData.get(position).get("input"));
editText.clearFocus();
if (index != -1 && index == position) {
editText.requestFocus();
}
final ViewHolder finalHolder = holder;
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext, finalHolder.title.getText(), Toast.LENGTH_SHORT).show();
}
});
return convertView;
}
public final class ViewHolder {
public TextView title;
public EditText editText;
}
}
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/app/5663.html