国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

RecyclerView中監聽EditText變化的BUG的解決方法

2019-10-22 18:21:58
字體:
來源:轉載
供稿:網友

需求:有一個列表,列表中有一個edittext(只能輸整形),外部有一個整形變量Int,每次改變列表中其中一項的edittext的值時,外部的Int都會改變。

既然這樣,我們就需要對edittext進行addTextChangedListener監聽,一般做法是在afterTextChanged中對外部進行循環累加,但是想想,每一次你改變edittext都要進行一次時間復雜度為n的循環的話,想想就覺得這個算法很那啥,所以我想了另一個算法,每次改變其中一個item的值時,用總的值減去原item的edittext中的值加上item的edittext新輸入的值,這樣的復雜度為1,看著就很舒服。

但是這樣也引出了一個問題,就是今天要說的BUG

我要講的BUG是RecyclerView導致數據錯亂的問題

我要講的BUG是RecyclerView導致數據錯亂的問題

我要講的BUG是RecyclerView導致數據錯亂的問題

重要事情說三遍

你想想,對于addTextChangedListener這個方法,你每次對edittext進行setText操作后都會調用這個方法,不巧的是recyclerview是復用容器,數據超出可用的容器時,會對edittext進行復用,也就是說,我們本身只想在addTextChangedListener中去監聽手動改變edittext的情況,而recyclerview重復調用setText也會導致默認調用addTextChangedListener而會產生嚴重的數據錯亂。

舉個栗子,對我的需求原本是做這樣的操作。

edtItem.addTextChangedListener(new TextWatcher() {        @Override        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {             // todo 獲取到edit改變前的數字             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改后的數字             String now = edtItem.getText().toString();        }      });

這樣拿到當前Item改變前的數字和改變后的數字,傳給外部(傳的做法我這沒寫,可以用觀察者),然后外部總int - befour + now 就能獲取到新的總數。

這邏輯看是完美,但是recyclerview幫你settext時,你的befour就是復用前的item中的數,而now就是新settext上去的數。
簡單來說,我們要的效果是手動修改editText時才進行int - befour + now步驟,而現在你光滑動就莫名其妙進行int - 復用前item的數 + 復用后item的數。

那我們就需要解決一個問題,只有手動修改edittext時,才進行正確的操作,滑動時,不進行操作
其實我以前有說過reyclerview不能直接對它的容器進行操作(也就是viewholder),而應該對它的數據進行操作。所以這里我們改成這樣的話,就不會受到滑動更新數據的影響。

edtItem.addTextChangedListener(new TextWatcher() {        @Override        public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {             // todo 獲取到edit改變前的數字             String befour = data;        }        @Override        public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {        }        @Override        public void afterTextChanged(Editable editable) {             // todo 獲取到edit改后的數字             data = edtItem.getText().toString();             String now = data ;        }      });

data是adapter傳給viewholder的數據。這樣寫的話在beforeTextChanged方法中獲取的就不是復用前item的數據,而是當前的數據。所以你滑動時發現befour 和now 會是一樣,這時就不用進行更改總數的操作,而手動改變editText時befour 和now 是不一樣的。

總結

可能你看不懂我的需求和例子,說明你沒碰到過這樣的情況(列表的edittext影響外部某個狀態),我也不太好解釋,但是你基本會碰到過數據錯亂的情況,這就是我要說的。

在RecyclerView中,不管你要做什么操作,不要直接對容器(ViewHolder)操作,而是對數據進行操作。

補充一點java的常識

如果你傳的是對象的話,這里對形參的改變,實參也會變,但是傳基本數據類型的話,你變形參是不會影響實參的,所以不管有多少個數據,在viewholder中最后應該傳入對象而不是基本數據類型.

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 丹棱县| 南涧| 浮山县| 余干县| 凤凰县| 鹤山市| 农安县| 漠河县| 丹凤县| 梅州市| 石狮市| 晋宁县| 古田县| 鹤庆县| 府谷县| 沧州市| 贡嘎县| 齐河县| 龙里县| 新密市| 尤溪县| 凤阳县| 青浦区| 富源县| 福泉市| 亚东县| 丁青县| 哈密市| 漯河市| 克什克腾旗| 丽江市| 卫辉市| 嘉义县| 淮滨县| 榆社县| 那坡县| 青川县| 焦作市| 嘉定区| 临西县| 壤塘县|