zl程序教程

您现在的位置是:首页 >  后端

当前栏目

关于ListView中包含EditText数据复用引起异常的解决方案详解手机开发

2023-06-13 09:20:13 时间

前几天测试提了一个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(); 


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; }

5663.html

app程序应用开发手机开发无线开发移动端开发