package
import android.text.Editable
import android.text.InputType
import android.text.Selection
import android.text.TextWatcher
import android.text.method.DigitsKeyListener
import android.view.View
import android.widget.EditText
import android.widget.LinearLayout
open class NumSpaceTextWatcher : TextWatcher {
private val mDesTxt: EditText
private var mOffset: Int
private var mAddChar: String? = null
private val mBuffer = StringBuffer()
private var mBeforeTextLength = 0
private var mOnTextLength = 0
private var mBeforeNumTxtLength = 0
private var mNumTxtLength = 0
private var mLocation = 0
private var mBeforeLocation = 0
private var mBeforeSpaceNumber = 0
private var isOverrideSpace = false
private var mOverrideSpaceNum = 0
private var isPaste = false
private var mPasteNum = 0
private var isChanged = false
private var disposeView: LinearLayout? = null
private var maxLength: Int = MAX_LENGTH
@JvmOverloads
constructor(target: EditText, offset: Int = DEFAULT_OFFSET, limitLength: Int = MAX_LENGTH,char:String? = ' '.toString()) {
if (target.inputType == InputType.TYPE_CLASS_NUMBER) {
target.inputType = InputType.TYPE_CLASS_TEXT
target.keyListener = MyDigitsKeyListener()
} else require(target.inputType == InputType.TYPE_CLASS_TEXT) {
"EditText only support TEXT and NUMBER InputTyp!"
}
mDesTxt = target
mOffset = offset
mAddChar = char
maxLength = limitLength
}
constructor(target: EditText, offset: Int, disposeView: LinearLayout?) {
if (target.inputType == InputType.TYPE_CLASS_NUMBER) {
target.inputType = InputType.TYPE_CLASS_TEXT
target.keyListener = MyDigitsKeyListener()
} else require(target.inputType == InputType.TYPE_CLASS_TEXT) {
"EditText only support TEXT and NUMBER InputTyp!"
}
mDesTxt = target
mOffset = offset
this.disposeView = disposeView
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
mBeforeTextLength = s.length
mBeforeNumTxtLength = s.toString().replace(" ".toRegex(), "").length
mBeforeLocation = mDesTxt.selectionEnd
if (mBuffer.isNotEmpty()) {
mBuffer.delete(0, mBuffer.length)
}
mBeforeSpaceNumber = 0
for (element in s) {
if (element.toString().equals(mAddChar)) {
mBeforeSpaceNumber++
}
}
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
mOnTextLength = s.length
mNumTxtLength = s.toString().replace(" ".toRegex(), "").length
if (mOffset >= (mOffset-1) && count >= mOffset) {
isPaste = true
mPasteNum = count
} else {
isPaste = false
mPasteNum = 0
}
if (isChanged) {
isChanged = false
return
}
if (mOnTextLength <= mOffset - 1) {
isChanged = false
return
}
if (mBeforeTextLength == mOnTextLength && mBeforeNumTxtLength == mNumTxtLength) {
isChanged = false
return
} else {
isChanged = true
}
isOverrideSpace = if (before == 1 && count == 0) {
false
} else {
mBeforeTextLength - mBeforeSpaceNumber - before + count != mNumTxtLength
}
mOverrideSpaceNum = if (isOverrideSpace) {
mNumTxtLength - (mBeforeTextLength - mBeforeSpaceNumber - before + count)
} else {
0
}
}
override fun afterTextChanged(s: Editable) {
if (isChanged) {
mLocation = mDesTxt.selectionEnd
var text = s.toString().replace(mAddChar?:"", "")
if (text.length > maxLength) {
text = text.substring(0, maxLength)
}
mBuffer.append(text)
var index = 0
var mAfterSpaceNumber = 0
while (index < mBuffer.length) {
if (index == mOffset * (1 + mAfterSpaceNumber) + mAfterSpaceNumber) {
mBuffer.insert(index, mAddChar)
mAfterSpaceNumber++
}
index++
}
if (isPaste) {
mLocation += mPasteNum / mOffset
isPaste = false
} else if (isOverrideSpace) {
mLocation += mOverrideSpaceNum
} else if (mLocation % (mOffset + 1) == 0) {
if (mBeforeLocation <= mLocation) {
mLocation++
} else {
mLocation--
}
}
val str = mBuffer.toString()
if (mLocation > str.length) {
mLocation = str.length
} else if (mLocation < 0) {
mLocation = 0
}
s.replace(0, s.length, str)
val editable = mDesTxt.text
Selection.setSelection(editable, mLocation)
}
if (s.length <= 0 && disposeView != null) {
disposeView!!.visibility = View.GONE
}
}
private inner class MyDigitsKeyListener : DigitsKeyListener() {
private val mAccepted = charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ')
override fun getAcceptedChars(): CharArray {
return mAccepted
}
}
companion object {
private const val DEFAULT_OFFSET = 4
private const val MAX_LENGTH = 9
}
}