前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于ListView中包含EditText数据复用引起异常的解决方案

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

作者头像
xiangzhihong
发布2018-02-05 16:36:07
1.5K0
发布2018-02-05 16:36:07
举报
文章被收录于专栏:向治洪向治洪

概述

前几天测试提了一个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;
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-12-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档