Skip to content

Commit

Permalink
update number formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
ibrahimsn98 committed Sep 30, 2020
1 parent 58729f9 commit 9a1f9b2
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 30 deletions.
2 changes: 0 additions & 2 deletions app/src/main/java/me/ibrahimsn/phonenumberkit/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,5 @@ class MainActivity : AppCompatActivity() {

// Provides country name, iso2 for given country code
val country = phoneNumberKit.getCountry(90)

editText.setText("+905066840880")
}
}
8 changes: 8 additions & 0 deletions lib/src/main/java/me/ibrahimsn/lib/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,12 @@ package me.ibrahimsn.lib
object Constants {

const val VIEW_TAG = "#"

const val KEY_DIGIT = '0'
const val KEY_SPACE = '1'
const val KEY_DASH = '-'

const val CHAR_SPACE = ' '
const val CHAR_DASH = '-'
const val CHAR_PLUS = '+'
}
79 changes: 57 additions & 22 deletions lib/src/main/java/me/ibrahimsn/lib/PhoneNumberKit.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ import android.text.InputType
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import com.google.android.material.textfield.TextInputLayout
import me.ibrahimsn.lib.Constants.CHAR_DASH
import me.ibrahimsn.lib.Constants.CHAR_PLUS
import me.ibrahimsn.lib.Constants.CHAR_SPACE
import me.ibrahimsn.lib.Constants.KEY_DASH
import me.ibrahimsn.lib.Constants.KEY_DIGIT
import me.ibrahimsn.lib.Constants.KEY_SPACE
import me.ibrahimsn.lib.bottomsheet.CountryPickerBottomSheet
import me.ibrahimsn.lib.core.Core
import me.ibrahimsn.lib.util.PhoneNumberTextWatcher
import me.ibrahimsn.lib.util.PhoneNumberValidator
import me.ibrahimsn.lib.util.prependPlus
import me.ibrahimsn.lib.util.startsWithPlus

class PhoneNumberKit(private val context: Context) {

Expand All @@ -22,39 +26,60 @@ class PhoneNumberKit(private val context: Context) {

private var country: Country? = null

private var rawInput: String?
get() = input?.editText?.text?.toString()
private var format: String = ""

private var hasManualCountry = false

private var rawInput: CharSequence?
get() = input?.editText?.text
set(value) {
input?.tag = Constants.VIEW_TAG
input?.editText?.setText(value)
value?.let {
input?.editText?.setSelection(value.length)
}
input?.editText?.setText("")
input?.editText?.append(value)
input?.tag = null
}

val isValid: Boolean
get() = PhoneNumberValidator.validate(rawInput)

private val textWatcher = object: PhoneNumberTextWatcher() {
override fun onTextChanged(text: CharSequence?, p1: Int, p2: Int, p3: Int) {
if (input?.tag != Constants.VIEW_TAG) {
if (!text.isNullOrEmpty() && !text.startsWithPlus()) {
rawInput = text.prependPlus()
}

val parsedNumber = core.parsePhoneNumber(rawInput, country?.iso2)
override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) {
if (input?.tag != Constants.VIEW_TAG) {
val parsedNumber = core.parsePhoneNumber(rawInput.toString(), country?.iso2)

// Update country flag and mask if detected as a different one
if (country == null || country?.countryCode != parsedNumber?.countryCode) {
setCountry(getCountry(parsedNumber?.countryCode))
if (!hasManualCountry) {
setCountry(getCountry(parsedNumber?.countryCode))
}
}

if (count != 0) {
applyFormat()
}
}
}
}

private fun applyFormat() {
rawInput?.let { raw ->
val pureNumber = raw.filter { i -> i.isDigit() }.toMutableList()

pureNumber.add(0, CHAR_PLUS)

// Update input text as formatted phone number
core.formatPhoneNumber(parsedNumber)?.let { number ->
rawInput = number
for (i in format.indices) {
if (pureNumber.size > i) {
if (format[i] == KEY_SPACE && pureNumber[i] != CHAR_SPACE) {
pureNumber.add(i, CHAR_SPACE)
continue
}

if (format[i] == KEY_DASH && pureNumber[i] != CHAR_DASH) {
pureNumber.add(i, CHAR_DASH)
continue
}
}
}

rawInput = pureNumber.joinToString("")
}
}

Expand All @@ -65,6 +90,7 @@ class PhoneNumberKit(private val context: Context) {
// Clear input if a country code selected manually
if (isManual) {
rawInput = country.countryCode.prependPlus()
hasManualCountry = true
}

// Setup country icon
Expand All @@ -75,10 +101,18 @@ class PhoneNumberKit(private val context: Context) {
// Set text length limit according to the example phone number
core.formatPhoneNumber(core.getExampleNumber(country.iso2))?.let { number ->
input?.editText?.filters = arrayOf(InputFilter.LengthFilter(number.length))
format = createNumberFormat(number)
applyFormat()
}
}
}

private fun createNumberFormat(number: String): String {
var format = number.replace("(\\d)".toRegex(), KEY_DIGIT.toString())
format = format.replace("(\\s)".toRegex(), KEY_SPACE.toString())
return format
}

/**
* Attaches to textInputLayout
*/
Expand All @@ -92,7 +126,8 @@ class PhoneNumberKit(private val context: Context) {
input.setStartIconTintList(null)

// Set initial country
setCountry(getCountry(defaultCountry) ?: Countries.list[0], true)
setCountry(getCountry(defaultCountry) ?: Countries.list[0])
rawInput = country?.countryCode?.prependPlus()
}

/**
Expand Down
4 changes: 3 additions & 1 deletion lib/src/main/java/me/ibrahimsn/lib/core/Core.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package me.ibrahimsn.lib.core
import com.google.i18n.phonenumbers.NumberParseException
import com.google.i18n.phonenumbers.PhoneNumberUtil
import com.google.i18n.phonenumbers.Phonenumber
import me.ibrahimsn.lib.util.prependPlus
import me.ibrahimsn.lib.util.startsWithPlus
import java.util.*

class Core {
Expand All @@ -15,7 +17,7 @@ class Core {
): Phonenumber.PhoneNumber? {
return try {
phoneUtil.parseAndKeepRawInput(
number,
if (number.startsWithPlus()) number else number.prependPlus(),
defaultRegion?.toUpperCase(Locale.ROOT)
)
} catch(e: NumberParseException) {
Expand Down
6 changes: 3 additions & 3 deletions lib/src/main/java/me/ibrahimsn/lib/util/Extensions.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package me.ibrahimsn.lib.util

fun CharSequence.prependPlus(): String {
fun CharSequence?.prependPlus(): String {
return StringBuilder()
.append("+")
.append(this)
Expand All @@ -14,6 +14,6 @@ fun Int.prependPlus(): String {
.toString()
}

fun CharSequence.startsWithPlus(): Boolean {
return this.startsWith("+")
fun CharSequence?.startsWithPlus(): Boolean {
return this?.startsWith("+") == true
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import android.text.TextWatcher

abstract class PhoneNumberTextWatcher : TextWatcher {

override fun afterTextChanged(text: Editable?) {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
// no-op
}

override fun beforeTextChanged(text: CharSequence?, p1: Int, p2: Int, p3: Int) {
override fun afterTextChanged(text: Editable?) {
// no-op
}
}

0 comments on commit 9a1f9b2

Please sign in to comment.