Skip to content

Instantly share code, notes, and snippets.

@liberorignanese
Last active January 12, 2024 18:05
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save liberorignanese/60a5ea9ddbdd71bdea8709dc6cadea41 to your computer and use it in GitHub Desktop.
Save liberorignanese/60a5ea9ddbdd71bdea8709dc6cadea41 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 (textLength > 4) {
                    etCreditCard.removeTextChangedListener(tv);
                    if (textLength > 16) {
                        s.replace(16, textLength, "");
                        textLength = s.length();
                    }
                    for (int i = 1; i <= textLength; i++){
                        if( ((i % 4) == 0) && i > 1 && i < textLength ){
                            MarginSpan marginSPan = new MarginSpan(20);
                            s.setSpan(marginSPan, i - 1, i, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        }else{
                            MarginSpan marginSPan = new MarginSpan(0);
                            s.setSpan(marginSPan, i - 1, i, 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);
}
}
@danielesegato
Copy link

Also if you click in the middle of the number and start to write there margins gets crazy

@liberorignanese
Copy link
Author

@danielesegato commented 2 hours ago
Also if you click in the middle of the number and start to write there margins gets crazy

Fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment