Android TextInputLayout with credit card mask
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TextInputLayout
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
app:counterMaxLength="16"
app:counterEnabled="true">
<android.support.design.widget.TextInputEditText
android:id="@+id/cc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Credit Card Number"
android:digits="1234567890"
android:inputType="number|textNoSuggestions"
/>
</android.support.design.widget.TextInputLayout>
</RelativeLayout>
In this example I will explain how you can build a TextInputLayout that shows credit card numeber.
The goal is to add a margin between every four digits without adding a space (" ") while you are inserting text.
You need to put a TextWatcher on a EditText.
The TextWatcher needs to add a margin every four digits.
Example:
private EditText etCreditCard;
private TextWatcher tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
etCreditCard = (EditText) findViewById(R.id.cc);
tv = 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) {
int textLength = etCreditCard.length();
if(etCreditCard.length() > 4){
etCreditCard.removeTextChangedListener(tv);
if(textLength > 15){
s.replace(16, textLength, "");
}else {
for(int i = 1; i <= (textLength / 4); i++){
MarginSpan marginSPan = new MarginSpan(20);
s.setSpan(marginSPan, (i * 4)-1, (i * 4), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
etCreditCard.addTextChangedListener(tv);
}
}
};
etCreditCard.addTextChangedListener(tv);
}
package com.liberorignanese.android.gist;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.style.ReplacementSpan;
/**
* Created by Libero Rignanese.
*/
public class MarginSpan extends ReplacementSpan {
private int mPadding;
public MarginSpan(int padding) {
mPadding = padding;
}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
float[] widths = new float[end - start];
paint.getTextWidths(text, start, end, widths);
int sum = mPadding;
for (int i = 0; i < widths.length; i++) {
sum += widths[i];
}
return sum;
}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
canvas.drawText(text, start, end, x, y, paint);
}
}