As requested by , here is a custom widget for entering international phone numbers. This simple problem actually presented a unique challenge insofar as you can create a Custom Field Widget - but the FlutterFlow UX does not allow access to its state. So Fake State 3.0 to the rescue!! I will explain further below.
It also exposed a bug in the FlutterFlow assets generation. Apparently FlutterFlow run mode does not have access to assets provided by a pub.dev package, so you will not see flags in run mode. But you will if you download the code and compile it.
So let's start with the Widget itself. It uses the intl_phone_field dependency. So we are setting up the Widget as follows: [image.png] and the dependency: [image.png] And the following code:
import 'package:intl_phone_field/intl_phone_field.dart';
class PhoneField extends StatefulWidget {
const PhoneField({
Key key,
this.width,
this.height,
this.state,
this.id,
this.label,
this.initialValue,
this.initialCountry,
}) : super(key: key);
final double width;
final double height;
final dynamic state;
final String id;
final String label;
final String initialValue;
final String initialCountry;
@override
_PhoneFieldState createState() => _PhoneFieldState();
}
class _PhoneFieldState extends State {
@override
Widget build(BuildContext context) {
return Container(
width: widget.width,
height: widget.height,
child: IntlPhoneField(
decoration: InputDecoration(
labelText: widget.label,
border: OutlineInputBorder(
borderSide: BorderSide(),
),
),
initialCountryCode: widget.initialCountry,
initialValue: widget.initialValue,
onChanged: (phone) {
if (widget.state[widget.id]==null) widget.state[widget.id] = {};
widget.state[widget.id]["phoneNumber"] = phone.completeNumber;
},
));
}
}
Compile and Preview. You will just get a blank box, but enter these parameter values and it should look OK:
[image.png]
So why do we need Fake State to interact with this Widget? Well, FlutterFlow does not allow us to directly interact with the state of the Widget in any way (at least that I have been able to find), so we need to get around it using Fake State 3.0. If you are unfamiliar with this concept, please read my Fake State 3.0 tutorial. Here I will just take you through a very simple version of it.
We are going to need 2 custom functions. The first one creates our application wide state object:
[image.png] using this code:
dynamic createAppState() { dynamic state = {}; return state; }That is the application level state that we need to pass around to all our pages as the "state" parameter.
The only other function we need is one that can read the phone number from the widget. It is defined like this: [image.png] WIth the following code:
String getPhoneNumber(
dynamic state,
String id,
) {
dynamic value = state[id];
if (value == null) return ("");
return value["phoneNumber"];
}
So, what we are doing in the widget is setting the phone number into the state on change, by ID. And this custom function is retrieving that phone number by that same ID. We need the ID because any given page could have mobile, landline, work etc. numbers.
So, let's put it together. First up, we need a "Splash Screen" that sets up the application wide Fake State. I called mine "ETPhoneHome" and laid it out like this: [image.png]
Then we need a page to enter the phone number. I named mine "EnterNumber". The important thing for this page is the state. So it has a state parameter as follows:
[image.png] And the layout is like this (using the new Custom Widget):
[image.png] The Custom Widget Properties are set like this: [image.png] Finally we need a page to display the entered phone number. I named mine "ShowNumber" and this is the layout: [image.png] Just like the EnterNumber page, it takes state as a parameter. So we can retrieve the phone number from the widget on the previous page like so: [image.png] Now all that is left is to add the actions. We start on the ETPhoneHome page by creating the state during the first button click: [image.png] with these parameters: [image.png] This sets up our application wide state and now we can leverage that. The phone widget will automatically set a field in the state (keyed by ID) whenever you change the number, so on the EnterNumber page, we can set the Dial button action as follows: [image.png] Which in turn makes our ShowNumber page just work because it is able to retrieve the entered phone number from the state based on the ID, using the custom function we set up earlier. So here is the final flow: [image.png] [image.png] (Flag image is missing in run mode, but OK on all real platforms)
Select a country: [image.png] Key in a number: [image.png] and click on Dial: [image.png] And that is all folks. Happy Fluttering!