Last active
August 25, 2021 06:52
-
-
Save masoudkarimi/1dea9b659ea5eb155c3aadb5c993d4c9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.your.package | |
import android.graphics.Canvas | |
import android.graphics.Paint | |
import android.text.Editable | |
import android.text.Spannable | |
import android.text.TextWatcher | |
import android.text.style.ReplacementSpan | |
import android.widget.TextView | |
import java.text.DecimalFormatSymbols | |
import java.util.* | |
class PriceFormatTextWatcher : TextWatcher { | |
private var paddingPx: Int = 0 | |
private var internalStopFormatFlag: Boolean = false | |
private val decimalFormatSymbols = DecimalFormatSymbols(Locale("fa")) // or en | |
private val separatorCharacter = decimalFormatSymbols.groupingSeparator.toString() | |
/** | |
* Change the padding, do not take effect until next text change | |
* | |
* @param paddingPx padding in pixels unit | |
*/ | |
fun setPaddingPx(paddingPx: Int) { | |
this.paddingPx = paddingPx | |
} | |
/** | |
* Change the padding, do not take effect until next text change | |
* | |
* @param textView the widget you want to format | |
* @param em padding in em unit (character size unit) | |
*/ | |
fun setPaddingEm(textView: TextView, em: Float) { | |
val emSize = textView.paint.measureText(separatorCharacter) | |
setPaddingPx((em * emSize).toInt()) | |
} | |
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} | |
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {} | |
override fun afterTextChanged(s: Editable) { | |
if (internalStopFormatFlag) { | |
return | |
} | |
internalStopFormatFlag = true | |
formatPhoneNumber(s, paddingPx, separatorCharacter) | |
internalStopFormatFlag = false | |
} | |
class SeparatorSpan( | |
private val mPadding: Int, | |
private val separator: String, | |
) : | |
ReplacementSpan() { | |
override fun getSize( | |
paint: Paint, | |
text: CharSequence, | |
start: Int, | |
end: Int, | |
fm: Paint.FontMetricsInt? | |
): Int { | |
val widths = FloatArray(end - start) | |
paint.getTextWidths(text, start, end, widths) | |
var sum = mPadding | |
for (i in widths.indices) { | |
sum += widths[i].toInt() | |
} | |
return sum | |
} | |
override fun draw( | |
canvas: Canvas, | |
text: CharSequence, | |
start: Int, | |
end: Int, | |
x: Float, | |
top: Int, | |
y: Int, | |
bottom: Int, | |
paint: Paint | |
) { | |
canvas.drawText(text, start, end, x, y.toFloat(), paint) | |
if (mPadding > 0) { | |
val drawingTextWidth = paint.measureText(text, start, end) | |
canvas.drawText( | |
separator, | |
0, | |
separator.length, | |
x + drawingTextWidth , | |
y.toFloat(), | |
paint | |
) | |
} | |
} | |
} | |
companion object { | |
@JvmOverloads | |
fun formatPhoneNumber( | |
ccNumber: Editable, | |
paddingPx: Int, | |
separator: String, | |
) { | |
val textLength = ccNumber.length | |
// first remove any previous span | |
val spans = ccNumber.getSpans(0, ccNumber.length, SeparatorSpan::class.java) | |
for (i in spans.indices) { | |
ccNumber.removeSpan(spans[i]) | |
} | |
for (i in 0 until textLength) { | |
val padding = if (textLength >= 4 && textLength.minus(i) | |
.rem(3) == 1 && i < textLength - 1 | |
) paddingPx else 0 | |
val span = | |
SeparatorSpan(padding, separator) | |
ccNumber.setSpan(span, i, i + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
editText.addTextChangedListener(PriceFormatTextWatcher().apply { | |
setPaddingEm(editText, 1f) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment