使用 EditText 连续输入 OTP
Continuous OTP input with EditText
这里是4EditText
输入数字密码。我希望它是这样的,如果第一个 EditText
被 1 个数字填充,那么焦点应该转到下一个 EditText
并且也应该以相反的方式工作。这样用户可以一直从最左边输入密码,也可以从最右边用同样的方式擦除。
有人可以建议最好的方法是什么吗?
如果您熟悉 RxJava
,那么这可能是满足您需求的最简单方法。
这是 Kotlin
代码示例
RxTextView.textChanges(edtOtp1).filter { it.length == 1 }.subscribe { edtOtp2.requestFocus() }
RxTextView.textChanges(edtOtp2).filter { it.length == 1 }.subscribe { edtOtp3.requestFocus() }
RxTextView.textChanges(edtOtp3).filter { it.length == 1 }.subscribe { edtOtp4.requestFocus() }
RxTextView.textChanges(edtOtp4).filter { it.length == 1 }.subscribe { context.hideKeyboard(view) }
你也可以用同样的方式写反向。当长度为零时,焦点指向前一个 Edittext。
您可以使用图书馆 Android PinView / OtpView
或者您可以使用 addTextChangedListener
添加一个 TextWatcher
,每当此 EditTextView 的文本更改时调用它,然后您可以在下一个 EditText 上调用 View.requestFocus()
来聚焦它
你可以做到
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<EditText
android:id="@+id/otpET1"
android:layout_width="30dp"
android:layout_height="30dp"
android:inputType="number"
android:maxLength="1"
android:gravity="center"
android:textSize="20sp"/>
<EditText
android:id="@+id/otpET2"
android:layout_width="30dp"
android:layout_height="30dp"
android:inputType="number"
android:maxLength="1"
android:gravity="center"
android:textSize="20sp"/>
<EditText
android:id="@+id/otpET3"
android:layout_width="30dp"
android:layout_height="30dp"
android:inputType="number"
android:maxLength="1"
android:gravity="center"
android:textSize="20sp"/>
<EditText
android:id="@+id/otpET4"
android:layout_width="30dp"
android:layout_height="30dp"
android:inputType="number"
android:maxLength="1"
android:gravity="center"
android:textSize="20sp"/>
<EditText
android:id="@+id/otpET5"
android:layout_width="30dp"
android:layout_height="30dp"
android:inputType="number"
android:maxLength="1"
android:gravity="center"
android:textSize="20sp"/>
<EditText
android:id="@+id/otpET6"
android:layout_width="30dp"
android:layout_height="30dp"
android:inputType="number"
android:gravity="center"
android:maxLength="1"
android:textSize="20sp"/>
</LinearLayout>
在activity
EditText[] otpETs = new EditText[6];
otpETs[0] = findViewById(R.id.otpET1);
otpETs[1] = findViewById(R.id.otpET2);
otpETs[2] = findViewById(R.id.otpET3);
otpETs[3] = findViewById(R.id.otpET4);
otpETs[4] = findViewById(R.id.otpET5);
otpETs[5] = findViewById(R.id.otpET6);
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
int keyCode = event.getKeyCode();
if (keyCode == 7 || keyCode == 8 ||
keyCode == 9 || keyCode == 10 ||
keyCode == 11 || keyCode == 12 ||
keyCode == 13 || keyCode == 14 ||
keyCode == 15 || keyCode == 16 ||
keyCode == 67) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KEYCODE_DEL) {
int index = checkWhoHasFocus();
if (index != 123) {
if (Helpers.rS(otpETs[index]).equals("")) {
if (index != 0) {
otpETs[index - 1].requestFocus();
}
} else {
return super.dispatchKeyEvent(event);
}
}
} else {
int index = checkWhoHasFocus();
if (index != 123) {
if (Helpers.rS(otpETs[index]).equals("")) {
return super.dispatchKeyEvent(event);
} else {
if (index != 5) {
otpETs[index + 1].requestFocus();
}
}
}
return super.dispatchKeyEvent(event);
}
}
} else {
return super.dispatchKeyEvent(event);
}
return true;
}
private int checkWhoHasFocus() {
for (int i = 0; i < otpETs.length; i++) {
EditText tempET = otpETs[i];
if (tempET.hasFocus()) {
return i;
}
}
return 123;
}
这只是为了从 editTexts 中获取字符串
public class Helpers {
public static String rS(EditText editText) {
return editText.getText().toString().trim();
}
}
最后,
String code = Helpers.rS(otpETs[0]) + Helpers.rS(otpETs[1]) +
Helpers.rS(otpETs[2]) + Helpers.rS(otpETs[3]) + Helpers.rS(otpETs[4])
+ Helpers.rS(otpETs[5]);
或者只使用一个简单的 for/while
循环。
在 Kotlin 中你可以像 ..
txtOTP_1.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (txtOTP_1.text.toString().length == 1) {
txtOTP_1.clearFocus()
txtOTP_2.requestFocus()
txtOTP_2.setCursorVisible(true)
}
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun afterTextChanged(s: Editable) {
if (txtOTP_1.text.toString().length == 0) {
txtOTP_1.requestFocus()
}
}
})
txtOTP_2.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (txtOTP_2.text.toString().length == 1) {
txtOTP_2.clearFocus()
txtOTP_3.requestFocus()
txtOTP_3.setCursorVisible(true)
}
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun afterTextChanged(s: Editable) {
if (txtOTP_2.text.toString().length == 0) {
txtOTP_2.requestFocus()
}
}
})
txtOTP_3.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (txtOTP_3.text.toString().length == 1) {
txtOTP_3.clearFocus()
txtOTP_4.requestFocus()
txtOTP_4.setCursorVisible(true)
}
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun afterTextChanged(s: Editable) {
if (txtOTP_3.text.toString().length == 0) {
txtOTP_3.requestFocus()
}
}
})
txtOTP_4.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (txtOTP_4.text.toString().length == 1) {
txtOTP_4.clearFocus()
txtOTP_5.requestFocus()
txtOTP_5.setCursorVisible(true)
}
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun afterTextChanged(s: Editable) {
if (txtOTP_4.text.toString().length == 0) {
txtOTP_4.requestFocus()
}
}
})
txtOTP_5.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (txtOTP_5.text.toString().length == 1) {
txtOTP_5.requestFocus()
txtOTP_5.setCursorVisible(true)
}
}
})
您无法单独使用 addTextChangedListener 完成它。您可能必须同时设置 onKeyListener。这是给你的代码:
//6 EditTexts are otpEt[0], otpEt[1],...otpEt[5]
private EditText[] otpEt = new EditText[6];
otpEt[0] = (EditText) findViewById(R.id.otpEt1);
otpEt[1] = (EditText) findViewById(R.id.otpEt2);
otpEt[2] = (EditText) findViewById(R.id.otpEt3);
otpEt[3] = (EditText) findViewById(R.id.otpEt4);
otpEt[4] = (EditText) findViewById(R.id.otpEt5);
otpEt[5] = (EditText) findViewById(R.id.otpEt6);
setOtpEditTextHandler();
private void setOtpEditTextHandler () { //This is the function to be called
for (int i = 0;i < 6;i++) { //Its designed for 6 digit OTP
final int iVal = i;
otpEt[iVal].addTextChangedListener(new TextWatcher() {
@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) {
if(iVal == 5 && !otpEt[iVal].getText().toString().isEmpty()) {
otpEt[iVal].clearFocus(); //Clears focus when you have entered the last digit of the OTP.
} else if (!otpEt[iVal].getText().toString().isEmpty()) {
otpEt[iVal+1].requestFocus(); //focuses on the next edittext after a digit is entered.
}
}
});
otpEt[iVal].setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() != KeyEvent.ACTION_DOWN) {
return false; //Dont get confused by this, it is because onKeyListener is called twice and this condition is to avoid it.
}
if(keyCode == KeyEvent.KEYCODE_DEL &&
otpEt[iVal].getText().toString().isEmpty() && iVal != 0) {
//this condition is to handel the delete input by users.
otpEt[iVal-1].setText("");//Deletes the digit of OTP
otpEt[iVal-1].requestFocus();//and sets the focus on previous digit
}
return false;
}
});
}
}
如果您觉得这段代码很难,只需将其粘贴到您的项目中并尝试重新排列。您将能够轻松获得它
你做的第一件事
class GenericTextWatcher(private val currentView: EditText,nextView: EditText?) :
TextWatcher {
private val nextView: EditText?
override fun afterTextChanged(editable: Editable) {
// TODO Auto-generated method stub
val text = editable.toString()
if (nextView != null && text.length == 1) {
nextView.requestFocus()
}
if (text.length > 1) {
currentView.setText(text[text.length - 1].toString())
currentView.setSelection(1)
}
}
override fun beforeTextChanged(arg0: CharSequence, arg1: Int, arg2: Int, arg3: Int) {
// TODO Auto-generated method stub
}
override fun onTextChanged(arg0: CharSequence, arg1: Int, arg2: Int, arg3: Int) {
// TODO Auto-generated method stub
}
init {
this.nextView = nextView
}
class GenericKeyEvent(
private val currentView: EditText,
private val previousView: EditText?
) :
View.OnKeyListener {
override fun onKey(v: View, keyCode: Int, event: KeyEvent): Boolean {
if (event.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_DEL && currentView.text.toString()
.isEmpty()
) {
previousView?.requestFocus()
return true
}
return false
}
你可以使用这个功能
private fun attachTextWatchersSMS(){
otpactivityBinding.etKode1.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode1, otpactivityBinding.etKode2))
otpactivityBinding.etKode2.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode2, otpactivityBinding.etKode3))
otpactivityBinding.etKode3.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode3, otpactivityBinding.etKode4))
otpactivityBinding.etKode4.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode4, otpactivityBinding.etKode5))
otpactivityBinding.etKode5.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode5, otpactivityBinding.etKode6))
otpactivityBinding.etKode6.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode6, otpactivityBinding.etKode7))
otpactivityBinding.etKode7.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode7, otpactivityBinding.etKode8))
otpactivityBinding.etKode8.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode8, null))
otpactivityBinding.etKode2.setOnKeyListener(GenericKeyEvent(otpactivityBinding.etKode2, otpactivityBinding.etKode1))
otpactivityBinding.etKode3.setOnKeyListener(GenericKeyEvent(otpactivityBinding.etKode3, otpactivityBinding.etKode2))
otpactivityBinding.etKode4.setOnKeyListener(GenericKeyEvent(otpactivityBinding.etKode4, otpactivityBinding.etKode3))
otpactivityBinding.etKode5.setOnKeyListener(GenericKeyEvent(otpactivityBinding.etKode5, otpactivityBinding.etKode4))
otpactivityBinding.etKode6.setOnKeyListener(GenericKeyEvent(otpactivityBinding.etKode6, otpactivityBinding.etKode5))
otpactivityBinding.etKode7.setOnKeyListener(GenericKeyEvent(otpactivityBinding.etKode7, otpactivityBinding.etKode6))
otpactivityBinding.etKode8.setOnKeyListener(GenericKeyEvent(otpactivityBinding.etKode8, otpactivityBinding.etKode7))
}
这里是4EditText
输入数字密码。我希望它是这样的,如果第一个 EditText
被 1 个数字填充,那么焦点应该转到下一个 EditText
并且也应该以相反的方式工作。这样用户可以一直从最左边输入密码,也可以从最右边用同样的方式擦除。
有人可以建议最好的方法是什么吗?
如果您熟悉 RxJava
,那么这可能是满足您需求的最简单方法。
这是 Kotlin
代码示例
RxTextView.textChanges(edtOtp1).filter { it.length == 1 }.subscribe { edtOtp2.requestFocus() }
RxTextView.textChanges(edtOtp2).filter { it.length == 1 }.subscribe { edtOtp3.requestFocus() }
RxTextView.textChanges(edtOtp3).filter { it.length == 1 }.subscribe { edtOtp4.requestFocus() }
RxTextView.textChanges(edtOtp4).filter { it.length == 1 }.subscribe { context.hideKeyboard(view) }
你也可以用同样的方式写反向。当长度为零时,焦点指向前一个 Edittext。
您可以使用图书馆 Android PinView / OtpView
或者您可以使用 addTextChangedListener
添加一个 TextWatcher
,每当此 EditTextView 的文本更改时调用它,然后您可以在下一个 EditText 上调用 View.requestFocus()
来聚焦它
你可以做到
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<EditText
android:id="@+id/otpET1"
android:layout_width="30dp"
android:layout_height="30dp"
android:inputType="number"
android:maxLength="1"
android:gravity="center"
android:textSize="20sp"/>
<EditText
android:id="@+id/otpET2"
android:layout_width="30dp"
android:layout_height="30dp"
android:inputType="number"
android:maxLength="1"
android:gravity="center"
android:textSize="20sp"/>
<EditText
android:id="@+id/otpET3"
android:layout_width="30dp"
android:layout_height="30dp"
android:inputType="number"
android:maxLength="1"
android:gravity="center"
android:textSize="20sp"/>
<EditText
android:id="@+id/otpET4"
android:layout_width="30dp"
android:layout_height="30dp"
android:inputType="number"
android:maxLength="1"
android:gravity="center"
android:textSize="20sp"/>
<EditText
android:id="@+id/otpET5"
android:layout_width="30dp"
android:layout_height="30dp"
android:inputType="number"
android:maxLength="1"
android:gravity="center"
android:textSize="20sp"/>
<EditText
android:id="@+id/otpET6"
android:layout_width="30dp"
android:layout_height="30dp"
android:inputType="number"
android:gravity="center"
android:maxLength="1"
android:textSize="20sp"/>
</LinearLayout>
在activity
EditText[] otpETs = new EditText[6];
otpETs[0] = findViewById(R.id.otpET1);
otpETs[1] = findViewById(R.id.otpET2);
otpETs[2] = findViewById(R.id.otpET3);
otpETs[3] = findViewById(R.id.otpET4);
otpETs[4] = findViewById(R.id.otpET5);
otpETs[5] = findViewById(R.id.otpET6);
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
int keyCode = event.getKeyCode();
if (keyCode == 7 || keyCode == 8 ||
keyCode == 9 || keyCode == 10 ||
keyCode == 11 || keyCode == 12 ||
keyCode == 13 || keyCode == 14 ||
keyCode == 15 || keyCode == 16 ||
keyCode == 67) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KEYCODE_DEL) {
int index = checkWhoHasFocus();
if (index != 123) {
if (Helpers.rS(otpETs[index]).equals("")) {
if (index != 0) {
otpETs[index - 1].requestFocus();
}
} else {
return super.dispatchKeyEvent(event);
}
}
} else {
int index = checkWhoHasFocus();
if (index != 123) {
if (Helpers.rS(otpETs[index]).equals("")) {
return super.dispatchKeyEvent(event);
} else {
if (index != 5) {
otpETs[index + 1].requestFocus();
}
}
}
return super.dispatchKeyEvent(event);
}
}
} else {
return super.dispatchKeyEvent(event);
}
return true;
}
private int checkWhoHasFocus() {
for (int i = 0; i < otpETs.length; i++) {
EditText tempET = otpETs[i];
if (tempET.hasFocus()) {
return i;
}
}
return 123;
}
这只是为了从 editTexts 中获取字符串
public class Helpers {
public static String rS(EditText editText) {
return editText.getText().toString().trim();
}
}
最后,
String code = Helpers.rS(otpETs[0]) + Helpers.rS(otpETs[1]) +
Helpers.rS(otpETs[2]) + Helpers.rS(otpETs[3]) + Helpers.rS(otpETs[4])
+ Helpers.rS(otpETs[5]);
或者只使用一个简单的 for/while
循环。
在 Kotlin 中你可以像 ..
txtOTP_1.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (txtOTP_1.text.toString().length == 1) {
txtOTP_1.clearFocus()
txtOTP_2.requestFocus()
txtOTP_2.setCursorVisible(true)
}
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun afterTextChanged(s: Editable) {
if (txtOTP_1.text.toString().length == 0) {
txtOTP_1.requestFocus()
}
}
})
txtOTP_2.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (txtOTP_2.text.toString().length == 1) {
txtOTP_2.clearFocus()
txtOTP_3.requestFocus()
txtOTP_3.setCursorVisible(true)
}
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun afterTextChanged(s: Editable) {
if (txtOTP_2.text.toString().length == 0) {
txtOTP_2.requestFocus()
}
}
})
txtOTP_3.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (txtOTP_3.text.toString().length == 1) {
txtOTP_3.clearFocus()
txtOTP_4.requestFocus()
txtOTP_4.setCursorVisible(true)
}
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun afterTextChanged(s: Editable) {
if (txtOTP_3.text.toString().length == 0) {
txtOTP_3.requestFocus()
}
}
})
txtOTP_4.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (txtOTP_4.text.toString().length == 1) {
txtOTP_4.clearFocus()
txtOTP_5.requestFocus()
txtOTP_5.setCursorVisible(true)
}
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
}
override fun afterTextChanged(s: Editable) {
if (txtOTP_4.text.toString().length == 0) {
txtOTP_4.requestFocus()
}
}
})
txtOTP_5.addTextChangedListener(object : TextWatcher {
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
if (txtOTP_5.text.toString().length == 1) {
txtOTP_5.requestFocus()
txtOTP_5.setCursorVisible(true)
}
}
})
您无法单独使用 addTextChangedListener 完成它。您可能必须同时设置 onKeyListener。这是给你的代码:
//6 EditTexts are otpEt[0], otpEt[1],...otpEt[5]
private EditText[] otpEt = new EditText[6];
otpEt[0] = (EditText) findViewById(R.id.otpEt1);
otpEt[1] = (EditText) findViewById(R.id.otpEt2);
otpEt[2] = (EditText) findViewById(R.id.otpEt3);
otpEt[3] = (EditText) findViewById(R.id.otpEt4);
otpEt[4] = (EditText) findViewById(R.id.otpEt5);
otpEt[5] = (EditText) findViewById(R.id.otpEt6);
setOtpEditTextHandler();
private void setOtpEditTextHandler () { //This is the function to be called
for (int i = 0;i < 6;i++) { //Its designed for 6 digit OTP
final int iVal = i;
otpEt[iVal].addTextChangedListener(new TextWatcher() {
@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) {
if(iVal == 5 && !otpEt[iVal].getText().toString().isEmpty()) {
otpEt[iVal].clearFocus(); //Clears focus when you have entered the last digit of the OTP.
} else if (!otpEt[iVal].getText().toString().isEmpty()) {
otpEt[iVal+1].requestFocus(); //focuses on the next edittext after a digit is entered.
}
}
});
otpEt[iVal].setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() != KeyEvent.ACTION_DOWN) {
return false; //Dont get confused by this, it is because onKeyListener is called twice and this condition is to avoid it.
}
if(keyCode == KeyEvent.KEYCODE_DEL &&
otpEt[iVal].getText().toString().isEmpty() && iVal != 0) {
//this condition is to handel the delete input by users.
otpEt[iVal-1].setText("");//Deletes the digit of OTP
otpEt[iVal-1].requestFocus();//and sets the focus on previous digit
}
return false;
}
});
}
}
如果您觉得这段代码很难,只需将其粘贴到您的项目中并尝试重新排列。您将能够轻松获得它
你做的第一件事
class GenericTextWatcher(private val currentView: EditText,nextView: EditText?) :
TextWatcher {
private val nextView: EditText?
override fun afterTextChanged(editable: Editable) {
// TODO Auto-generated method stub
val text = editable.toString()
if (nextView != null && text.length == 1) {
nextView.requestFocus()
}
if (text.length > 1) {
currentView.setText(text[text.length - 1].toString())
currentView.setSelection(1)
}
}
override fun beforeTextChanged(arg0: CharSequence, arg1: Int, arg2: Int, arg3: Int) {
// TODO Auto-generated method stub
}
override fun onTextChanged(arg0: CharSequence, arg1: Int, arg2: Int, arg3: Int) {
// TODO Auto-generated method stub
}
init {
this.nextView = nextView
}
class GenericKeyEvent(
private val currentView: EditText,
private val previousView: EditText?
) :
View.OnKeyListener {
override fun onKey(v: View, keyCode: Int, event: KeyEvent): Boolean {
if (event.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_DEL && currentView.text.toString()
.isEmpty()
) {
previousView?.requestFocus()
return true
}
return false
}
你可以使用这个功能
private fun attachTextWatchersSMS(){
otpactivityBinding.etKode1.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode1, otpactivityBinding.etKode2))
otpactivityBinding.etKode2.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode2, otpactivityBinding.etKode3))
otpactivityBinding.etKode3.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode3, otpactivityBinding.etKode4))
otpactivityBinding.etKode4.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode4, otpactivityBinding.etKode5))
otpactivityBinding.etKode5.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode5, otpactivityBinding.etKode6))
otpactivityBinding.etKode6.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode6, otpactivityBinding.etKode7))
otpactivityBinding.etKode7.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode7, otpactivityBinding.etKode8))
otpactivityBinding.etKode8.addTextChangedListener(GenericTextWatcher(otpactivityBinding.etKode8, null))
otpactivityBinding.etKode2.setOnKeyListener(GenericKeyEvent(otpactivityBinding.etKode2, otpactivityBinding.etKode1))
otpactivityBinding.etKode3.setOnKeyListener(GenericKeyEvent(otpactivityBinding.etKode3, otpactivityBinding.etKode2))
otpactivityBinding.etKode4.setOnKeyListener(GenericKeyEvent(otpactivityBinding.etKode4, otpactivityBinding.etKode3))
otpactivityBinding.etKode5.setOnKeyListener(GenericKeyEvent(otpactivityBinding.etKode5, otpactivityBinding.etKode4))
otpactivityBinding.etKode6.setOnKeyListener(GenericKeyEvent(otpactivityBinding.etKode6, otpactivityBinding.etKode5))
otpactivityBinding.etKode7.setOnKeyListener(GenericKeyEvent(otpactivityBinding.etKode7, otpactivityBinding.etKode6))
otpactivityBinding.etKode8.setOnKeyListener(GenericKeyEvent(otpactivityBinding.etKode8, otpactivityBinding.etKode7))
}