如何允许在 edittext 中使用 mm/yyyy 格式输入 credit/debit 卡片详细信息
How to allow mm/yyyy format in edittext for entering credit/debit card details
我有一个 activity
添加了 credit/debit 卡片详细信息。目前我的代码允许以 MM/YY
格式添加日期和月份。但我需要 4 位数格式的年份 MM/YYYY
。添加'/'分隔符设置在第二位数字之后。因此,如果我增加我的总位数,我会在每第二个数字后得到一个分隔符。如何解决这个问题?
Carddetails.java:
public class CardDetailsActivity extends AppCompatActivity implements TextWatcher {
private static final int CARD_NUMBER_TOTAL_SYMBOLS = 19; // size of pattern 0000-0000-0000-0000
private static final int CARD_NUMBER_TOTAL_DIGITS = 16; // max numbers of digits in pattern: 0000 x walknew2
private static final int CARD_NUMBER_DIVIDER_MODULO = 5; // means divider position is every 5th symbol beginning with walknew4
private static final int CARD_NUMBER_DIVIDER_POSITION = CARD_NUMBER_DIVIDER_MODULO - 1; // means divider position is every 4th symbol beginning with 0
private static final char CARD_NUMBER_DIVIDER = '-';
@BindView(R.id.cardno)
EditText cardno;
@BindView(R.id.cardDateEditText)
EditText cardDateEditText;
@BindView(R.id.cardCVCEditText)
EditText cardCVCEditText;
SharedPreferences pref;
SharedPreferences.Editor editor;
private static final int CARD_DATE_TOTAL_SYMBOLS = 7; // size of pattern MM/YY
private static final int CARD_DATE_TOTAL_DIGITS = 6; // max numbers of digits in pattern: MM + YY
private static final int CARD_DATE_DIVIDER_MODULO = 3; // means divider position is every 3rd symbol beginning with walknew4
private static final int CARD_DATE_DIVIDER_POSITION = CARD_DATE_DIVIDER_MODULO - 1; // means divider position is every 2nd symbol beginning with 0
private static final char CARD_DATE_DIVIDER = '/';
private static final int CARD_CVC_TOTAL_SYMBOLS = 3;
String card_date, card_year, card_month, card_cvv, card_num, user_id, card_type = "debitcard";
@BindView(R.id.btn_add_card)
Button btn_add_card;
@BindView(R.id.btn_back)
Button btn_back;
Context context;
ProgressDialog progressDialog;
ApiService apiService;
String driverid, id, usertype, c_id, booking_id;
EditText card_numm, card_yearm, card_cvvm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_card_details);
ButterKnife.bind(this);
context = CardDetailsActivity.this;
Log.e("TAG", "Inside Card Details Activity:");
apiService = RetrofitSingleton.getApiService();
usertype = PrefConnect.readString(CardDetailsActivity.this, PrefConnect.USERTYPE, "");
pref = getApplicationContext().getSharedPreferences("MyPref", 0);
editor = pref.edit();
id = pref.getString("driver_id", "");
Log.e("driver_id", id);
try {
if (getIntent() != null) {
driverid = getIntent().getStringExtra("Driverid");
booking_id = getIntent().getStringExtra("bookingid");
}
} catch (Exception e) {
e.printStackTrace();
Log.e("paymentact", e.getMessage());
}
cardno.getText().toString().trim();
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
cardno.addTextChangedListener(this);
cardDateEditText.addTextChangedListener(this);
card_numm = (EditText) findViewById(R.id.cardno);
card_yearm = (EditText) findViewById(R.id.cardDateEditText);
card_cvvm = (EditText) findViewById(R.id.cardCVCEditText);
}
@OnClick({R.id.btn_add_card, R.id.btn_back})
public void OnClick(View view) {
switch (view.getId()) {
case R.id.btn_back:
finish();
break;
case R.id.btn_add_card:
View view1 = getCurrentFocus();
Log.e("TAG", "Inside Card Details Activity Button Add Card ");
Validation();
break;
}
}
private boolean isInputCorrect(Editable s, int size, int dividerPosition, char divider) {
boolean isCorrect = s.length() <= size;
for (int i = 0; i < s.length(); i++) {
if (i > 0 && (i + 1) % dividerPosition == 0) {
isCorrect &= divider == s.charAt(i);
} else {
isCorrect &= Character.isDigit(s.charAt(i));
}
}
return isCorrect;
}
private String concatString(char[] digits, int dividerPosition, char divider) {
final StringBuilder formatted = new StringBuilder();
for (int i = 0; i < digits.length; i++) {
if (digits[i] != 0) {
formatted.append(digits[i]);
if ((i > 0) && (i < (digits.length - 1)) && (((i + 1) % dividerPosition) == 0)) {
formatted.append(divider);
}
}
}
return formatted.toString();
}
private char[] getDigitArray(final Editable s, final int size) {
char[] digits = new char[size];
int index = 0;
for (int i = 0; i < s.length() && index < size; i++) {
char current = s.charAt(i);
if (Character.isDigit(current)) {
digits[index] = current;
index++;
}
}
return digits;
}
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable s) {
card_num = String.valueOf(s);
Log.i("TAG", "Card Date:" + s);
Log.i("TAG", "Card Date :" + cardDateEditText.getEditableText());
if (s == cardno.getEditableText()) {
if (!isInputCorrect(s, CARD_NUMBER_TOTAL_SYMBOLS, CARD_NUMBER_DIVIDER_MODULO, CARD_NUMBER_DIVIDER)) {
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_NUMBER_TOTAL_DIGITS), CARD_NUMBER_DIVIDER_POSITION, CARD_NUMBER_DIVIDER));
}
// DO STH
} else if (s == cardDateEditText.getEditableText()) {
if (!isInputCorrect(s, CARD_DATE_TOTAL_SYMBOLS, CARD_DATE_DIVIDER_MODULO, CARD_DATE_DIVIDER)) {
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_DATE_TOTAL_DIGITS), CARD_DATE_DIVIDER_POSITION, CARD_DATE_DIVIDER));
} else if (s == cardCVCEditText.getEditableText()) {
if (s.length() > CARD_CVC_TOTAL_SYMBOLS) {
s.delete(CARD_CVC_TOTAL_SYMBOLS, s.length());
}
}
}
}
}
据我了解,您的日期分隔符必须始终位于 2
位置
private static final int CARD_DATE_DIVIDER_POSITION = CARD_DATE_DIVIDER_MODULO - 1; // means divider position is every 2nd symbol beginning with 0
根据上面的声明,在附加日期分隔符之前,我应该这样测试(你可以这样改变你的 isInputCorrect
方法):
private boolean isInputCorrect(Editable s, int size, int dividerPosition, char divider) {
boolean isCorrect = s.length() <= size;
for (int i = 0; i < s.length(); i++) {
if (i > 0 && (i + 1) % dividerPosition == 0) {
if (divider=='/') {
if (i==2) {
isCorrect &= divider == s.charAt(i);
}
}
} else {
isCorrect &= Character.isDigit(s.charAt(i));
}
}
return isCorrect;
}
然后文字改完后可以稍微修改一下变成:
@Override
public void afterTextChanged(Editable s) {
card_num = String.valueOf(s);
String ss=cardDateEditText.getText().toString();
Log.i("TAG", "Card Date:" + s);
Log.i("TAG", "Card Date :" + ss);
if (s == cardno.getEditableText()) {
if (!isInputCorrect(s, CARD_NUMBER_TOTAL_SYMBOLS, CARD_NUMBER_DIVIDER_MODULO, CARD_NUMBER_DIVIDER)) {
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_NUMBER_TOTAL_DIGITS), CARD_NUMBER_DIVIDER_POSITION, CARD_NUMBER_DIVIDER));
}
} else if (s == cardDateEditText.getEditableText()) {
if (s.length()<=CARD_DATE_TOTAL_SYMBOLS)
{
if (!isInputCorrect(s, CARD_DATE_TOTAL_SYMBOLS, CARD_DATE_DIVIDER_MODULO, CARD_DATE_DIVIDER)) {
Log.e("TAG",s+"");
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_DATE_TOTAL_DIGITS), CARD_DATE_DIVIDER_POSITION, CARD_DATE_DIVIDER));
}
}else
{
s.delete(CARD_DATE_TOTAL_SYMBOLS,s.length());
}
} else if (s == cardCVCEditText.getEditableText()) {
if (s.length() > CARD_CVC_TOTAL_SYMBOLS) {
s.delete(CARD_CVC_TOTAL_SYMBOLS, s.length());
}
}
}
因此您还测试了可编辑文本的长度。
日期分隔符只能包含一次,并且紧跟在由前两个字符表示的月份之后。这意味着最后一位数字必须在第 2 个位置索引 1,在那一刻 i==1
。所以不会附加其他分隔符。我应该测试分隔符集是否用于日期,以了解我正在处理日期,然后测试索引是否不大于或等于 2.
我就是这样处理的。我希望这将有所帮助。
我有一个 activity
添加了 credit/debit 卡片详细信息。目前我的代码允许以 MM/YY
格式添加日期和月份。但我需要 4 位数格式的年份 MM/YYYY
。添加'/'分隔符设置在第二位数字之后。因此,如果我增加我的总位数,我会在每第二个数字后得到一个分隔符。如何解决这个问题?
Carddetails.java:
public class CardDetailsActivity extends AppCompatActivity implements TextWatcher {
private static final int CARD_NUMBER_TOTAL_SYMBOLS = 19; // size of pattern 0000-0000-0000-0000
private static final int CARD_NUMBER_TOTAL_DIGITS = 16; // max numbers of digits in pattern: 0000 x walknew2
private static final int CARD_NUMBER_DIVIDER_MODULO = 5; // means divider position is every 5th symbol beginning with walknew4
private static final int CARD_NUMBER_DIVIDER_POSITION = CARD_NUMBER_DIVIDER_MODULO - 1; // means divider position is every 4th symbol beginning with 0
private static final char CARD_NUMBER_DIVIDER = '-';
@BindView(R.id.cardno)
EditText cardno;
@BindView(R.id.cardDateEditText)
EditText cardDateEditText;
@BindView(R.id.cardCVCEditText)
EditText cardCVCEditText;
SharedPreferences pref;
SharedPreferences.Editor editor;
private static final int CARD_DATE_TOTAL_SYMBOLS = 7; // size of pattern MM/YY
private static final int CARD_DATE_TOTAL_DIGITS = 6; // max numbers of digits in pattern: MM + YY
private static final int CARD_DATE_DIVIDER_MODULO = 3; // means divider position is every 3rd symbol beginning with walknew4
private static final int CARD_DATE_DIVIDER_POSITION = CARD_DATE_DIVIDER_MODULO - 1; // means divider position is every 2nd symbol beginning with 0
private static final char CARD_DATE_DIVIDER = '/';
private static final int CARD_CVC_TOTAL_SYMBOLS = 3;
String card_date, card_year, card_month, card_cvv, card_num, user_id, card_type = "debitcard";
@BindView(R.id.btn_add_card)
Button btn_add_card;
@BindView(R.id.btn_back)
Button btn_back;
Context context;
ProgressDialog progressDialog;
ApiService apiService;
String driverid, id, usertype, c_id, booking_id;
EditText card_numm, card_yearm, card_cvvm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_card_details);
ButterKnife.bind(this);
context = CardDetailsActivity.this;
Log.e("TAG", "Inside Card Details Activity:");
apiService = RetrofitSingleton.getApiService();
usertype = PrefConnect.readString(CardDetailsActivity.this, PrefConnect.USERTYPE, "");
pref = getApplicationContext().getSharedPreferences("MyPref", 0);
editor = pref.edit();
id = pref.getString("driver_id", "");
Log.e("driver_id", id);
try {
if (getIntent() != null) {
driverid = getIntent().getStringExtra("Driverid");
booking_id = getIntent().getStringExtra("bookingid");
}
} catch (Exception e) {
e.printStackTrace();
Log.e("paymentact", e.getMessage());
}
cardno.getText().toString().trim();
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
cardno.addTextChangedListener(this);
cardDateEditText.addTextChangedListener(this);
card_numm = (EditText) findViewById(R.id.cardno);
card_yearm = (EditText) findViewById(R.id.cardDateEditText);
card_cvvm = (EditText) findViewById(R.id.cardCVCEditText);
}
@OnClick({R.id.btn_add_card, R.id.btn_back})
public void OnClick(View view) {
switch (view.getId()) {
case R.id.btn_back:
finish();
break;
case R.id.btn_add_card:
View view1 = getCurrentFocus();
Log.e("TAG", "Inside Card Details Activity Button Add Card ");
Validation();
break;
}
}
private boolean isInputCorrect(Editable s, int size, int dividerPosition, char divider) {
boolean isCorrect = s.length() <= size;
for (int i = 0; i < s.length(); i++) {
if (i > 0 && (i + 1) % dividerPosition == 0) {
isCorrect &= divider == s.charAt(i);
} else {
isCorrect &= Character.isDigit(s.charAt(i));
}
}
return isCorrect;
}
private String concatString(char[] digits, int dividerPosition, char divider) {
final StringBuilder formatted = new StringBuilder();
for (int i = 0; i < digits.length; i++) {
if (digits[i] != 0) {
formatted.append(digits[i]);
if ((i > 0) && (i < (digits.length - 1)) && (((i + 1) % dividerPosition) == 0)) {
formatted.append(divider);
}
}
}
return formatted.toString();
}
private char[] getDigitArray(final Editable s, final int size) {
char[] digits = new char[size];
int index = 0;
for (int i = 0; i < s.length() && index < size; i++) {
char current = s.charAt(i);
if (Character.isDigit(current)) {
digits[index] = current;
index++;
}
}
return digits;
}
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable s) {
card_num = String.valueOf(s);
Log.i("TAG", "Card Date:" + s);
Log.i("TAG", "Card Date :" + cardDateEditText.getEditableText());
if (s == cardno.getEditableText()) {
if (!isInputCorrect(s, CARD_NUMBER_TOTAL_SYMBOLS, CARD_NUMBER_DIVIDER_MODULO, CARD_NUMBER_DIVIDER)) {
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_NUMBER_TOTAL_DIGITS), CARD_NUMBER_DIVIDER_POSITION, CARD_NUMBER_DIVIDER));
}
// DO STH
} else if (s == cardDateEditText.getEditableText()) {
if (!isInputCorrect(s, CARD_DATE_TOTAL_SYMBOLS, CARD_DATE_DIVIDER_MODULO, CARD_DATE_DIVIDER)) {
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_DATE_TOTAL_DIGITS), CARD_DATE_DIVIDER_POSITION, CARD_DATE_DIVIDER));
} else if (s == cardCVCEditText.getEditableText()) {
if (s.length() > CARD_CVC_TOTAL_SYMBOLS) {
s.delete(CARD_CVC_TOTAL_SYMBOLS, s.length());
}
}
}
}
}
据我了解,您的日期分隔符必须始终位于 2
位置private static final int CARD_DATE_DIVIDER_POSITION = CARD_DATE_DIVIDER_MODULO - 1; // means divider position is every 2nd symbol beginning with 0
根据上面的声明,在附加日期分隔符之前,我应该这样测试(你可以这样改变你的 isInputCorrect
方法):
private boolean isInputCorrect(Editable s, int size, int dividerPosition, char divider) {
boolean isCorrect = s.length() <= size;
for (int i = 0; i < s.length(); i++) {
if (i > 0 && (i + 1) % dividerPosition == 0) {
if (divider=='/') {
if (i==2) {
isCorrect &= divider == s.charAt(i);
}
}
} else {
isCorrect &= Character.isDigit(s.charAt(i));
}
}
return isCorrect;
}
然后文字改完后可以稍微修改一下变成:
@Override
public void afterTextChanged(Editable s) {
card_num = String.valueOf(s);
String ss=cardDateEditText.getText().toString();
Log.i("TAG", "Card Date:" + s);
Log.i("TAG", "Card Date :" + ss);
if (s == cardno.getEditableText()) {
if (!isInputCorrect(s, CARD_NUMBER_TOTAL_SYMBOLS, CARD_NUMBER_DIVIDER_MODULO, CARD_NUMBER_DIVIDER)) {
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_NUMBER_TOTAL_DIGITS), CARD_NUMBER_DIVIDER_POSITION, CARD_NUMBER_DIVIDER));
}
} else if (s == cardDateEditText.getEditableText()) {
if (s.length()<=CARD_DATE_TOTAL_SYMBOLS)
{
if (!isInputCorrect(s, CARD_DATE_TOTAL_SYMBOLS, CARD_DATE_DIVIDER_MODULO, CARD_DATE_DIVIDER)) {
Log.e("TAG",s+"");
s.replace(0, s.length(), concatString(getDigitArray(s, CARD_DATE_TOTAL_DIGITS), CARD_DATE_DIVIDER_POSITION, CARD_DATE_DIVIDER));
}
}else
{
s.delete(CARD_DATE_TOTAL_SYMBOLS,s.length());
}
} else if (s == cardCVCEditText.getEditableText()) {
if (s.length() > CARD_CVC_TOTAL_SYMBOLS) {
s.delete(CARD_CVC_TOTAL_SYMBOLS, s.length());
}
}
}
因此您还测试了可编辑文本的长度。
日期分隔符只能包含一次,并且紧跟在由前两个字符表示的月份之后。这意味着最后一位数字必须在第 2 个位置索引 1,在那一刻 i==1
。所以不会附加其他分隔符。我应该测试分隔符集是否用于日期,以了解我正在处理日期,然后测试索引是否不大于或等于 2.
我就是这样处理的。我希望这将有所帮助。