概述

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

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

  1. (转载)解决ListView中使用EditText所遇到的一些冲突

    大家都知道在listView中使用editText,在输入过程中是有冲突的.今天稍微研究了一下这个问题,有一点点小小的心得和大家一起分享下. 首先建立一个最简单的demo,主界面就是一个ListVie ...

  2. 判断DataTale中判断某个字段中包含某个数据

    // <summary> /// 判断DataTale中判断某个字段中包含某个数据 /// </summary> /// <param name="dt&quo ...

  3. Fusion Tables 图层用于呈现 Google Fusion Tables 中包含的数据

    Google Maps API 允许您使用 FusionTablesLayer 对象将 Google Fusion Tables 中包含的数据呈现为地图上的图层.Google Fusion Table ...

  4. ListView 中含有 EditText 导致焦点丢失的问题

    ListView 中的 item 中有 EditText 时. 如果activity的输入法选项设置为 android:windowSoftInputMode="adjustResize&q ...

  5. 传输json数据到前台的时候,数据中包含日期数据

    问题描述 当从数据库中查询的数据中包含有日期格式的数据的时候,数据传输到前台会报错. 解决方式 // 逐条将日期进行格式化后再传输 Date date = new SimpleDateFormat(& ...

  6. 关于ListView中notifyDataSetChanged()刷新数据不更新原因

    使用Listview的时候: 当要动态显示更改后的数据(例如数据库改动), 很多人应该都用过notifyDataSetChanged();这个方法来刷新Listview,显示改后的数据. 这时候就要注 ...

  7. PHP中$_REQUEST中包含的数据,数据被覆盖问题

    这个问题涉及到php.ini中的两个变量. variables_order = "EGPCS" variables_order 系统在定义PHP预定义变量,EGPCS 是 Envi ...

  8. Kafka:ZK+Kafka+Spark Streaming集群环境搭建(二十五)Structured Streaming:同一个topic中包含一组数据的多个部分,按照key它们拼接为一条记录(以及遇到的问题)。

    需求: 目前kafka的topic上有一批数据,这些数据被分配到9个不同的partition中(就是发布时key:{m1,m2,m3,m4...m9},value:{records items}),m ...

  9. ListView中含有EditText时候--要命的焦点问题迎刃而解

    最近做项目的时候遇到了一个问题,就是在ListView的item上面含有一个EditText,要求是这样: 1当点击item的时候,item可以点击; 2当点击EditText的时候EditText也 ...

随机推荐

  1. Apache 安装与配置(WIN10)

    本地坏境:windows 10 Pro 1709 Apache版本:httpd-2.4.32-Win64-VC15 Apache下载地址:https://www.apachelounge.com/do ...

  2. leetcode 717. 1-bit and 2-bit Characters -easy

    https://leetcode.com/problems/1-bit-and-2-bit-characters/description/ We have two special characters ...

  3. [LeetCode] Number of Longest Increasing Subsequence 最长递增序列的个数

    Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: I ...

  4. js if for 详解 获取元素方式 及一些js 基础知识

    ##获取元素的新方法## --document.querySelector('Css Selector{css选择器}') 接收一个css选择器(通配,群组,类,包含,id....等) 若这个选择器对 ...

  5. vim 批量注释和批量取消注释

    批量注释 按ctrl+v进入可视块模式, 上下移动选中需要注释的行, 按I, 输入注释符号#, 按两下Esc, 保存   批量取消注释 按ctrl+v进入可视块模式, 上下移动选中需要取消注释的行, ...

  6. [HNOI 2008]越狱

    Description 监狱有连续编号为1...N的N个房间,每个房间关押一个犯人,有M种宗教,每个犯人可能信仰其中一种.如果 相邻房间的犯人的宗教相同,就可能发生越狱,求有多少种状态可能发生越狱 I ...

  7. hdu 5266 pog loves szh III(lca + 线段树)

    I - pog loves szh III Time Limit:6000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I ...

  8. PTA 银行排队问题之单队列多窗口服务

    假设银行有K个窗口提供服务,窗口前设一条黄线,所有顾客按到达时间在黄线后排成一条长龙.当有窗口空闲时,下一位顾客即去该窗口处理事务.当有多个窗口可选择时,假设顾客总是选择编号最小的窗口. 本题要求输出 ...

  9. 怎样使用Secure CRT查看vcenter和esxi主机的日志文件(转)

    对ESXI主机的日志管理对于故障诊断和合规性至关重要.Esxi主机的日志通过syslog工具进行管理的,在默认的情况下,日志文件存储在主机的scratch分区中(/scratch/log/).scra ...

  10. java中什么是序列化和反序列化

    序列化:能够把一个对象用二进制的表示出来. 类似我第一个字节表示什么属性名词,第二个字节表示什么属性值,第几个字段表示有几个属性等. 而且这个二进制可以写到硬盘或者在网络上传输但不会破坏他的结构.一般 ...