小編給大家分享一下RecyclerView中如何監(jiān)聽EditText變化的BUG,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
成都創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),調(diào)兵山企業(yè)網(wǎng)站建設(shè),調(diào)兵山品牌網(wǎng)站建設(shè),網(wǎng)站定制,調(diào)兵山網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,調(diào)兵山網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競爭力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。需求:有一個(gè)列表,列表中有一個(gè)edittext(只能輸整形),外部有一個(gè)整形變量Int,每次改變列表中其中一項(xiàng)的edittext的值時(shí),外部的Int都會改變。
既然這樣,我們就需要對edittext進(jìn)行addTextChangedListener監(jiān)聽,一般做法是在afterTextChanged中對外部進(jìn)行循環(huán)累加,但是想想,每一次你改變edittext都要進(jìn)行一次時(shí)間復(fù)雜度為n的循環(huán)的話,想想就覺得這個(gè)算法很那啥,所以我想了另一個(gè)算法,每次改變其中一個(gè)item的值時(shí),用總的值減去原item的edittext中的值加上item的edittext新輸入的值,這樣的復(fù)雜度為1,看著就很舒服。
但是這樣也引出了一個(gè)問題,就是今天要說的BUG
我要講的BUG是RecyclerView導(dǎo)致數(shù)據(jù)錯(cuò)亂的問題
我要講的BUG是RecyclerView導(dǎo)致數(shù)據(jù)錯(cuò)亂的問題
我要講的BUG是RecyclerView導(dǎo)致數(shù)據(jù)錯(cuò)亂的問題
重要事情說三遍
你想想,對于addTextChangedListener這個(gè)方法,你每次對edittext進(jìn)行setText操作后都會調(diào)用這個(gè)方法,不巧的是recyclerview是復(fù)用容器,數(shù)據(jù)超出可用的容器時(shí),會對edittext進(jìn)行復(fù)用,也就是說,我們本身只想在addTextChangedListener中去監(jiān)聽手動改變edittext的情況,而recyclerview重復(fù)調(diào)用setText也會導(dǎo)致默認(rèn)調(diào)用addTextChangedListener而會產(chǎn)生嚴(yán)重的數(shù)據(jù)錯(cuò)亂。
舉個(gè)栗子,對我的需求原本是做這樣的操作。
edtItem.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { // todo 獲取到edit改變前的數(shù)字 String befour = edtItem.getText().toString(); } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { // todo 獲取到edit改后的數(shù)字 String now = edtItem.getText().toString(); } });
這樣拿到當(dāng)前Item改變前的數(shù)字和改變后的數(shù)字,傳給外部(傳的做法我這沒寫,可以用觀察者),然后外部總int - befour + now 就能獲取到新的總數(shù)。
這邏輯看是完美,但是recyclerview幫你settext時(shí),你的befour就是復(fù)用前的item中的數(shù),而now就是新settext上去的數(shù)。
簡單來說,我們要的效果是手動修改editText時(shí)才進(jìn)行int - befour + now步驟,而現(xiàn)在你光滑動就莫名其妙進(jìn)行int - 復(fù)用前item的數(shù) + 復(fù)用后item的數(shù)。
那我們就需要解決一個(gè)問題,只有手動修改edittext時(shí),才進(jìn)行正確的操作,滑動時(shí),不進(jìn)行操作
其實(shí)我以前有說過reyclerview不能直接對它的容器進(jìn)行操作(也就是viewholder),而應(yīng)該對它的數(shù)據(jù)進(jìn)行操作。所以這里我們改成這樣的話,就不會受到滑動更新數(shù)據(jù)的影響。
edtItem.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { // todo 獲取到edit改變前的數(shù)字 String befour = data; } @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { } @Override public void afterTextChanged(Editable editable) { // todo 獲取到edit改后的數(shù)字 data = edtItem.getText().toString(); String now = data ; } });
data是adapter傳給viewholder的數(shù)據(jù)。這樣寫的話在beforeTextChanged方法中獲取的就不是復(fù)用前item的數(shù)據(jù),而是當(dāng)前的數(shù)據(jù)。所以你滑動時(shí)發(fā)現(xiàn)befour 和now 會是一樣,這時(shí)就不用進(jìn)行更改總數(shù)的操作,而手動改變editText時(shí)befour 和now 是不一樣的。
總結(jié)
可能你看不懂我的需求和例子,說明你沒碰到過這樣的情況(列表的edittext影響外部某個(gè)狀態(tài)),我也不太好解釋,但是你基本會碰到過數(shù)據(jù)錯(cuò)亂的情況,這就是我要說的。
在RecyclerView中,不管你要做什么操作,不要直接對容器(ViewHolder)操作,而是對數(shù)據(jù)進(jìn)行操作。
補(bǔ)充一點(diǎn)java的常識
如果你傳的是對象的話,這里對形參的改變,實(shí)參也會變,但是傳基本數(shù)據(jù)類型的話,你變形參是不會影響實(shí)參的,所以不管有多少個(gè)數(shù)據(jù),在viewholder中最后應(yīng)該傳入對象而不是基本數(shù)據(jù)類型.
以上是“RecyclerView中如何監(jiān)聽EditText變化的BUG”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!