Skip to content

Instantly share code, notes, and snippets.

@yesidlazaro
Forked from liberorignanese/MarginSpan.java
Created October 5, 2016 01:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yesidlazaro/2c89de4f7d5fbf9651a580a48d41fa87 to your computer and use it in GitHub Desktop.
Save yesidlazaro/2c89de4f7d5fbf9651a580a48d41fa87 to your computer and use it in GitHub Desktop.
Android TextInputLayout with credit card mask

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.

Screen

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);

    }
<?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>
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);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment