我在我的应用中验证otp时使用此编辑文字。
我可以使用6个编辑文本来执行此操作,例如 my_layout.xml 是否可以使用单个编辑文本来做这件事。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:wheel="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="To complete the installation,\nplease enter the 6-digit\nverification code."
android:id="@+id/textView4"
android:textColor="@color/black"
android:gravity="center" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLength="1"
android:gravity="center" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLength="1"
android:gravity="center" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLength="1"
android:gravity="center" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLength="1"
android:layout_marginLeft="15dp"
android:gravity="center" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLength="1"
android:gravity="center" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLength="1"
android:gravity="center" />
</LinearLayout>
</LinearLayout>
答案 0 :(得分:2)
你必须实现TextWacher并一次删除它们,你的EditText看起来像这样
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editText"
android:singleLine="true"
android:text="______"
android:inputType = "textNoSuggestions"
android:letterSpacing="0.4" -->Its the spacing of letter
android:textSize="29sp" />
这是实施
EditText editText;
String text;
boolean delete = false;
text = editText.getText().toString();
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
text = editText.getText().toString();
if (count > after)
delete = true;
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
StringBuilder sb = new StringBuilder(s.toString());
int replacePosition = editText.getSelectionEnd();
if (s.length() != 6) { //where 6 is the character underline per text
if (!delete) {
if (replacePosition < s.length())
sb.deleteCharAt(replacePosition);
} else {
sb.insert(replacePosition, '_');
}
if (replacePosition < s.length() || delete) {
editText.setText(sb.toString());
editText.setSelection(replacePosition);
} else {
editText.setText(text);
editText.setSelection(replacePosition - 1);
}
}
}
delete = false;
}
@Override
public void afterTextChanged(Editable s) {
}
});
答案 1 :(得分:-1)
我认为为时已晚,但是一旦你有时间,你应该试试这个。我希望这能满足你的要求。
pincode_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_marginTop="2dp"
android:layout_marginBottom="2dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout android:id="@+id/pin_layout"
android:layout_width="match_parent"
android:layout_height="56dp"
android:orientation="horizontal"
android:gravity="center_horizontal"
android:layout_gravity="center_horizontal">
<EditText android:id="@+id/pin_first_edittext"
android:layout_width="40dp"
android:gravity="center"
android:layout_height="match_parent"
android:background="@drawable/otp_drawable"
style="@style/otp_edittext_style" />
<EditText android:id="@+id/pin_second_edittext"
android:layout_width="40dp"
android:layout_marginLeft="11dp"
android:background="@drawable/otp_drawable"
android:layout_height="match_parent"
style="@style/otp_edittext_style" />
<EditText android:id="@+id/pin_third_edittext"
android:layout_width="40dp"
android:layout_marginLeft="11dp"
android:background="@drawable/otp_drawable"
android:layout_height="match_parent"
style="@style/otp_edittext_style" />
<EditText android:id="@+id/pin_forth_edittext"
android:layout_width="40dp"
android:layout_marginLeft="11dp"
android:background="@drawable/otp_drawable"
android:layout_height="match_parent"
style="@style/otp_edittext_style" />
<EditText android:id="@+id/pin_fifth_edittext"
android:layout_width="40dp"
android:layout_marginLeft="11dp"
android:background="@drawable/otp_drawable"
android:layout_height="match_parent"
style="@style/otp_edittext_style" />
<EditText android:id="@+id/pin_sixth_edittext"
android:layout_width="40dp"
android:layout_marginLeft="11dp"
android:background="@drawable/otp_drawable"
android:layout_height="match_parent"
style="@style/otp_edittext_style" />
</LinearLayout>
<EditText android:id="@+id/pin_hidden_edittext"
android:layout_width="1dp"
android:layout_height="1dp"
android:gravity="center_horizontal"
android:layout_gravity="center_horizontal"
android:background="@null"
android:cursorVisible="false"
android:maxLength="6"
android:textColor="#00000000"
android:contentDescription="@string/pin_content_desc" />
PinCodeLayout.java
import android.app.Service;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.Nullable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;
import com.elanic.R;
import com.elanic.utils.StringUtils;
/**
* Created by sandeep on 8/19/2017.
*/
public class PinCodeLayout extends LinearLayout implements
View.OnFocusChangeListener, View.OnKeyListener, TextWatcher {
private EditText mPinFirstDigitEditText;
private EditText mPinSecondDigitEditText;
private EditText mPinThirdDigitEditText;
private EditText mPinForthDigitEditText;
private EditText mPinFifthDigitEditText;
private EditText mPinSixthDigitEditText;
private EditText mPinHiddenEditText;
private boolean isManuallyEntering = true;
private String pinCodeText;
private PinCodeCallBack pinCodeCallback;
public PinCodeLayout(Context context) {
super(context);
init(context);
}
public PinCodeLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public PinCodeLayout(Context context, @Nullable AttributeSet attrs, int
defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int
after) {
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
final int id = v.getId();
switch (id) {
case R.id.pin_first_edittext:
if (hasFocus) {
setFocus(mPinHiddenEditText);
showSoftKeyboard(mPinHiddenEditText);
}
break;
case R.id.pin_second_edittext:
if (hasFocus) {
setFocus(mPinHiddenEditText);
showSoftKeyboard(mPinHiddenEditText);
}
break;
case R.id.pin_third_edittext:
if (hasFocus) {
setFocus(mPinHiddenEditText);
showSoftKeyboard(mPinHiddenEditText);
}
break;
case R.id.pin_forth_edittext:
if (hasFocus) {
setFocus(mPinHiddenEditText);
showSoftKeyboard(mPinHiddenEditText);
}
break;
case R.id.pin_fifth_edittext:
if (hasFocus) {
setFocus(mPinHiddenEditText);
showSoftKeyboard(mPinHiddenEditText);
}
break;
case R.id.pin_sixth_edittext:
if (hasFocus) {
setFocus(mPinHiddenEditText);
showSoftKeyboard(mPinHiddenEditText);
}
break;
default:
break;
}
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
final int id = v.getId();
switch (id) {
case R.id.pin_hidden_edittext:
if (keyCode == KeyEvent.KEYCODE_DEL) {
if (mPinHiddenEditText.getText().length() == 6)
mPinSixthDigitEditText.setText("");
else if (mPinHiddenEditText.getText().length() == 5)
mPinFifthDigitEditText.setText("");
else if (mPinHiddenEditText.getText().length() == 4)
mPinForthDigitEditText.setText("");
else if (mPinHiddenEditText.getText().length() == 3)
mPinThirdDigitEditText.setText("");
else if (mPinHiddenEditText.getText().length() == 2)
mPinSecondDigitEditText.setText("");
else if (mPinHiddenEditText.getText().length() == 1)
mPinFirstDigitEditText.setText("");
if (mPinHiddenEditText.length() > 0) {
mPinHiddenEditText.setText(mPinHiddenEditText.getText()
.subSequence(0, mPinHiddenEditText.length() - 1));
mPinHiddenEditText.post(new Runnable() {
@Override
public void run() {
mPinHiddenEditText.setSelection(mPinHiddenEditText.
getText().toString().length());
}
});
}
return true;
}
case R.id.pin_first_edittext:
case R.id.pin_second_edittext:
case R.id.pin_third_edittext:
case R.id.pin_forth_edittext:
case R.id.pin_fifth_edittext:
case R.id.pin_sixth_edittext:
if (keyCode == KeyEvent.KEYCODE_0 || keyCode ==
KeyEvent.KEYCODE_1 ||
keyCode == KeyEvent.KEYCODE_2 || keyCode ==
KeyEvent.KEYCODE_3 ||
keyCode == KeyEvent.KEYCODE_4 || keyCode ==
KeyEvent.KEYCODE_5 ||
keyCode == KeyEvent.KEYCODE_6 || keyCode ==
KeyEvent.KEYCODE_7 ||
keyCode == KeyEvent.KEYCODE_8 || keyCode ==
KeyEvent.KEYCODE_9) {
isManuallyEntering = true;
}
break;
default:
return false;
}
}
return false;
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
setDefaultPinBackground(mPinFirstDigitEditText);
setDefaultPinBackground(mPinSecondDigitEditText);
setDefaultPinBackground(mPinThirdDigitEditText);
setDefaultPinBackground(mPinForthDigitEditText);
setDefaultPinBackground(mPinFifthDigitEditText);
setDefaultPinBackground(mPinSixthDigitEditText);
if (s.length() == 0) {
setFocusedPinBackground(mPinFirstDigitEditText);
mPinFirstDigitEditText.setText("");
pinCodeText = "";
} else if (s.length() == 1) {
setFocusedPinBackground(mPinSecondDigitEditText);
mPinFirstDigitEditText.setText(s.charAt(0) + "");
mPinSecondDigitEditText.setText("");
mPinThirdDigitEditText.setText("");
mPinForthDigitEditText.setText("");
mPinFifthDigitEditText.setText("");
mPinSixthDigitEditText.setText("");
} else if (s.length() == 2) {
setFocusedPinBackground(mPinThirdDigitEditText);
mPinSecondDigitEditText.setText(s.charAt(1) + "");
mPinThirdDigitEditText.setText("");
mPinForthDigitEditText.setText("");
mPinFifthDigitEditText.setText("");
mPinSixthDigitEditText.setText("");
} else if (s.length() == 3) {
setFocusedPinBackground(mPinForthDigitEditText);
mPinThirdDigitEditText.setText(s.charAt(2) + "");
mPinForthDigitEditText.setText("");
mPinFifthDigitEditText.setText("");
mPinSixthDigitEditText.setText("");
} else if (s.length() == 4) {
setFocusedPinBackground(mPinFifthDigitEditText);
mPinForthDigitEditText.setText(s.charAt(3) + "");
mPinFifthDigitEditText.setText("");
mPinSixthDigitEditText.setText("");
} else if (s.length() == 5) {
setFocusedPinBackground(mPinSixthDigitEditText);
mPinFifthDigitEditText.setText(s.charAt(4) + "");
mPinSixthDigitEditText.setText("");
} else if (s.length() == 6) {
mPinSixthDigitEditText.setText(s.charAt(5) + "");
setDefaultPinBackground(mPinSixthDigitEditText);
pinCodeText = s.toString();
hideSoftKeyboard(mPinSixthDigitEditText);
if (isManuallyEntering) {
pinCodeCallback.onPinCodeEntered();
}
}
}
@Override
public void afterTextChanged(Editable s) {
}
private void init(Context context) {
LayoutInflater inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.pincode_layout, this);
init();
setPINListeners();
}
/**
* Initialize EditText fields.
*/
private void init() {
mPinFirstDigitEditText = (EditText)
findViewById(R.id.pin_first_edittext);
mPinSecondDigitEditText = (EditText)
findViewById(R.id.pin_second_edittext);
mPinThirdDigitEditText = (EditText)
findViewById(R.id.pin_third_edittext);
mPinForthDigitEditText = (EditText)
findViewById(R.id.pin_forth_edittext);
mPinFifthDigitEditText = (EditText)
findViewById(R.id.pin_fifth_edittext);
mPinSixthDigitEditText = (EditText)
findViewById(R.id.pin_sixth_edittext);
mPinHiddenEditText = (EditText) findViewById(R.id.pin_hidden_edittext);
isManuallyEntering = true;
}
private void setPINListeners() {
mPinHiddenEditText.addTextChangedListener(this);
mPinFirstDigitEditText.setOnFocusChangeListener(this);
mPinSecondDigitEditText.setOnFocusChangeListener(this);
mPinThirdDigitEditText.setOnFocusChangeListener(this);
mPinForthDigitEditText.setOnFocusChangeListener(this);
mPinFifthDigitEditText.setOnFocusChangeListener(this);
mPinSixthDigitEditText.setOnFocusChangeListener(this);
mPinFirstDigitEditText.setOnKeyListener(this);
mPinSecondDigitEditText.setOnKeyListener(this);
mPinThirdDigitEditText.setOnKeyListener(this);
mPinForthDigitEditText.setOnKeyListener(this);
mPinFifthDigitEditText.setOnKeyListener(this);
mPinSixthDigitEditText.setOnKeyListener(this);
mPinHiddenEditText.setOnKeyListener(this);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int proposedHeight = MeasureSpec.getSize(heightMeasureSpec);
final int actualHeight = getHeight();
Log.d("TAG", "proposed: " + proposedHeight + ", actual: " +
actualHeight);
if (actualHeight >= proposedHeight) {
// Keyboard is shown
if (mPinHiddenEditText.length() == 0)
setFocusedPinBackground(mPinFirstDigitEditText);
else
setDefaultPinBackground(mPinFirstDigitEditText);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* Sets default PIN background.
*
* @param editText edit text to change
*/
private void setDefaultPinBackground(EditText editText) {
setViewBackground(editText,
getResources().getDrawable(R.drawable.otp_drawable));
}
/**
* Sets focus on a specific EditText field.
*
* @param editText EditText to set focus on
*/
public static void setFocus(EditText editText) {
if (editText == null)
return;
editText.setFocusable(true);
editText.setFocusableInTouchMode(true);
editText.requestFocus();
}
/**
* Sets focused PIN field background.
*
* @param editText edit text to change
*/
private void setFocusedPinBackground(EditText editText) {
setViewBackground(editText,
getResources().getDrawable(R.drawable.otp_drawable));
}
/**
* Sets background of the view.
* This method varies in implementation depending on Android SDK version.
*
* @param view View to which set background
* @param background Background to set to view
*/
@SuppressWarnings("deprecation")
public void setViewBackground(View view, Drawable background) {
if (view == null || background == null)
return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
view.setBackground(background);
} else {
view.setBackgroundDrawable(background);
}
}
/**
* Shows soft keyboard.
*
* @param editText EditText which has focus
*/
public void showSoftKeyboard(EditText editText) {
if (editText == null)
return;
InputMethodManager imm = (InputMethodManager)
getContext().getSystemService(Service.INPUT_METHOD_SERVICE);
editText.setRawInputType(Configuration.KEYBOARD_12KEY);
imm.showSoftInput(editText, 0);
if (pinCodeCallback != null) {
// pinCodeCallback.hideProgressBar(false);
}
}
/**
* Hides soft keyboard.
*
* @param editText EditText which has focus
*/
public void hideSoftKeyboard(EditText editText) {
if (editText == null)
return;
InputMethodManager imm = (InputMethodManager)
getContext().getSystemService(Service.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
if (pinCodeCallback != null) {
// pinCodeCallback.hideProgressBar(true);
}
}
public void setData(CharSequence data) {
if (!StringUtils.isNullOrEmpty(data)) {
isManuallyEntering = false;
mPinFirstDigitEditText.setText(String.valueOf(data.charAt(0)));
mPinHiddenEditText.setText(String.valueOf(data.charAt(0)));
mPinSecondDigitEditText.setText(String.valueOf(data.charAt(1)));
mPinHiddenEditText.append(String.valueOf(data.charAt(1)));
mPinThirdDigitEditText.setText(String.valueOf(data.charAt(2)));
mPinHiddenEditText.append(String.valueOf(data.charAt(2)));
mPinForthDigitEditText.setText(String.valueOf(data.charAt(3)));
mPinHiddenEditText.append(String.valueOf(data.charAt(3)));
mPinFifthDigitEditText.setText(String.valueOf(data.charAt(4)));
mPinHiddenEditText.append(String.valueOf(data.charAt(4)));
mPinSixthDigitEditText.setText(String.valueOf(data.charAt(5)));
mPinHiddenEditText.append(String.valueOf(data.charAt(5)));
hideSoftKeyboard(mPinSixthDigitEditText);
if (pinCodeCallback != null) {
pinCodeCallback.onPinCodeEntered();
}
} else {
isManuallyEntering = true;
mPinSixthDigitEditText.setText("");
mPinFifthDigitEditText.setText("");
mPinForthDigitEditText.setText("");
mPinThirdDigitEditText.setText("");
mPinSecondDigitEditText.setText("");
mPinFirstDigitEditText.setText("");
mPinHiddenEditText.setText("");
setFocus(mPinFirstDigitEditText);
showSoftKeyboard(mPinFirstDigitEditText);
}
}
public String getPinCodeText() {
return pinCodeText;
}
public void setCallBack(PinCodeCallBack pinCodeCallBack) {
this.pinCodeCallback = pinCodeCallBack;
}
public interface PinCodeCallBack {
void onPinCodeEntered();
/**
* true --> show && false--> hide
**/
void hideProgressBar(boolean show);
}
}
otp_drawable.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
android:thickness="0dp">
<corners android:radius="1dp" />
<solid android:color="@color/otpBackgroundColor" />
edittext style
<style name="otp_edittext_style">
<item name="android:gravity">center</item>
<item name="android:cursorVisible">false</item>
<item name="android:maxLength">1</item>
<item name="android:minEms">2</item>
<item name="android:inputType">numberDecimal</item>
<item name="android:focusable">true</item>
<item name="android:textSize">18sp</item>
<item name="android:fontFamily">sans-serif</item>
<item name="android:textColor">@color/post_description_color</item>
<item name="android:focusableInTouchMode">true</item>
</style>