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

有些时候事情往往不会像你想像的那么简单

开发过程中,我们会遇到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);
        }
    }
});


你可能感兴趣的:(Android实际开发问题03------ListView中添加Edittext)