Most of them listen for text changes and add spaces and I don't like this approche. Mostly because user can see those space while selecting text.
So I will add mine implementation :)
Here is screenshot from Gennymotion:
And sources as well (link on GitHub):
public class CreditCardTransformation implements TransformationMethod { private static final Divider sDivider = new Divider(); @Override public CharSequence getTransformation(final CharSequence source, View view) { return new SpannedWrapper(source) { @Override @SuppressWarnings("unchecked") publicT[] getSpans(int start, int end, Class type) { T[] array = super.getSpans(start, end, type); if (!type.isAssignableFrom(Divider.class)) { return array; } Object[] result = (Object[]) Array.newInstance(type, array.length + 1); result[0] = sDivider; System.arraycopy(array, 0, result, 1, array.length); return (T[]) result; } @Override public int getSpanStart(Object tag) { if (tag instanceof Divider) { return 0; } return super.getSpanStart(tag); } @Override public int getSpanEnd(Object tag) { if (tag instanceof Divider) { return length(); } return super.getSpanEnd(tag); } }; } @Override public void onFocusChanged(View view, CharSequence sourceText, boolean focused, int direction, Rect previouslyFocusedRect) { } static class SpannedWrapper implements Spanned { private Spanned mSpanned; private CharSequence mSource; SpannedWrapper(CharSequence source) { mSource = source; if (mSource instanceof Spanned) { mSpanned = (Spanned) source; } } @Override @SuppressWarnings("unchecked") public T[] getSpans(int start, int end, Class type) { if (mSpanned != null) { return mSpanned.getSpans(start, end, type); } return (T[]) Array.newInstance(type, 0); } @Override public int getSpanStart(Object tag) { if (mSpanned != null) { return mSpanned.getSpanStart(tag); } return 0; } @Override public int getSpanEnd(Object tag) { if (mSpanned != null) { return mSpanned.getSpanEnd(tag); } return 0; } @Override public int getSpanFlags(Object tag) { if (mSpanned != null) { return mSpanned.getSpanFlags(tag); } return 0; } @Override public int nextSpanTransition(int start, int limit, Class type) { if (mSpanned != null) { return mSpanned.nextSpanTransition(start, limit, type); } return 0; } @Override public int length() { return mSource.length(); } @Override public char charAt(int index) { return mSource.charAt(index); } @Override public CharSequence subSequence(int start, int end) { return mSource.subSequence(start, end); } @Override public String toString() { return mSource.toString(); } } static class Divider extends ReplacementSpan { @Override public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) { int groups = Math.min(3, (end - start) / 4); return (int) (paint.measureText(text, start, end) + paint.getTextSize() * groups); } @Override public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) { int offset = 0; int groupStart = start; while (groupStart < end) { int groupEnd = Math.min(groupStart + 4, end); canvas.drawText(text, groupStart, groupEnd, x + offset, y, paint); offset += paint.measureText(text, groupStart, groupEnd) + paint.getTextSize(); groupStart = groupEnd; } } } }
No comments:
Post a Comment