如何在用户输入时以mm / yy格式化信用卡到期日期

时间:2017-03-28 08:18:48

标签: android

我想实现这样的算法:

用户开始输入" MM" ,它应该给" /"在用户输入" MM"的两位数后然后,它应该只输入" yy"的最后两位数字。我怎样才能实现这种功能?

11 个答案:

答案 0 :(得分:11)

android:maxLength="5"

并设置为editText的电话,以便显示“/”

android:inputType="phone"
textWatcher上的

执行此操作....我将稍后验证正确的mm / yy月份,以避免用户输入数据,如55/66 max应该是12/31,但应该在少于或30的情况下验证数月天...

 @Override
    public void afterTextChanged(Editable editable) {


        if (editable.length() > 0 && (editable.length() % 3) == 0) {
            final char c = editable.charAt(editable.length() - 1);
            if ('/' == c) {
                editable.delete(editable.length() - 1, editable.length());
            }
        }
        if (editable.length() > 0 && (editable.length() % 3) == 0) {
            char c = editable.charAt(editable.length() - 1);
            if (Character.isDigit(c) && TextUtils.split(editable.toString(), String.valueOf("/")).length <= 2) {
                editable.insert(editable.length() - 1, String.valueOf("/"));
            }
        }
    }

答案 1 :(得分:4)

我只是通过自动检查,自动完成,自动移动到CVV edittext来实现像优步信用卡日期格式的方法。

 <EditText
            android:id="@+id/credit_card_expire_et"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginRight="@dimen/activity_horizontal_margin"
            android:layout_weight="1"
            android:hint="MM/YY"
            android:inputType="number"
            android:maxLength="5"
            android:maxLines="1" />

    <EditText
        android:id="@+id/credit_card_cvv_et"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/activity_horizontal_margin"
        android:layout_weight="1"
        android:hint="CVV"
        android:inputType="number"
        android:maxLength="3"
        android:maxLines="1" />

@BindView(R.id.credit_card_expire_et)
EditText creditExpireEt;
@BindView(R.id.credit_card_cvv_et)
EditText creditCVVEt;


@OnTextChanged(value = R.id.credit_card_expire_et, callback = BEFORE_TEXT_CHANGED)
    void beforeExpireEtChanged() {
        previousLength = creditExpireEt.getText().toString().length();
    }

    @OnTextChanged(R.id.credit_card_expire_et)
    void autoFixAndMoveToNext() {
        int length = creditExpireEt.getText().toString().trim().length();

        if (previousLength <= length && length < 3) {
            int month = Integer.parseInt(creditExpireEt.getText().toString());
            if (length == 1 && month >= 2) {
                String autoFixStr = "0" + month + "/";
                creditExpireEt.setText(autoFixStr);
                creditExpireEt.setSelection(3);
            } else if (length == 2 && month <= 12) {
                String autoFixStr = creditExpireEt.getText().toString() + "/";
                creditExpireEt.setText(autoFixStr);
                creditExpireEt.setSelection(3);
            } else if (length ==2 && month > 12) {
                creditExpireEt.setText("1");
                creditExpireEt.setSelection(1);
            }
        } else if (length == 5) {
            creditCVVEt.requestFocus(); // auto move to next edittext
        }
    }

答案 2 :(得分:2)

首先将EditText的最大字符数设置为5,如下所示:

android:maxLength="5"

并设置为数字editText

android:inputType="number"

然后将onEditTextChangedListener添加到EditText以检测字符数是否更改为2并且没有从3更改为2,如果删除“/”之前的数字则删除“/”:

edit_text.addTextChangedListener(object : TextWatcher {
    override fun afterTextChanged(p0: Editable?) {}

    override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}

    override fun onTextChanged(p0: CharSequence?, start: Int, removed: Int, added: Int) {
        if (start == 1 && start+added == 2 && p0?.contains('/') == false) {
            edit_text.setText(p0.toString() + "/")
        } else if (start == 3 && start-removed == 2 && p0?.contains('/') == true) {
            edit_text.setText(p0.toString().replace("/", ""))
        }
    }
})

答案 3 :(得分:1)

private static final String EXP_DATE_REGAX = "(0[1-9]|1[0-2])[0-9]{2}";

if (!edt_expiry_date.getText().toString().isEmpty()) {

                    Pattern pattern = Pattern.compile(EXP_DATE_REGAX);
                    Matcher matcher = pattern.matcher(edt_expiry_date.getText().toString());

                        if(!matcher.find()){
                            edt_expiry_date.setError("Invalid Expiry Date");
                        }else{
                            Calendar c = Calendar.getInstance();

                            int year = c.get(Calendar.YEAR) % 100;
                            int month = c.get(Calendar.MONTH)+1;

                            if(Integer.parseInt((edt_expiry_date.getText().toString().substring(2)))>=year){
                               if(Integer.parseInt((edt_expiry_date.getText().toString().substring(2)))==year){
                                   if(Integer.parseInt((edt_expiry_date.getText().toString().substring(0,2)))>=month){
                                       str_expiry_date = edt_expiry_date.getText().toString();
                                       dialog.dismiss();
                                   }else{
                                       edt_expiry_date.setError("Invalid Expiry Date");
                                   }
                               }else{
                                   str_expiry_date = edt_expiry_date.getText().toString();
                                   dialog.dismiss();
                               }


                            }else{
                                edt_expiry_date.setError("Invalid Expiry Date");
                            }

                           // dialog.dismiss();

                    }

                } else {
                    edt_expiry_date.setError("Enter Expiry Date");
                }

答案 4 :(得分:0)

基于文本的日期输入所需的问题和字符串操作在这里看起来并不值得。如果用户返回到字符串的开头并开始键入会发生什么?如果用户开始输入错误的格式会发生什么?您必须考虑大量案例,而没有非常好的方法来控制用户可以输入的内容。在这些情况下,我只使用DatePicker like the one in this solution

如果你设置了心脏,你可以保留EditText,只需设置onClickListener以在选中时调出DatePicker。我建议在它上面设置这两个字段:

android:cursorVisible="false"
android:focusable="false"

这样EditText看起来不会被输入。我对其他答案的唯一建议或补充是&#34; Clear&#34;按钮,以便可以根据需要擦除EditText值。为此,只需通过中性按钮添加它,如下所示:

builder.setView(dialog)
        // Add action buttons
        .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int id) {
                listener.onDateSet(null, yearPicker.getValue(), monthPicker.getValue(), 0);
            }
        })
        .setNeutralButton(R.string.clear, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                //check for a month value of -1 in onDateSet to clear current field
                listener.onDateSet(null, -1, -1, 0);
            }
        })
        .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                MonthYearPickerFragment.this.getDialog().cancel();
            }
        });

然后检查并查看是否应该清除该字段,只需执行以下操作:

@Override
public void onDateSet(DatePicker datePicker, int i, int i1, int i2) {
    if (i > -1){
        et.setText(i1 + "/" + i);
    } else {
        et.setText("");
    }
}

答案 5 :(得分:0)

在Kotlin中,格式为

  

“ MM / YY”

您可以使用此

et_expire_date.addTextChangedListener(object : TextWatcher {

        override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
            var working = s.toString()
            var isValid = true
            if (working.length == 2 && before == 0) {
                if (Integer.parseInt(working) < 1 || Integer.parseInt(working) > 12) {
                    isValid = false
                } else {
                    working += "/"
                    et_expire_date.setText(working)
                    et_expire_date.setSelection(working.length)
                }
            } else if (working.length == 5 && before == 0) {
                val enteredYear = working.substring(3)
                val currentYear = Calendar.getInstance().get(Calendar.YEAR) % 100//getting last 2 digits of current year i.e. 2018 % 100 = 18
                if (Integer.parseInt(enteredYear) < currentYear) {
                    isValid = false
                }
            } else if (working.length != 5) {
                isValid = false
            }

            if (!isValid) {
                et_expire_date.error = getString(R.string.enter_valid_date_mm_yy)
            } else {
                et_expire_date.error = null
            }

        }

        override fun afterTextChanged(s: Editable) {}

        override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
    })

其中et_expire_date是用于输入日期的edittext

答案 6 :(得分:0)

@Goodlife的科特林版

override fun afterTextChanged(s: Editable?) {
                if (s!!.isNotEmpty() && (s.length % 3) == 0) {
                    val c = s[s.length-1]
                    if (c == '/') {
                        s.delete(s.length-1, s.length)
                    }
                }
                if (s.isNotEmpty() && (s.length % 3) == 0) {
                    val c = s[s.length-1]
                    if (Character.isDigit(c) && TextUtils.split(s.toString(), "/").size <= 2) {
                        s.insert(s.length-1, "/")
                    }
                }
            }

答案 7 :(得分:0)

简单答案,将长度设置为5(毫米/年)或7(毫米/年)

    YourEditText.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) {

                int len=s.toString().length();

                if (before == 0 && len == 2)
                    YourEditText.append("/");
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

答案 8 :(得分:0)

EditText et_expiry_date= (EditText) findViewById(R.id.et_expiry_date);

et_expiry_date.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) {
    String current = s.toString();
    if (current.length() == 2 && start == 1) {
            et_expiry_date.setText(current + "/");
            et_expiry_date.setSelection(current.length() + 1);
    } 
    else if (current.length() == 2 && before == 1) {
        current = current.substring(0, 1);
        et_expiry_date.setText(current);
        et_expiry_date.setSelection(current.length());
    }
}

@Override
public void afterTextChanged(Editable s) {}
});

答案 9 :(得分:0)

将这些添加到youredittext.addTextChangedListener

         @Override
         public void onTextChanged(CharSequence s, int start, int before, int count) {

            if (s.length() == 2) {
                if(start==2 && before==1 && !s.toString().contains("/")){
                    youredittext.setText(""+s.toString().charAt(0));
                    youredittext.setSelection(1);
                }
                else {
                    youredittext.setText(s + "/");
                    youredittext.setSelection(3);
                }
            }
          }

答案 10 :(得分:-1)

使用TextWatcher,例如:

EditText editText = (EditText) findViewById(R.id.yourEditTextId);
yourEditText.addTextChangedListener(new TextWatcher() {

public void afterTextChanged(Editable s) {
  // Do what you want here
  String myStr = s.toString();
  // Check if MM and do what you want
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

public void onTextChanged(CharSequence s, int start, int before, int count) {}
});