Mou*_*esh 22 android android-edittext
嗨,我正在开发一个应用程序,当用户想要重置他的密码时,要求OTP,我需要一个像附加图像中那样的文本...我想继续的是每个字母的单独文本,全部它们排列成水平方向的线性布局,有一些边距......最大长度为1,因此每个editText只能输入一个字母......这是一个正确的方法吗?有什么建议??
Lal*_*dar 27
在所有这些答案之后,考虑到 UI/UX,我没有找到我想要的东西,元素的删除存在缺陷,以至于要回到以前的状态EditText,当前 EditText 不应为空。
这是我在 Kotlin 中实现的解决方案,它适用于通过在键盘上按下的 Delete 键进行删除。此外,delete 函数是这样实现的,当当前EditText为空并按下 Delete 键时,它会切换回上一个EditText并删除其元素。
调用函数如下:
//GenericTextWatcher here works only for moving to next EditText when a number is entered
//first parameter is the current EditText and second parameter is next EditText
editText1.addTextChangedListener(GenericTextWatcher(editText1, editText2))
editText2.addTextChangedListener(GenericTextWatcher(editText2, editText3))
editText3.addTextChangedListener(GenericTextWatcher(editText3, editText4))
editText4.addTextChangedListener(GenericTextWatcher(editText4, null))
//GenericKeyEvent here works for deleting the element and to switch back to previous EditText
//first parameter is the current EditText and second parameter is previous EditText
editText1.setOnKeyListener(GenericKeyEvent(editText1, null))
editText2.setOnKeyListener(GenericKeyEvent(editText2, editText1))
editText3.setOnKeyListener(GenericKeyEvent(editText3, editText2))
editText4.setOnKeyListener(GenericKeyEvent(editText4,editText3))
Run Code Online (Sandbox Code Playgroud)现在,将这两个类粘贴到您当前的类中
class GenericKeyEvent internal constructor(private val currentView: EditText, private val previousView: EditText?) : View.OnKeyListener{
override fun onKey(p0: View?, keyCode: Int, event: KeyEvent?): Boolean {
if(event!!.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_DEL && currentView.id != R.id.editText1 && currentView.text.isEmpty()) {
//If current is empty then previous EditText's number will also be deleted
previousView!!.text = null
previousView.requestFocus()
return true
}
return false
}
}
class GenericTextWatcher internal constructor(private val currentView: View, private val nextView: View?) : TextWatcher {
override fun afterTextChanged(editable: Editable) { // TODO Auto-generated method stub
val text = editable.toString()
when (currentView.id) {
R.id.editText1 -> if (text.length == 1) nextView!!.requestFocus()
R.id.editText2 -> if (text.length == 1) nextView!!.requestFocus()
R.id.editText3 -> if (text.length == 1) nextView!!.requestFocus()
//You can use EditText4 same as above to hide the keyboard
}
}
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
}
}
Run Code Online (Sandbox Code Playgroud)此外,要禁用可见光标,您可以在布局android:cursorVisible="false"中的EditText标记中使用,也可以使用 java 函数setCursorVisible(false)。
编辑:我正在使用股票小部件,EditTexts因此如果您想在它们周围显示一个框,只需创建一个可绘制的布局并将其设置为背景EditTexts并为它们提供 5dp 的填充。这将创建一个盒子并使其看起来更酷。
A.R*_*.R. 21
您可以通过使TextWatcher更通用来尝试这一点,因此它易于使用和理解
使用以下课程:
public class GenericTextWatcher implements TextWatcher
{
private View view;
private GenericTextWatcher(View view)
{
this.view = view;
}
@Override
public void afterTextChanged(Editable editable) {
// TODO Auto-generated method stub
String text = editable.toString();
switch(view.getId())
{
case R.id.editText1:
if(text.length()==1)
et2.requestFocus();
break;
case R.id.editText2:
if(text.length()==1)
et3.requestFocus();
else if(text.length()==0)
et1.requestFocus();
break;
case R.id.editText3:
if(text.length()==1)
et4.requestFocus();
else if(text.length()==0)
et2.requestFocus();
break;
case R.id.editText4:
if(text.length()==0)
et3.requestFocus();
break;
}
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
}
Run Code Online (Sandbox Code Playgroud)
如何使用上面的课程
et1.addTextChangedListener(new GenericTextWatcher(et1));
et2.addTextChangedListener(new GenericTextWatcher(et2));
et3.addTextChangedListener(new GenericTextWatcher(et3));
et4.addTextChangedListener(new GenericTextWatcher(et4));
Run Code Online (Sandbox Code Playgroud)
这里et1,et2,et3和et4是你的EditTexts,我知道它根据Java标准的错误命名约定,但你可以用你的替换它.
PS你可以在这里找到一些 xml设计 GitHub,其他一些样本设计xml供参考
public class GenericTextWatcher implements TextWatcher {
private EditText etPrev;
private EditText etNext;
public GenericTextWatcher(EditText etNext, EditText etPrev) {
this.etPrev = etPrev;
this.etNext = etNext;
}
@Override
public void afterTextChanged(Editable editable) {
String text = editable.toString();
if (text.length() == 1)
etNext.requestFocus();
else if (text.length() == 0)
etPrev.requestFocus();
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
}
}
Run Code Online (Sandbox Code Playgroud)
接下来,我们在每个编辑文本上添加 addTextChangedListener。
e1.addTextChangedListener(new GenericTextWatcher(e2, e1))
e2.addTextChangedListener(new GenericTextWatcher(e3, e1))
e3.addTextChangedListener(new GenericTextWatcher(e4, e2))
e4.addTextChangedListener(new GenericTextWatcher(e5, e3))
e5.addTextChangedListener(new GenericTextWatcher(e6, e4))
e6.addTextChangedListener(new GenericTextWatcher(e6, e5))
Run Code Online (Sandbox Code Playgroud)
小智 8
我根据其他答案实现了以下代码。
我希望这段代码非常简单,经过优化并且可以理解更改。
不要android:maxLength="1"在您的xml中使用。
//package your package
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
public class PinActivity extends AppCompatActivity {
private EditText editText1, editText2, editText3, editText4;
private EditText[] editTexts;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pin);
editText1 = (EditText) findViewById(R.id.otpEdit1);
editText2 = (EditText) findViewById(R.id.otpEdit2);
editText3 = (EditText) findViewById(R.id.otpEdit3);
editText4 = (EditText) findViewById(R.id.otpEdit4);
editTexts = new EditText[]{editText1, editText2, editText3, editText4};
editText1.addTextChangedListener(new PinTextWatcher(0));
editText2.addTextChangedListener(new PinTextWatcher(1));
editText3.addTextChangedListener(new PinTextWatcher(2));
editText4.addTextChangedListener(new PinTextWatcher(3));
editText1.setOnKeyListener(new PinOnKeyListener(0));
editText2.setOnKeyListener(new PinOnKeyListener(1));
editText3.setOnKeyListener(new PinOnKeyListener(2));
editText4.setOnKeyListener(new PinOnKeyListener(3));
}
public class PinTextWatcher implements TextWatcher {
private int currentIndex;
private boolean isFirst = false, isLast = false;
private String newTypedString = "";
PinTextWatcher(int currentIndex) {
this.currentIndex = currentIndex;
if (currentIndex == 0)
this.isFirst = true;
else if (currentIndex == editTexts.length - 1)
this.isLast = true;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
newTypedString = s.subSequence(start, start + count).toString().trim();
}
@Override
public void afterTextChanged(Editable s) {
String text = newTypedString;
/* Detect paste event and set first char */
if (text.length() > 1)
text = String.valueOf(text.charAt(0)); // TODO: We can fill out other EditTexts
editTexts[currentIndex].removeTextChangedListener(this);
editTexts[currentIndex].setText(text);
editTexts[currentIndex].setSelection(text.length());
editTexts[currentIndex].addTextChangedListener(this);
if (text.length() == 1)
moveToNext();
else if (text.length() == 0)
moveToPrevious();
}
private void moveToNext() {
if (!isLast)
editTexts[currentIndex + 1].requestFocus();
if (isAllEditTextsFilled() && isLast) { // isLast is optional
editTexts[currentIndex].clearFocus();
hideKeyboard();
}
}
private void moveToPrevious() {
if (!isFirst)
editTexts[currentIndex - 1].requestFocus();
}
private boolean isAllEditTextsFilled() {
for (EditText editText : editTexts)
if (editText.getText().toString().trim().length() == 0)
return false;
return true;
}
private void hideKeyboard() {
if (getCurrentFocus() != null) {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
}
}
public class PinOnKeyListener implements View.OnKeyListener {
private int currentIndex;
PinOnKeyListener(int currentIndex) {
this.currentIndex = currentIndex;
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN) {
if (editTexts[currentIndex].getText().toString().isEmpty() && currentIndex != 0)
editTexts[currentIndex - 1].requestFocus();
}
return false;
}
}
}
Run Code Online (Sandbox Code Playgroud)
OtpEditText.java(自定义EditText):
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.Editable;
import android.util.AttributeSet;
import android.view.ActionMode;
import android.view.View;
import androidx.appcompat.widget.AppCompatEditText;
public class OtpEditText extends AppCompatEditText {
private float mSpace = 24; //24 dp by default, space between the lines
private float mNumChars = 4;
private float mLineSpacing = 8; //8dp by default, height of the text from our lines
private int mMaxLength = 4;
private float mLineStroke = 2;
private Paint mLinesPaint;
private OnClickListener mClickListener;
public OtpEditText(Context context) {
super(context);
}
public OtpEditText(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public OtpEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs) {
float multi = context.getResources().getDisplayMetrics().density;
mLineStroke = multi * mLineStroke;
mLinesPaint = new Paint(getPaint());
mLinesPaint.setStrokeWidth(mLineStroke);
mLinesPaint.setColor(getResources().getColor(R.color.colorPrimaryDark));
setBackgroundResource(0);
mSpace = multi * mSpace; //convert to pixels for our density
mLineSpacing = multi * mLineSpacing; //convert to pixels for our density
mNumChars = mMaxLength;
super.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// When tapped, move cursor to end of text.
setSelection(getText().length());
if (mClickListener != null) {
mClickListener.onClick(v);
}
}
});
}
@Override
public void setOnClickListener(OnClickListener l) {
mClickListener = l;
}
@Override
public void setCustomSelectionActionModeCallback(ActionMode.Callback actionModeCallback) {
throw new RuntimeException("setCustomSelectionActionModeCallback() not supported.");
}
@Override
protected void onDraw(Canvas canvas) {
int availableWidth = getWidth() - getPaddingRight() - getPaddingLeft();
float mCharSize;
if (mSpace < 0) {
mCharSize = (availableWidth / (mNumChars * 2 - 1));
} else {
mCharSize = (availableWidth - (mSpace * (mNumChars - 1))) / mNumChars;
}
int startX = getPaddingLeft();
int bottom = getHeight() - getPaddingBottom();
//Text Width
Editable text = getText();
int textLength = text.length();
float[] textWidths = new float[textLength];
getPaint().getTextWidths(getText(), 0, textLength, textWidths);
for (int i = 0; i < mNumChars; i++) {
canvas.drawLine(startX, bottom, startX + mCharSize, bottom, mLinesPaint);
if (getText().length() > i) {
float middle = startX + mCharSize / 2;
canvas.drawText(text, i, i + 1, middle - textWidths[0] / 2, bottom - mLineSpacing, getPaint());
}
if (mSpace < 0) {
startX += mCharSize * 2;
} else {
startX += mCharSize + mSpace;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如下所示在XML中使用此自定义的EditText:
<OtpEditText
android:id="@+id/et_otp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cursorVisible="false"
android:digits="1234567890"
android:inputType="number"
android:maxLength="4"
android:textIsSelectable="false"
android:textSize="20sp"/>
Run Code Online (Sandbox Code Playgroud)
参考:
文章: https : //medium.com/@ali.muzaffar/building-a-pinentryedittext-in-android-5f2eddcae5d3
示例代码: https : //gist.github.com/alphamu/0d3055e0233c5749b8d6
private class GenericTextWatcher implements TextWatcher {
private EditText currentView;
private EditText nextView;
private GenericTextWatcher(EditText currentView, EditText nextView) {
this.currentView = currentView;
this.nextView = nextView;
}
@Override
public void afterTextChanged(Editable editable) {
// TODO Auto-generated method stub
String text = editable.toString();
if (nextView != null && text.length() == 1) {
nextView.requestFocus();
}
if(text.length() >1){
currentView.setText(String.valueOf(text.charAt(text.length() - 1)));
currentView.setSelection(1);
}
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
}
private class GenericKeyEvent implements View.OnKeyListener {
private EditText currentView;
private EditText previousView;
public GenericKeyEvent(EditText currentView, EditText previousView) {
this.currentView = currentView;
this.previousView = previousView;
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_DEL && currentView.getText().toString().isEmpty()) {
if (previousView != null) {
previousView.requestFocus();
}
return true;
}
return false;
}
}
Run Code Online (Sandbox Code Playgroud)
private void attachTextWatchers() {
binding.editText1.addTextChangedListener(new GenericTextWatcher(binding.editText1, binding.editText2));
binding.editText2.addTextChangedListener(new GenericTextWatcher(binding.editText2, binding.editText3));
binding.editText3.addTextChangedListener(new GenericTextWatcher(binding.editText3, binding.editText4));
binding.editText4.addTextChangedListener(new GenericTextWatcher(binding.editText4, null));
binding.editText2.setOnKeyListener(new GenericKeyEvent(binding.editText2, binding.editText1));
binding.editText3.setOnKeyListener(new GenericKeyEvent(binding.editText3, binding.editText2));
binding.editText4.setOnKeyListener(new GenericKeyEvent(binding.editText4, binding.editText3));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
28184 次 |
| 最近记录: |