Skip to content

International phone number input field for Android with emoji flags

License

Notifications You must be signed in to change notification settings

tfcporciuncula/phonemoji

Repository files navigation

Maven Central Build Status ktlint

☏ phonemoji

Phonemoji provides a flexible text input field implementation that formats international phone numbers as you type and displays the flag of the country that matches the number's country code. It's powered by libphonenumber (or its Android port to be more precise), compatible with Material Components, and based on PhoneNumberFormattingTextWatcher.

demo

🙃 Flags are emoji, so no extra resources are required. Also, they look cute.

👉 Flags are not tappable -- there's no list with all the country codes or anything like that.

🚩 The flag is updated as the phone number is entered and formatted. It updates as soon as the country code is identified, and it only changes again if a different valid country code is entered.

➕ It only supports international numbers, so the plus sign is always there and can't be removed. It's still part of the input, though, so you can still move the cursor before the sign. If you do that and input a character, the input will be entered after the plus sign.

Download

repositories {
  mavenCentral()
}

dependencies {
  implementation 'com.fredporciuncula:phonemoji:1.5.2'
}

Usage

The library offers a TextInputEditText and a TextInputLayout implementation. When you put them together, the TextInputLayout renders the flag as a startIconDrawable based on the TextInputEditText input:

<com.fredporciuncula.phonemoji.PhonemojiTextInputLayout
  style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:hint="@string/phone_number"
  >

  <com.fredporciuncula.phonemoji.PhonemojiTextInputEditText
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

</com.fredporciuncula.phonemoji.PhonemojiTextInputLayout>

  • The flag visibility and size can be set with the attributes phonemoji_showFlag and phonemoji_flagSize.
  • The field is never empty. By default, it starts with +XX, where XX is the country calling code for the network country (from TelephonyManager) or for the country from the default Locale in case the network country doesn't resolve to a valid country code.
  • The initial country code can also be set with the attributes phonemoji_initialRegionCode (e.g. US for 1) and phonemoji_initialCountryCode (e.g. 1 for the US) or through setRegionCode() and setCountryCode().

If you don't want to work with a TextInputLayout, or if you don't want to render the flag as the start icon there, you can use a PhonemojiFlagTextView to render the flag anywhere you place it. You can "connect" it with the TextInputEditText by referencing it in the phonemoji_flagFor attribute like this:

<LinearLayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:orientation="horizontal"
  >

  <com.fredporciuncula.phonemoji.PhonemojiFlagTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:textSize="16sp"
    app:phonemoji_flagFor="@id/phonemojiTextInputEditText"
    />

  <com.fredporciuncula.phonemoji.PhonemojiTextInputEditText
    android:id="@+id/phonemojiTextInputEditText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:phonemoji_initialRegionCode="BR"
    />

</LinearLayout>

🙆‍♂️

Data binding

If you're planning to use data binding, don't use the text property directly like this:

android:text="@{user.phoneNumber}"

Instead, use internationalPhoneNumber to make sure the input will always be formatted properly:

internationalPhoneNumber="@{user.phoneNumber}"

Startup

The library initializes itself using the App Startup library. In general, this isn't important for consumers, and it just means you can use the library without worrying about any initialization logic. But it also means the library depends on App Startup in order to work properly, so if you disable it for any reason, the library will crash.