前言
日常開發(fā)中丙猬,經(jīng)常需要監(jiān)聽(tīng)EditText的變化改變TextView涨颜。有的時(shí)候還有EditText和EditText聯(lián)動(dòng),EditText和SeekBar聯(lián)動(dòng)茧球,這種情況要注意避免死循環(huán)庭瑰,關(guān)鍵點(diǎn)是找到一個(gè)標(biāo)識(shí)來(lái)識(shí)別誰(shuí)影響誰(shuí),例如可以獲取焦點(diǎn)判斷抢埋,涉及到的知識(shí)點(diǎn)如下:
EditText.addTextChangeListener(...)
EditText.setOnFocusChangeListener(...)
SeekBar.setOnSeekBarChangeListener(...)
相關(guān)知識(shí)
1.EditText.addTextChangeListener(...)
這個(gè)監(jiān)聽(tīng)有三個(gè)方法弹灭,大多是在onTextChanged()和afterTextChanged()處理督暂。經(jīng)過(guò)測(cè)試單字符輸入刪除、中間輸入刪除穷吮、多字符輸入刪除等逻翁,發(fā)現(xiàn)beforeTextChanged()和onTextChanged()的后面三個(gè)參數(shù)打印的數(shù)據(jù)是一一對(duì)應(yīng)的,即start - start捡鱼,count - before 八回,after - count。具體參數(shù)意思可看注釋驾诈,此處不舉例數(shù)據(jù)講解了缠诅。輸入emoji表情為啥count是2,可以看另一篇文章http://www.reibang.com/p/9434db689602
mEtPrice.addTextChangedListener(new TextWatcher() {
/**
* 輸入框改變前的內(nèi)容
* @param charSequence 輸入前字符串
* @param start 起始光標(biāo)
* @param count 刪除字符串的數(shù)量(這里的count是用str.length()計(jì)算的乍迄,因?yàn)閯h除一個(gè)emoji表情管引,count打印結(jié)果是 2)
* @param after 輸入框中改變后的字符串與起始位置的偏移量(也就是輸入字符串的length)
*/
@Override
public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) {
}
/**
* 輸入框改變后的內(nèi)容
* @param charSequence 字符串信息
* @param start 起始光標(biāo)
* @param before 輸入框中改變前的字符串與起始位置的偏移量(也就是刪除字符串的length)
* @param count 輸入字符串的數(shù)量(輸入一個(gè)emoji表情,count打印結(jié)果是2)
*/
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
}
/**
* @param editable 輸入結(jié)束呈現(xiàn)在輸入框中的信息
*/
@Override
public void afterTextChanged(Editable editable) {
}
});
2.EditText.setOnFocusChangeListener(...)
判斷EditText是否獲取了焦點(diǎn)
mEtValueA.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
focusChangeFlag = b;
}
});
3.SeekBar.setOnSeekBarChangeListener(...)
SeekBar滑動(dòng)監(jiān)聽(tīng)就乓,代碼調(diào)用的setProgress(...)只會(huì)執(zhí)行onProgressChanged(...)這個(gè)方法汉匙,另外兩個(gè)方法不執(zhí)行,且參數(shù)fromUser為false生蚁。如果是用戶手動(dòng)拖動(dòng)噩翠,三個(gè)方法都會(huì)執(zhí)行,且fromUser返回true邦投。
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
/**
* 進(jìn)度條改變事件
* @param seekBar
* @param progress 進(jìn)度條
* @param fromUser 是否是用戶操作伤锚,用戶手動(dòng)滑動(dòng)時(shí)-true,調(diào)用setProgress()-false
*/
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser){ //是用戶操作,去影響EditText
mEtFloatRatio.setText(progress+"");
}
}
/**
* 進(jìn)度條開始拖動(dòng)事件
* @param seekBar
*/
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
/**
* 進(jìn)度條停止拖動(dòng)事件(手指離開屏幕后)
* @param seekBar
*/
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
實(shí)例
EditText和EditText聯(lián)動(dòng)
獲取EditTexti焦點(diǎn)判斷志衣,當(dāng)自身獲取到焦點(diǎn)時(shí)屯援,才去影響其他EditText,避免死循環(huán)念脯。
private boolean AFocusChangeFlag; //valueA焦點(diǎn)狀態(tài)
private boolean BFocusChangeFlag; //valueB焦點(diǎn)狀態(tài)
//1.焦點(diǎn)監(jiān)聽(tīng)事件
mEtValueA.setOnFocusChangeListener((view, b) -> AFocusChangeFlag = b);
mEtValueB.setOnFocusChangeListener((view, b) -> BFocusChangeFlag = b);
//2.mEtValueA.addTextChangedListener(...)的監(jiān)聽(tīng)
public void afterTextChanged(Editable editable) {
//首位為"" or 0狞洋,置1,輸入的數(shù)字從1開始
if (editable.toString().startsWith("0") || editable.toString().equals("") || editable.toString().startsWith(".")) {
mEtValueA.setText("1");
mEtValueA.setSelection(1);
return;
}
if(AFocusChangeFlag){ //編輯A的情況下绿店,去改變B
mEtValueB.setText(10000 - Integer.valueOf(editable.toString()) +"");
}
}
//3.mEtValueB.addTextChangedListener(...)的監(jiān)聽(tīng)
@Override
public void afterTextChanged(Editable editable) {
if (editable.toString().startsWith("0") || editable.toString().equals("") || editable.toString().startsWith(".")) {
mEtValueB.setText("1");
mEtValueB.setSelection(1);
return;
}
if(BFocusChangeFlag){ //編輯A的情況下吉懊,去改變B
mEtValueA.setText(10000 - Integer.valueOf(editable.toString()) +"");
}
}
EditText和SeekBar聯(lián)動(dòng)
兩種方式處理:
1.還是獲取EditText焦點(diǎn),但因?yàn)橥蟿?dòng)SeekBar的時(shí)候假勿,EditText沒(méi)有失去焦點(diǎn)借嗽,所以要自己去取消EditText的焦點(diǎn)。
2.判斷SeekBar是否是用戶手動(dòng)滑動(dòng)的转培,如果是才去影響EditText恶导。(推薦這種)
private int floatRatio; //浮動(dòng)比例,范圍 [0,100]
//1.mEt.addTextChangedListener(...)的方法
@Override
public void afterTextChanged(Editable editable) {
//允許輸入的范圍是[0,100]
String str = editable.toString();
if (str.startsWith("00") || str.equals("")) {
mEtFloatRatio.setText("0");
mEtFloatRatio.setSelection(1);
return;
}
floatRatio = Integer.valueOf(str);
if (floatRatio>100){
mEtFloatRatio.setText("100");
mEtFloatRatio.setSelection(3);
return;
}
//改變進(jìn)度條
mSeekBar.setProgress(floatRatio);
}
//2.mSeekBar.setOnSeekBarChangeListener(...)的方法
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(fromUser){ //是用戶操作,去影響EditText
mEtFloatRatio.setText(progress+"");
}
}
EditText和SeekBar聯(lián)動(dòng)浸须,且有+惨寿,-按鈕
這種情況邦泄,不能只用fromUser來(lái)判斷了,因?yàn)辄c(diǎn)擊“+”“-”按鈕時(shí)裂垦,是要SeekBar去影響EditText虎韵,而此時(shí)是調(diào)用的setProgress(),fromUser返回的是false缸废。所以還是用EditText焦點(diǎn)去判斷包蓝,在用戶滑動(dòng)SeekBar、點(diǎn)擊"+","-"時(shí)失去焦點(diǎn)企量。這種處理方式其實(shí)用戶體驗(yàn)不好测萎,焦點(diǎn)跑別的輸入框去了。届巩。硅瞧。