您的位置:首页 > 移动开发 > Android开发

Android实际开发问题03------ListView中添加Edittext

2016-01-07 10:40 489 查看
有些时候事情往往不会像你想像的那么简单

开发过程中,我们会遇到ListViewItem里面含有Edittext的情况,希望将edittext对应的数据存到对应的条目中,比如每个商品都需要在评价的时候,留有评价信息,也就是在书写评价的时候,就将对应的评价信息放到对应商品信息中,这样避免因为Adapternotifydatachanged刷新,所以用到了addTextChangeListener这个监听事件,在其中的方法中用来记录.下面列举其中遇到的问题:

1.焦点问题

下面是item的代码

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:orientation="vertical">

    <TextView

        android:id="@+id/tv"

        android:layout_width="match_parent"

        android:layout_height="wrap_content" />

在这里写上一个edittext

    <EditText

        android:id="@+id/et"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:gravity="top"

        android:lines="1" />

</LinearLayout>

然后写一个普通的Adapter,运行程序会发现,点击edittext的时候
,会出现键盘界面切换了两下,然后又消失了的状况,,这个时候应该是焦点导致了问题,所以我的解决方式是在对应的activity中

android:windowSoftInputMode="adjustResize"

这个是调整键盘弹出时edittext相对的尺寸,不同的方式有不同的效果

然后就是设置listview在滚动的时候获取焦点在失去焦点

 lv_list.setOnScrollListener(new AbsListView.OnScrollListener() {

            @Override

            public void onScrollStateChanged(AbsListView absListView, int i) {

                lv_list.requestFocus();//这两句话很重要

                lv_list.clearFocus();

            }

            @Override

            public void onScroll(AbsListView absListView, int i, int i1, int i2) {

            }

        });

写完上述会发现不会在出现刚才那种情况了...

2.addTextChangeListener的问题

如果你用了ViewHolder的话,就会出现下面这种情况,打开程序,先

        1)上下拖动Listview,然后填写第一条数据的信息,然后向下拖动,你会发现正好被重用的那条数据也显示你第一条数据

        2)填写第一条数据,然后上下拖动,再回到第一条数据那里,你会发现第一条数据消失了,

,如果你觉得是复用控件导致的问题,就像是这桌吃完饭,没有刷完,等到下一波客人来的时候剩下的情景一样,那么下面这样写可能你会明白的比较透彻

//根据当前条目,获取对应数据,然后将对应的信息填写到Edittext上,

final ViewHolder viewHolder = (ViewHolder) view.getTag();

final TData tData = list.get(pos);

viewHolder.et.setText(tData.getValue() == null ? "" : tData.getValue());

这样问题就被解决了吧,可是你会发现问题仍然存在,然后添加监听事件,你会发现Edittext对应的监听事件执行了好多遍

如果这个Edittext同时被第一条数据和第十条数据复用的话,那么监听事件会执行对第一条和第十条的两个方法,所以也就是说,Edittext的addTextChangeListener的是add,而不是set的原因了,我的解决方式就是下面这样:

viewHolder.et.setOnFocusChangeListener(new View.OnFocusChangeListener() {

            @Override

            public void onFocusChange(final View view, boolean b) {

                //根据焦点决定当前到底是谁被选中,全局变量肯定只有一个值,不会有多个值

                if (b) {

                    view.setTag(1);

                    selection = pos;

                } else {//这种情况主要依赖于Listview的滚动事件,抢走了焦点,也就是上面所写的滚动事件

                    Log.e("cxd1", "移除");

                    view.setTag(0);

                }

            }

        });

viewHolder.et.addTextChangedListener(new TextWatcher() {

            @Override

            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

                Log.e("cxd", "beforeTextChanged");

            }

            //这里保存数据的时候就不会同时给多条数据赋值了

            @Override

            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

                Log.e("cxd", "onTextChanged");

                Object tag = viewHolder.et.getTag();

                if (tag == null) {

                    return;

                }

                  //两个条件缺一不可

                  if ("1".equals(tag.toString()) && pos == selection) {

                    Log.e("cxd", "pos=" + pos + "|||charSequence=" + charSequence.toString());

                    tData.setValue(charSequence.toString());

                }

            }

            @Override

            public void afterTextChanged(Editable editable) {

                Log.e("cxd", "afterTextChanged");

            }

        });

上面的情况也可以通过removeTextChange解决,在获取焦点时调用addTextChangeListener,失去焦点时调用removeTextChange,将自身事件移除,关键在于焦点的失去那里

viewHolder.et.setInputType(inputType);

final TextWatcher textWatcher= new TextWatcher() {

    @Override

        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override

    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

        tData.setValue(charSequence.toString());

    }

    @Override

    public void afterTextChanged(Editable editable) {

    }

};

viewHolder.et.setOnFocusChangeListener(new View.OnFocusChangeListener() {

    @Override

    public void onFocusChange(final View view, boolean b) {

        if (b) {

            viewHolder.et.addTextChangedListener(textWatcher);

        } else {

            viewHolder.et.removeTextChangedListener(textWatcher);

        }

    }

});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: