android listview edittext 事件,Android ListView item中含有Edittext 中一些坑
今天做一個界面. ?是?一個列表 .列表中有spinner,button,edittext等控件
首次打開需要展示,用戶可以修改,修改后數(shù)據(jù)保存.
??在保存Edittext控件上的值的時(shí)候,用的etRemark.addTextChangedListener(myTextWatcher)????????
注意?是addTextChangedListener
來監(jiān)聽Edittext的值,如果變化的話 就將變化的值直接存入數(shù)據(jù)集對象中.
這樣存在了幾個問題
1,我們改變了一個editext的值后通過logcat 發(fā)現(xiàn)?onTextChanged會被多次調(diào)用.
我們知道listview在第一次展示的時(shí)候會多次調(diào)用getView方法來確定itemView的高度.
多次調(diào)用就會給同一個editext控件 add多個TextChangedListener.
public?void?addTextChangedListener(TextWatcher?watcher)?{
if?(mListeners?==?null)?{
mListeners?=?new?ArrayList();
}
mListeners.add(watcher);
}
也就導(dǎo)致了為什么輸入一次 會多次調(diào)用TextChangedListener的方法.
2,listview滑動后發(fā)現(xiàn)editext的值會混亂.
如果一屏為3個item
具體混亂特征為首次加載完listview的時(shí)候.
第一次滑動,滑倒第二頁的時(shí)候第二屏的第一個(position=3)會把第一屏的第一個item(position=0)給覆蓋掉.如果position=3的這個item為空的話.再滑到頂部則發(fā)現(xiàn)position的item 也為空了.
這個時(shí)候在position=0的item中的editext的值改變的時(shí)候,往下滑發(fā)現(xiàn)position=3的也改變了.
我們都知道這是convertView復(fù)用的結(jié)果.
具體原因是,在加載第二屏第一個的item的時(shí)候調(diào)用的getView()方法,
EditText?et=?ViewHolder.get(convertView,?R.id.item_editText);
et.setText(datas.get(itemPosition).editTextValue);
et.addTextChangedListener(myTextWatcher);
我的代碼里有一個settext(value)方法,,因?yàn)楹偷谝黄恋膇tem用的是同一個editext對象
這個時(shí)候會觸發(fā)TextChanged事件,因?yàn)橛玫氖莂ddTextChangedListener方法.所以這個editext中有多個listener
插入Textwatcher代碼.
class?MyTextWatcher?implements?TextWatcher{
private?int?position;
public?MyTextWatcher(int?position)?{
super();
this.position?=?position;
}
@Override
public?void?beforeTextChanged(CharSequence?s,?int?start,?int?count,?int?after)?????????????????{
}
@Override
public?void?onTextChanged(CharSequence?s,?int?start,?int?before,?int?count)?{
}
@Override
public?void?afterTextChanged(Editable?s)?{
datas.get(position).editTextValue=?s.toString();
}
}
也會觸發(fā),所以這個時(shí)候,就會調(diào)用afterTextChanged()方法
因?yàn)槲业腡extWatcher對象中維護(hù)了一個position的全局變量,其實(shí)這個TextWatcher的position為0.則把position為3的edittext的值賦給了datas.get(0)editTextValue;所以存在了第一次滑動的時(shí)候會發(fā)現(xiàn)值會被覆蓋的問題.
等到多次滑動后一個editext控件就會add多個TextWatcher對象,這個時(shí)候一旦修改一個editext的值,就會調(diào)用多個TextWatcher的textChanged回調(diào),也就是為什么改一個position為0的editext.怎么也把position為3的editext也改了.
其實(shí)修改的是datas中的值.
怎么解決呢.看了半天廢話終于到點(diǎn)子上了.
1 不復(fù)用converView,并且為listview的item指定高度阻止首次加載多次調(diào)用getView()方法.
但是這樣每次都去inflate布局文件實(shí)在太坑了.
2 不用addTextChangedListener 改用?setOnFocusChangeListener() .靠失去焦點(diǎn)來觸發(fā)保存數(shù)據(jù)
個人嘗試過后沒問題.但是失去焦點(diǎn).總感覺有點(diǎn)不靠譜.不知道是不是web開發(fā)的后遺癥,怕如果用戶輸入完后直接點(diǎn)擊別的地方的按鈕,會不會不會觸發(fā),(經(jīng)過原生的android測試,發(fā)現(xiàn)無論是關(guān)閉輸入框,還是點(diǎn)擊別的地方的按鈕,都會觸發(fā)焦點(diǎn)丟失事件) ?應(yīng)該可以放心使用
3. 還用addTextChangedListener()來觸發(fā)保存,不過在editext賦值之前先remov掉之前的TextWatcher
查看源碼removeTextChangedListener()方法 用的是
public?void?removeTextChangedListener(TextWatcher?watcher)?{
if?(mListeners?!=?null)?{
int?i?=?mListeners.indexOf(watcher);
if?(i?>=?0)?{
mListeners.remove(i);
}
}
}
list的indexOf()方法.
則需要重寫TextWatcher的 equals()方法.
見代碼
MyTextWatcher?myTextWatcher?=?new?MyTextWatcher(itemPosition);
et.removeTextChangedListener(myTextWatcher);
et.setText(datas.get(itemPosition).editTextValue);
et.addTextChangedListener(myTextWatcher);
MyTextWatcher類中重寫
@Override
public?boolean?equals(Object?o)?{
return?true;
}
這樣就可以完美解決了;
總結(jié)
以上是生活随笔為你收集整理的android listview edittext 事件,Android ListView item中含有Edittext 中一些坑的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Web渗透基础小总结
- 下一篇: Android服务器django,And