SlideShare a Scribd company logo
1 of 34
Download to read offline
Creating an Uber Clone - Part VI
In this part we’ll go into SMS Activation flow
Enter Mobile Number
© Codename One 2017 all rights reserved
The first form in the SMS activation flow is the enter mobile number form. It’s a simple form even though there are some interesting subtle features here. The cool thing is
that we did almost all of the work for this element already
public class EnterMobileNumberForm extends Form {
public EnterMobileNumberForm() {
super(BoxLayout.y());
Form previous = getCurrentForm();
getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW,
e -> previous.showBack());
add(new Label("Enter your mobile number", "FlagButton"));
CountryCodePicker countryCodeButton = new CountryCodePicker();
TextField phoneNumber = new TextField("", "050-123-4567", 40,
TextField.PHONENUMBER);
add(BorderLayout.centerEastWest(
phoneNumber,
null,
countryCodeButton));
Style ps = phoneNumber.getUnselectedStyle();
Style cs = countryCodeButton.getUnselectedStyle();
int pl = cs.getPaddingLeft(isRTL());
int pr = cs.getPaddingRight(isRTL());
countryCodeButton.getAllStyles().setPaddingUnit(Style.UNIT_TYPE_PIXELS);
countryCodeButton.getAllStyles().setPadding(ps.getPaddingTop(),
ps.getPaddingBottom(), pl, pr);
EnterMobileNumberForm
Let’s jump right into the code that makes that form…

We use standard back navigation since the toolbar is pretty standard here
public class EnterMobileNumberForm extends Form {
public EnterMobileNumberForm() {
super(BoxLayout.y());
Form previous = getCurrentForm();
getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW,
e -> previous.showBack());
add(new Label("Enter your mobile number", "FlagButton"));
CountryCodePicker countryCodeButton = new CountryCodePicker();
TextField phoneNumber = new TextField("", "050-123-4567", 40,
TextField.PHONENUMBER);
add(BorderLayout.centerEastWest(
phoneNumber,
null,
countryCodeButton));
Style ps = phoneNumber.getUnselectedStyle();
Style cs = countryCodeButton.getUnselectedStyle();
int pl = cs.getPaddingLeft(isRTL());
int pr = cs.getPaddingRight(isRTL());
countryCodeButton.getAllStyles().setPaddingUnit(Style.UNIT_TYPE_PIXELS);
countryCodeButton.getAllStyles().setPadding(ps.getPaddingTop(),
ps.getPaddingBottom(), pl, pr);
EnterMobileNumberForm
The phone number text field is right next to the country code button. We place it in the center of a border layout so it will take up all available space
public class EnterMobileNumberForm extends Form {
public EnterMobileNumberForm() {
super(BoxLayout.y());
Form previous = getCurrentForm();
getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW,
e -> previous.showBack());
add(new Label("Enter your mobile number", "FlagButton"));
CountryCodePicker countryCodeButton = new CountryCodePicker();
TextField phoneNumber = new TextField("", "050-123-4567", 40,
TextField.PHONENUMBER);
add(BorderLayout.centerEastWest(
phoneNumber,
null,
countryCodeButton));
Style ps = phoneNumber.getUnselectedStyle();
Style cs = countryCodeButton.getUnselectedStyle();
int pl = cs.getPaddingLeft(isRTL());
int pr = cs.getPaddingRight(isRTL());
countryCodeButton.getAllStyles().setPaddingUnit(Style.UNIT_TYPE_PIXELS);
countryCodeButton.getAllStyles().setPadding(ps.getPaddingTop(),
ps.getPaddingBottom(), pl, pr);
EnterMobileNumberForm
I want the padding on the text field and button to match so they align properly. Once paddings are set they are always in pixels so we need to change the style to use
pixels. I don't want to impact the left/right padding values so I extract them first and save them so I can restore them into the UI. I could technically create a separate
UIID to align both but I wanted to do this in the code so future changes to the theme won't break alignment

Just so you’ll get a sense of why this exists this screenshot shows side by side how this looks with and without the alignment code. Guess which is the right one…
Style ps = phoneNumber.getUnselectedStyle();
Style cs = countryCodeButton.getUnselectedStyle();
int pl = cs.getPaddingLeft(isRTL());
int pr = cs.getPaddingRight(isRTL());
countryCodeButton.getAllStyles().setPaddingUnit(Style.UNIT_TYPE_PIXELS);
countryCodeButton.getAllStyles().setPadding(ps.getPaddingTop(),
ps.getPaddingBottom(), pl, pr);
setEditOnShow(phoneNumber);
FloatingActionButton fab = FloatingActionButton.createFAB(
FontImage.MATERIAL_ARROW_FORWARD);
fab.bindFabToContainer(this);
fab.addActionListener(e -> {
String number = phoneNumber.getText();
if(number.startsWith("0")) {
number = number.substring(1);
}
new EnterSMSVerificationDigitsForm(countryCodeButton.getText() +
"-" + number).show();
});
}
}
EnterMobileNumberForm
You can start editing a text field by invoking startEditing. However, this is a bit more challenging to do with a form that isn't showing yet so we have a special case for
that: setEditOnShow.

And this is pretty much it for this form…
SMS Verification
© Codename One 2017 all rights reserved
Once the number is entered we move to the SMS verification stage or password entry stage. In this case I’ve hardcoded the SMS verification stage. I didn’t do the SMS
re-send countdown but I did do the number input. Notice that the text fields look like Android text fields but have a sort of center alignment structure. Also notice that the
error mode spans the 4 text elements…

Lets jump into the code and look at how this was done.
public class EnterSMSVerificationDigitsForm extends Form {
public EnterSMSVerificationDigitsForm(String phone) {
super(new BorderLayout());
Form previous = getCurrentForm();
getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW,
e -> previous.showBack());
Container box = new Container(BoxLayout.y());
box.setScrollableY(true);
box.add(new SpanLabel("Enter the 4-digit code sent to you at " + phone,
"FlagButton"));
TextField[] digits = createDigits(4);
setEditOnShow(digits[0]);
box.add(BoxLayout.encloseX(digits));
SpanLabel error = new SpanLabel("The SMS passcode you've entered is incorrect",
"ErrorLabel");
error.setVisible(false);
box.add(error);
add(CENTER, box);
Label resend = new Label("Resend code in 00:12", "ResendCode");
add(SOUTH, resend);
FloatingActionButton fab = FloatingActionButton.createFAB(
FontImage.MATERIAL_ARROW_FORWARD);
fab.bindFabToContainer(this);
EnterSMSVerificationDigitsForm
The EnterSMSVerificationDigitsForm is a bit of a mouthful but it describes the function of the form rather well. Lets go over this form line by line…

We use a border layout and place a box in the center which we make scrollable on the Y axis. The reason for the border layout is so we can stick the countdown label in
the south. Otherwise I would have used box layout for the entire form. 

Notice I set the container to be scrollable on the Y axis, this is important for containers where we have text input. It allows our keyboard code to resize the container
properly when the keyboard shows.

I’d like to also point out that I used the standard back command in the toolbar.
public class EnterSMSVerificationDigitsForm extends Form {
public EnterSMSVerificationDigitsForm(String phone) {
super(new BorderLayout());
Form previous = getCurrentForm();
getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW,
e -> previous.showBack());
Container box = new Container(BoxLayout.y());
box.setScrollableY(true);
box.add(new SpanLabel("Enter the 4-digit code sent to you at " + phone,
"FlagButton"));
TextField[] digits = createDigits(4);
setEditOnShow(digits[0]);
box.add(BoxLayout.encloseX(digits));
SpanLabel error = new SpanLabel("The SMS passcode you've entered is incorrect",
"ErrorLabel");
error.setVisible(false);
box.add(error);
add(CENTER, box);
Label resend = new Label("Resend code in 00:12", "ResendCode");
add(SOUTH, resend);
FloatingActionButton fab = FloatingActionButton.createFAB(
FontImage.MATERIAL_ARROW_FORWARD);
fab.bindFabToContainer(this);
EnterSMSVerificationDigitsForm
We create an array of text fields to loop over. This allows us to easily change the code to accept 6 digits. I’ll discuss the createDigits method soon
public class EnterSMSVerificationDigitsForm extends Form {
public EnterSMSVerificationDigitsForm(String phone) {
super(new BorderLayout());
Form previous = getCurrentForm();
getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW,
e -> previous.showBack());
Container box = new Container(BoxLayout.y());
box.setScrollableY(true);
box.add(new SpanLabel("Enter the 4-digit code sent to you at " + phone,
"FlagButton"));
TextField[] digits = createDigits(4);
setEditOnShow(digits[0]);
box.add(BoxLayout.encloseX(digits));
SpanLabel error = new SpanLabel("The SMS passcode you've entered is incorrect",
"ErrorLabel");
error.setVisible(false);
box.add(error);
add(CENTER, box);
Label resend = new Label("Resend code in 00:12", "ResendCode");
add(SOUTH, resend);
FloatingActionButton fab = FloatingActionButton.createFAB(
FontImage.MATERIAL_ARROW_FORWARD);
fab.bindFabToContainer(this);
EnterSMSVerificationDigitsForm
Yes, this works! It adds all the components in the array so it will add the 4 digit text fields
public class EnterSMSVerificationDigitsForm extends Form {
public EnterSMSVerificationDigitsForm(String phone) {
super(new BorderLayout());
Form previous = getCurrentForm();
getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW,
e -> previous.showBack());
Container box = new Container(BoxLayout.y());
box.setScrollableY(true);
box.add(new SpanLabel("Enter the 4-digit code sent to you at " + phone,
"FlagButton"));
TextField[] digits = createDigits(4);
setEditOnShow(digits[0]);
box.add(BoxLayout.encloseX(digits));
SpanLabel error = new SpanLabel("The SMS passcode you've entered is incorrect",
"ErrorLabel");
error.setVisible(false);
box.add(error);
add(CENTER, box);
Label resend = new Label("Resend code in 00:12", "ResendCode");
add(SOUTH, resend);
FloatingActionButton fab = FloatingActionButton.createFAB(
FontImage.MATERIAL_ARROW_FORWARD);
fab.bindFabToContainer(this);
EnterSMSVerificationDigitsForm
The error label is always there we just hide it
public class EnterSMSVerificationDigitsForm extends Form {
public EnterSMSVerificationDigitsForm(String phone) {
super(new BorderLayout());
Form previous = getCurrentForm();
getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW,
e -> previous.showBack());
Container box = new Container(BoxLayout.y());
box.setScrollableY(true);
box.add(new SpanLabel("Enter the 4-digit code sent to you at " + phone,
"FlagButton"));
TextField[] digits = createDigits(4);
setEditOnShow(digits[0]);
box.add(BoxLayout.encloseX(digits));
SpanLabel error = new SpanLabel("The SMS passcode you've entered is incorrect",
"ErrorLabel");
error.setVisible(false);
box.add(error);
add(CENTER, box);
Label resend = new Label("Resend code in 00:12", "ResendCode");
add(SOUTH, resend);
FloatingActionButton fab = FloatingActionButton.createFAB(
FontImage.MATERIAL_ARROW_FORWARD);
fab.bindFabToContainer(this);
EnterSMSVerificationDigitsForm
For now I don't animate the resend text. Again, notice that I use BorderLayout to position the resend label at the bottom and place the rest of the stuff in a BoxLayout in
the center
FloatingActionButton fab = FloatingActionButton.createFAB(
FontImage.MATERIAL_ARROW_FORWARD);
fab.bindFabToContainer(this);
fab.addActionListener(e -> {
if(!isValid(toString(digits))) {
error.setVisible(true);
errorFields(digits);
repaint();
return;
}
new EnterPasswordForm().show();
});
}
private TextField[] createDigits(int count) {
TextField[] response = new TextField[count];
for(int iter = 0 ; iter < count ; iter++) {
TextField t = new TextField("", "0", 1, TextField.NUMERIC);
t.setUIID("Digit");
t.getHintLabel().getAllStyles().setAlignment(CENTER);
response[iter] = t;
}
EnterSMSVerificationDigitsForm
When the floating action button is pressed we validate the input so we can decide whether to show an error or proceed
FloatingActionButton fab = FloatingActionButton.createFAB(
FontImage.MATERIAL_ARROW_FORWARD);
fab.bindFabToContainer(this);
fab.addActionListener(e -> {
if(!isValid(toString(digits))) {
error.setVisible(true);
errorFields(digits);
repaint();
return;
}
new EnterPasswordForm().show();
});
}
private TextField[] createDigits(int count) {
TextField[] response = new TextField[count];
for(int iter = 0 ; iter < count ; iter++) {
TextField t = new TextField("", "0", 1, TextField.NUMERIC);
t.setUIID("Digit");
t.getHintLabel().getAllStyles().setAlignment(CENTER);
response[iter] = t;
}
EnterSMSVerificationDigitsForm
The generic creation code creates the array of numeric text fields and aligns the hints to the center
private TextField[] createDigits(int count) {
TextField[] response = new TextField[count];
for(int iter = 0 ; iter < count ; iter++) {
TextField t = new TextField("", "0", 1, TextField.NUMERIC);
t.setUIID("Digit");
t.getHintLabel().getAllStyles().setAlignment(CENTER);
response[iter] = t;
}
for(int iter = 0 ; iter < count - 1 ; iter++) {
onTypeNext(response[iter], response[iter + 1]);
}
return response;
}
private void errorFields(TextField... fields) {
for(TextField f : fields) {
f.getAllStyles().setBorder(Border.createUnderlineBorder(2, 0xcc0000));
f.getSelectedStyle().setBorder(Border.createUnderlineBorder(4, 0xcc0000));
}
}
EnterSMSVerificationDigitsForm
This logic makes sure that once we type a character the input will automatically move to the next text field
private TextField[] createDigits(int count) {
TextField[] response = new TextField[count];
for(int iter = 0 ; iter < count ; iter++) {
TextField t = new TextField("", "0", 1, TextField.NUMERIC);
t.setUIID("Digit");
t.getHintLabel().getAllStyles().setAlignment(CENTER);
response[iter] = t;
}
for(int iter = 0 ; iter < count - 1 ; iter++) {
onTypeNext(response[iter], response[iter + 1]);
}
return response;
}
private void errorFields(TextField... fields) {
for(TextField f : fields) {
f.getAllStyles().setBorder(Border.createUnderlineBorder(2, 0xcc0000));
f.getSelectedStyle().setBorder(Border.createUnderlineBorder(4, 0xcc0000));
}
}
EnterSMSVerificationDigitsForm
In case of an error we just change the underline style. We could have also done this by invoking setUIID which might have been more elegant
private void errorFields(TextField... fields) {
for(TextField f : fields) {
f.getAllStyles().setBorder(Border.createUnderlineBorder(2, 0xcc0000));
f.getSelectedStyle().setBorder(Border.createUnderlineBorder(4, 0xcc0000));
}
}
private String toString(TextField[] digits) {
StringBuilder s = new StringBuilder();
for(TextField t : digits) {
s.append(t.getAsInt(0));
}
return s.toString();
}
public boolean isValid(String s) {
return s.startsWith("0");
}
private void onTypeNext(TextField current, TextField next) {
current.addDataChangedListener((i, ii) -> {
if(current.getText().length() == 1) {
current.stopEditing();
next.startEditingAsync();
}
});
EnterSMSVerificationDigitsForm
We bind a listener to each text field and if the length of the text is 1 we stop editing and move to the next text field. And this is pretty much it with the exception of the
styles we had to add to make this happen…
Digit
© Codename One 2017 all rights reserved
The Digit style is a special case of the text field specifically designed for this form. The main reason for a special style is the problematic center alignment in text field.
Because of the way this works I preferred using a 1 millimeter padding on the sides to give the feel of center alignment in this case. 

Center alignment works in text area, label etc. However, it's flaky in text fields because it's really hard to get the position right when moving from lightweight to native
editing
Digit
© Codename One 2017 all rights reserved
Another important bit is the smaller margin that makes the fields stand closer to one another
Digit
© Codename One 2017 all rights reserved
As I mentioned before since this is a specialization of text field we derive from the text field class.

One thing to notice is that in the selected style we need to override the border as well to implement a 4 pixel underline border. It’s because we derive from the unselected
digit and not from the selected version of text field so we need to re-define how a selected digit entry looks
Digit
© Codename One 2017 all rights reserved
However, we also override the font size to make it slightly smaller and thus more consistent with the native Uber app
ErrorLabel
© Codename One 2017 all rights reserved
The error label is just a red on white label
ErrorLabel
© Codename One 2017 all rights reserved
It has a bit of a smaller padding so it can use up space
ErrorLabel
© Codename One 2017 all rights reserved
It still has 0 margin like most components
ErrorLabel
© Codename One 2017 all rights reserved
But it has a smaller light font at 2.8 millimeters which is more consistent with the material design aesthetic
ResendCode
© Codename One 2017 all rights reserved
The ResendCode style just pads the text so it will align properly with the FloatingActionButton
ResendCode
© Codename One 2017 all rights reserved
It leaves margin as 0 by default
ResendCode
© Codename One 2017 all rights reserved
But it has smaller text size than a typical label
Password Entry Form
© Codename One 2017 all rights reserved
The last form in the SMS activation flow is the password entry form. It’s a trivial form after the others we’ve been through here so I’ll gloss over it relatively quickly.
public class EnterPasswordForm extends Form {
public EnterPasswordForm() {
super(new BorderLayout());
Form previous = getCurrentForm();
getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW,
e -> previous.showBack());
Container box = new Container(BoxLayout.y());
box.setScrollableY(true);
box.add(new SpanLabel("Welcome back, signin to continue", "FlagButton"));
TextField password = new TextField("", "Enter your password", 80, TextField.PASSWORD);
setEditOnShow(password);
box.add(password);
SpanLabel error = new SpanLabel("Password error", "ErrorLabel");
error.setVisible(false);
box.add(error);
add(CENTER, box);
Button forgot = new Button("I forgot my password", "ForgotPassword");
Button account = new Button("I don't have an account", "ForgotPassword");
add(SOUTH, BoxLayout.encloseY(forgot, account));
FloatingActionButton fab = FloatingActionButton.createFAB(
FontImage.MATERIAL_ARROW_FORWARD);
fab.bindFabToContainer(this);
fab.addActionListener(e -> {
new MapForm().show();
});
}
}
EnterPasswordForm
This is the entire form code literally in one page. After the activation form there is literally nothing new or interesting here. 

The only aspect that’s here and wasn’t there is the “ForgotPassword” UIID which we align with the floating action button. In this case we have 2 elements that we enclose
in a box layout Y in the south. Most of the work here is in the UIID itself.
ForgotPassword
© Codename One 2017 all rights reserved
The forgot password buttons have a bluish color and are transparent
ForgotPassword
© Codename One 2017 all rights reserved
The padding is carefully measured to align properly with the floating action button
ForgotPassword
© Codename One 2017 all rights reserved
Margin is zero as usual
ForgotPassword
© Codename One 2017 all rights reserved
The font is a relatively small 2.5 millimeter size. And that concludes the SMS activation UI flow mockup!

More Related Content

Similar to Creating an Uber - Part VI - Transcript.pdf

Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfShaiAlmog1
 
Creating a Facebook Clone - Part XVI.pdf
Creating a Facebook Clone - Part XVI.pdfCreating a Facebook Clone - Part XVI.pdf
Creating a Facebook Clone - Part XVI.pdfShaiAlmog1
 
Creating a Facebook Clone - Part VII.pdf
Creating a Facebook Clone - Part VII.pdfCreating a Facebook Clone - Part VII.pdf
Creating a Facebook Clone - Part VII.pdfShaiAlmog1
 
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdfCreating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdfShaiAlmog1
 
Creating an Uber Clone - Part III - Transcript.pdf
Creating an Uber Clone - Part III - Transcript.pdfCreating an Uber Clone - Part III - Transcript.pdf
Creating an Uber Clone - Part III - Transcript.pdfShaiAlmog1
 
Creating a Facebook Clone - Part XLI - Transcript.pdf
Creating a Facebook Clone - Part XLI - Transcript.pdfCreating a Facebook Clone - Part XLI - Transcript.pdf
Creating a Facebook Clone - Part XLI - Transcript.pdfShaiAlmog1
 
Extracting ui Design - part 6 - transcript.pdf
Extracting ui Design - part 6 - transcript.pdfExtracting ui Design - part 6 - transcript.pdf
Extracting ui Design - part 6 - transcript.pdfShaiAlmog1
 
Creating an Uber Clone - Part XXXIX.pdf
Creating an Uber Clone - Part XXXIX.pdfCreating an Uber Clone - Part XXXIX.pdf
Creating an Uber Clone - Part XXXIX.pdfShaiAlmog1
 
Creating a Facebook Clone - Part XXXV - Transcript.pdf
Creating a Facebook Clone - Part XXXV - Transcript.pdfCreating a Facebook Clone - Part XXXV - Transcript.pdf
Creating a Facebook Clone - Part XXXV - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdfCreating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdfShaiAlmog1
 
Miscellaneous Features - Part 2 - Transcript.pdf
Miscellaneous Features - Part 2 - Transcript.pdfMiscellaneous Features - Part 2 - Transcript.pdf
Miscellaneous Features - Part 2 - Transcript.pdfShaiAlmog1
 
Creating a Facebook Clone - Part VI.pdf
Creating a Facebook Clone - Part VI.pdfCreating a Facebook Clone - Part VI.pdf
Creating a Facebook Clone - Part VI.pdfShaiAlmog1
 
Creating an Uber Clone - Part XXXIV.pdf
Creating an Uber Clone - Part XXXIV.pdfCreating an Uber Clone - Part XXXIV.pdf
Creating an Uber Clone - Part XXXIV.pdfShaiAlmog1
 
Creating an Uber Clone - Part V.pdf
Creating an Uber Clone - Part V.pdfCreating an Uber Clone - Part V.pdf
Creating an Uber Clone - Part V.pdfShaiAlmog1
 
Extracting ui Design - part 4 - transcript.pdf
Extracting ui Design - part 4 - transcript.pdfExtracting ui Design - part 4 - transcript.pdf
Extracting ui Design - part 4 - transcript.pdfShaiAlmog1
 
2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf
2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf
2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdfallwayscollection
 
Nokia Asha App Development - Part 2
Nokia Asha App Development - Part 2Nokia Asha App Development - Part 2
Nokia Asha App Development - Part 2Marlon Luz
 
Creating a Facebook Clone - Part XXXV.pdf
Creating a Facebook Clone - Part XXXV.pdfCreating a Facebook Clone - Part XXXV.pdf
Creating a Facebook Clone - Part XXXV.pdfShaiAlmog1
 

Similar to Creating an Uber - Part VI - Transcript.pdf (20)

Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdf
 
Creating a Facebook Clone - Part XVI.pdf
Creating a Facebook Clone - Part XVI.pdfCreating a Facebook Clone - Part XVI.pdf
Creating a Facebook Clone - Part XVI.pdf
 
Creating a Facebook Clone - Part VII.pdf
Creating a Facebook Clone - Part VII.pdfCreating a Facebook Clone - Part VII.pdf
Creating a Facebook Clone - Part VII.pdf
 
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdfCreating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
 
Creating an Uber Clone - Part III - Transcript.pdf
Creating an Uber Clone - Part III - Transcript.pdfCreating an Uber Clone - Part III - Transcript.pdf
Creating an Uber Clone - Part III - Transcript.pdf
 
Java calculator
Java calculatorJava calculator
Java calculator
 
Creating a Facebook Clone - Part XLI - Transcript.pdf
Creating a Facebook Clone - Part XLI - Transcript.pdfCreating a Facebook Clone - Part XLI - Transcript.pdf
Creating a Facebook Clone - Part XLI - Transcript.pdf
 
Extracting ui Design - part 6 - transcript.pdf
Extracting ui Design - part 6 - transcript.pdfExtracting ui Design - part 6 - transcript.pdf
Extracting ui Design - part 6 - transcript.pdf
 
Creating an Uber Clone - Part XXXIX.pdf
Creating an Uber Clone - Part XXXIX.pdfCreating an Uber Clone - Part XXXIX.pdf
Creating an Uber Clone - Part XXXIX.pdf
 
Creating a Facebook Clone - Part XXXV - Transcript.pdf
Creating a Facebook Clone - Part XXXV - Transcript.pdfCreating a Facebook Clone - Part XXXV - Transcript.pdf
Creating a Facebook Clone - Part XXXV - Transcript.pdf
 
Creating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdfCreating a Whatsapp Clone - Part IX.pdf
Creating a Whatsapp Clone - Part IX.pdf
 
Miscellaneous Features - Part 2 - Transcript.pdf
Miscellaneous Features - Part 2 - Transcript.pdfMiscellaneous Features - Part 2 - Transcript.pdf
Miscellaneous Features - Part 2 - Transcript.pdf
 
Mobile Application Development class 007
Mobile Application Development class 007Mobile Application Development class 007
Mobile Application Development class 007
 
Creating a Facebook Clone - Part VI.pdf
Creating a Facebook Clone - Part VI.pdfCreating a Facebook Clone - Part VI.pdf
Creating a Facebook Clone - Part VI.pdf
 
Creating an Uber Clone - Part XXXIV.pdf
Creating an Uber Clone - Part XXXIV.pdfCreating an Uber Clone - Part XXXIV.pdf
Creating an Uber Clone - Part XXXIV.pdf
 
Creating an Uber Clone - Part V.pdf
Creating an Uber Clone - Part V.pdfCreating an Uber Clone - Part V.pdf
Creating an Uber Clone - Part V.pdf
 
Extracting ui Design - part 4 - transcript.pdf
Extracting ui Design - part 4 - transcript.pdfExtracting ui Design - part 4 - transcript.pdf
Extracting ui Design - part 4 - transcript.pdf
 
2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf
2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf
2. Section 2. Implementing functionality in the PersonEntry. (1.5 ma.pdf
 
Nokia Asha App Development - Part 2
Nokia Asha App Development - Part 2Nokia Asha App Development - Part 2
Nokia Asha App Development - Part 2
 
Creating a Facebook Clone - Part XXXV.pdf
Creating a Facebook Clone - Part XXXV.pdfCreating a Facebook Clone - Part XXXV.pdf
Creating a Facebook Clone - Part XXXV.pdf
 

More from ShaiAlmog1

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...ShaiAlmog1
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfShaiAlmog1
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfShaiAlmog1
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfShaiAlmog1
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfShaiAlmog1
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfShaiAlmog1
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfShaiAlmog1
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfShaiAlmog1
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfShaiAlmog1
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfShaiAlmog1
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfShaiAlmog1
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfShaiAlmog1
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfCreating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfCreating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part VI.pdf
Creating a Whatsapp Clone - Part VI.pdfCreating a Whatsapp Clone - Part VI.pdf
Creating a Whatsapp Clone - Part VI.pdfShaiAlmog1
 

More from ShaiAlmog1 (20)

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdf
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdf
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdf
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdf
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdf
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdf
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdf
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdf
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdf
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdf
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdf
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdf
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdf
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdf
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdf
 
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfCreating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdf
 
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfCreating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdf
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdf
 
Creating a Whatsapp Clone - Part VI.pdf
Creating a Whatsapp Clone - Part VI.pdfCreating a Whatsapp Clone - Part VI.pdf
Creating a Whatsapp Clone - Part VI.pdf
 

Recently uploaded

How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfSrushith Repakula
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfdanishmna97
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe中 央社
 
“Iamnobody89757” Understanding the Mysterious of Digital Identity.pdf
“Iamnobody89757” Understanding the Mysterious of Digital Identity.pdf“Iamnobody89757” Understanding the Mysterious of Digital Identity.pdf
“Iamnobody89757” Understanding the Mysterious of Digital Identity.pdfMuhammad Subhan
 
Top 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development CompaniesTop 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development CompaniesTopCSSGallery
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard37
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxFIDO Alliance
 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Skynet Technologies
 
Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGDSC PJATK
 
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...marcuskenyatta275
 
State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!Memoori
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMKumar Satyam
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAnitaRaj43
 
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxHarnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxFIDO Alliance
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform EngineeringMarcus Vechiato
 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptxFIDO Alliance
 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceSamy Fodil
 
Generative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfGenerative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfalexjohnson7307
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc
 

Recently uploaded (20)

How we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdfHow we scaled to 80K users by doing nothing!.pdf
How we scaled to 80K users by doing nothing!.pdf
 
How to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cfHow to Check CNIC Information Online with Pakdata cf
How to Check CNIC Information Online with Pakdata cf
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe
 
“Iamnobody89757” Understanding the Mysterious of Digital Identity.pdf
“Iamnobody89757” Understanding the Mysterious of Digital Identity.pdf“Iamnobody89757” Understanding the Mysterious of Digital Identity.pdf
“Iamnobody89757” Understanding the Mysterious of Digital Identity.pdf
 
Top 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development CompaniesTop 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development Companies
 
JohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptxJohnPollard-hybrid-app-RailsConf2024.pptx
JohnPollard-hybrid-app-RailsConf2024.pptx
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptx
 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
 
Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 Warsaw
 
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...
TEST BANK For, Information Technology Project Management 9th Edition Kathy Sc...
 
State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by Anitaraj
 
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptxHarnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
Harnessing Passkeys in the Battle Against AI-Powered Cyber Threats.pptx
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform Engineering
 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM Performance
 
Overview of Hyperledger Foundation
Overview of Hyperledger FoundationOverview of Hyperledger Foundation
Overview of Hyperledger Foundation
 
Generative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfGenerative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdf
 
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
TrustArc Webinar - Unified Trust Center for Privacy, Security, Compliance, an...
 

Creating an Uber - Part VI - Transcript.pdf

  • 1. Creating an Uber Clone - Part VI In this part we’ll go into SMS Activation flow
  • 2. Enter Mobile Number © Codename One 2017 all rights reserved The first form in the SMS activation flow is the enter mobile number form. It’s a simple form even though there are some interesting subtle features here. The cool thing is that we did almost all of the work for this element already
  • 3. public class EnterMobileNumberForm extends Form { public EnterMobileNumberForm() { super(BoxLayout.y()); Form previous = getCurrentForm(); getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW, e -> previous.showBack()); add(new Label("Enter your mobile number", "FlagButton")); CountryCodePicker countryCodeButton = new CountryCodePicker(); TextField phoneNumber = new TextField("", "050-123-4567", 40, TextField.PHONENUMBER); add(BorderLayout.centerEastWest( phoneNumber, null, countryCodeButton)); Style ps = phoneNumber.getUnselectedStyle(); Style cs = countryCodeButton.getUnselectedStyle(); int pl = cs.getPaddingLeft(isRTL()); int pr = cs.getPaddingRight(isRTL()); countryCodeButton.getAllStyles().setPaddingUnit(Style.UNIT_TYPE_PIXELS); countryCodeButton.getAllStyles().setPadding(ps.getPaddingTop(), ps.getPaddingBottom(), pl, pr); EnterMobileNumberForm Let’s jump right into the code that makes that form… We use standard back navigation since the toolbar is pretty standard here
  • 4. public class EnterMobileNumberForm extends Form { public EnterMobileNumberForm() { super(BoxLayout.y()); Form previous = getCurrentForm(); getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW, e -> previous.showBack()); add(new Label("Enter your mobile number", "FlagButton")); CountryCodePicker countryCodeButton = new CountryCodePicker(); TextField phoneNumber = new TextField("", "050-123-4567", 40, TextField.PHONENUMBER); add(BorderLayout.centerEastWest( phoneNumber, null, countryCodeButton)); Style ps = phoneNumber.getUnselectedStyle(); Style cs = countryCodeButton.getUnselectedStyle(); int pl = cs.getPaddingLeft(isRTL()); int pr = cs.getPaddingRight(isRTL()); countryCodeButton.getAllStyles().setPaddingUnit(Style.UNIT_TYPE_PIXELS); countryCodeButton.getAllStyles().setPadding(ps.getPaddingTop(), ps.getPaddingBottom(), pl, pr); EnterMobileNumberForm The phone number text field is right next to the country code button. We place it in the center of a border layout so it will take up all available space
  • 5. public class EnterMobileNumberForm extends Form { public EnterMobileNumberForm() { super(BoxLayout.y()); Form previous = getCurrentForm(); getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW, e -> previous.showBack()); add(new Label("Enter your mobile number", "FlagButton")); CountryCodePicker countryCodeButton = new CountryCodePicker(); TextField phoneNumber = new TextField("", "050-123-4567", 40, TextField.PHONENUMBER); add(BorderLayout.centerEastWest( phoneNumber, null, countryCodeButton)); Style ps = phoneNumber.getUnselectedStyle(); Style cs = countryCodeButton.getUnselectedStyle(); int pl = cs.getPaddingLeft(isRTL()); int pr = cs.getPaddingRight(isRTL()); countryCodeButton.getAllStyles().setPaddingUnit(Style.UNIT_TYPE_PIXELS); countryCodeButton.getAllStyles().setPadding(ps.getPaddingTop(), ps.getPaddingBottom(), pl, pr); EnterMobileNumberForm I want the padding on the text field and button to match so they align properly. Once paddings are set they are always in pixels so we need to change the style to use pixels. I don't want to impact the left/right padding values so I extract them first and save them so I can restore them into the UI. I could technically create a separate UIID to align both but I wanted to do this in the code so future changes to the theme won't break alignment Just so you’ll get a sense of why this exists this screenshot shows side by side how this looks with and without the alignment code. Guess which is the right one…
  • 6. Style ps = phoneNumber.getUnselectedStyle(); Style cs = countryCodeButton.getUnselectedStyle(); int pl = cs.getPaddingLeft(isRTL()); int pr = cs.getPaddingRight(isRTL()); countryCodeButton.getAllStyles().setPaddingUnit(Style.UNIT_TYPE_PIXELS); countryCodeButton.getAllStyles().setPadding(ps.getPaddingTop(), ps.getPaddingBottom(), pl, pr); setEditOnShow(phoneNumber); FloatingActionButton fab = FloatingActionButton.createFAB( FontImage.MATERIAL_ARROW_FORWARD); fab.bindFabToContainer(this); fab.addActionListener(e -> { String number = phoneNumber.getText(); if(number.startsWith("0")) { number = number.substring(1); } new EnterSMSVerificationDigitsForm(countryCodeButton.getText() + "-" + number).show(); }); } } EnterMobileNumberForm You can start editing a text field by invoking startEditing. However, this is a bit more challenging to do with a form that isn't showing yet so we have a special case for that: setEditOnShow. And this is pretty much it for this form…
  • 7. SMS Verification © Codename One 2017 all rights reserved Once the number is entered we move to the SMS verification stage or password entry stage. In this case I’ve hardcoded the SMS verification stage. I didn’t do the SMS re-send countdown but I did do the number input. Notice that the text fields look like Android text fields but have a sort of center alignment structure. Also notice that the error mode spans the 4 text elements… Lets jump into the code and look at how this was done.
  • 8. public class EnterSMSVerificationDigitsForm extends Form { public EnterSMSVerificationDigitsForm(String phone) { super(new BorderLayout()); Form previous = getCurrentForm(); getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW, e -> previous.showBack()); Container box = new Container(BoxLayout.y()); box.setScrollableY(true); box.add(new SpanLabel("Enter the 4-digit code sent to you at " + phone, "FlagButton")); TextField[] digits = createDigits(4); setEditOnShow(digits[0]); box.add(BoxLayout.encloseX(digits)); SpanLabel error = new SpanLabel("The SMS passcode you've entered is incorrect", "ErrorLabel"); error.setVisible(false); box.add(error); add(CENTER, box); Label resend = new Label("Resend code in 00:12", "ResendCode"); add(SOUTH, resend); FloatingActionButton fab = FloatingActionButton.createFAB( FontImage.MATERIAL_ARROW_FORWARD); fab.bindFabToContainer(this); EnterSMSVerificationDigitsForm The EnterSMSVerificationDigitsForm is a bit of a mouthful but it describes the function of the form rather well. Lets go over this form line by line… We use a border layout and place a box in the center which we make scrollable on the Y axis. The reason for the border layout is so we can stick the countdown label in the south. Otherwise I would have used box layout for the entire form. Notice I set the container to be scrollable on the Y axis, this is important for containers where we have text input. It allows our keyboard code to resize the container properly when the keyboard shows. I’d like to also point out that I used the standard back command in the toolbar.
  • 9. public class EnterSMSVerificationDigitsForm extends Form { public EnterSMSVerificationDigitsForm(String phone) { super(new BorderLayout()); Form previous = getCurrentForm(); getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW, e -> previous.showBack()); Container box = new Container(BoxLayout.y()); box.setScrollableY(true); box.add(new SpanLabel("Enter the 4-digit code sent to you at " + phone, "FlagButton")); TextField[] digits = createDigits(4); setEditOnShow(digits[0]); box.add(BoxLayout.encloseX(digits)); SpanLabel error = new SpanLabel("The SMS passcode you've entered is incorrect", "ErrorLabel"); error.setVisible(false); box.add(error); add(CENTER, box); Label resend = new Label("Resend code in 00:12", "ResendCode"); add(SOUTH, resend); FloatingActionButton fab = FloatingActionButton.createFAB( FontImage.MATERIAL_ARROW_FORWARD); fab.bindFabToContainer(this); EnterSMSVerificationDigitsForm We create an array of text fields to loop over. This allows us to easily change the code to accept 6 digits. I’ll discuss the createDigits method soon
  • 10. public class EnterSMSVerificationDigitsForm extends Form { public EnterSMSVerificationDigitsForm(String phone) { super(new BorderLayout()); Form previous = getCurrentForm(); getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW, e -> previous.showBack()); Container box = new Container(BoxLayout.y()); box.setScrollableY(true); box.add(new SpanLabel("Enter the 4-digit code sent to you at " + phone, "FlagButton")); TextField[] digits = createDigits(4); setEditOnShow(digits[0]); box.add(BoxLayout.encloseX(digits)); SpanLabel error = new SpanLabel("The SMS passcode you've entered is incorrect", "ErrorLabel"); error.setVisible(false); box.add(error); add(CENTER, box); Label resend = new Label("Resend code in 00:12", "ResendCode"); add(SOUTH, resend); FloatingActionButton fab = FloatingActionButton.createFAB( FontImage.MATERIAL_ARROW_FORWARD); fab.bindFabToContainer(this); EnterSMSVerificationDigitsForm Yes, this works! It adds all the components in the array so it will add the 4 digit text fields
  • 11. public class EnterSMSVerificationDigitsForm extends Form { public EnterSMSVerificationDigitsForm(String phone) { super(new BorderLayout()); Form previous = getCurrentForm(); getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW, e -> previous.showBack()); Container box = new Container(BoxLayout.y()); box.setScrollableY(true); box.add(new SpanLabel("Enter the 4-digit code sent to you at " + phone, "FlagButton")); TextField[] digits = createDigits(4); setEditOnShow(digits[0]); box.add(BoxLayout.encloseX(digits)); SpanLabel error = new SpanLabel("The SMS passcode you've entered is incorrect", "ErrorLabel"); error.setVisible(false); box.add(error); add(CENTER, box); Label resend = new Label("Resend code in 00:12", "ResendCode"); add(SOUTH, resend); FloatingActionButton fab = FloatingActionButton.createFAB( FontImage.MATERIAL_ARROW_FORWARD); fab.bindFabToContainer(this); EnterSMSVerificationDigitsForm The error label is always there we just hide it
  • 12. public class EnterSMSVerificationDigitsForm extends Form { public EnterSMSVerificationDigitsForm(String phone) { super(new BorderLayout()); Form previous = getCurrentForm(); getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW, e -> previous.showBack()); Container box = new Container(BoxLayout.y()); box.setScrollableY(true); box.add(new SpanLabel("Enter the 4-digit code sent to you at " + phone, "FlagButton")); TextField[] digits = createDigits(4); setEditOnShow(digits[0]); box.add(BoxLayout.encloseX(digits)); SpanLabel error = new SpanLabel("The SMS passcode you've entered is incorrect", "ErrorLabel"); error.setVisible(false); box.add(error); add(CENTER, box); Label resend = new Label("Resend code in 00:12", "ResendCode"); add(SOUTH, resend); FloatingActionButton fab = FloatingActionButton.createFAB( FontImage.MATERIAL_ARROW_FORWARD); fab.bindFabToContainer(this); EnterSMSVerificationDigitsForm For now I don't animate the resend text. Again, notice that I use BorderLayout to position the resend label at the bottom and place the rest of the stuff in a BoxLayout in the center
  • 13. FloatingActionButton fab = FloatingActionButton.createFAB( FontImage.MATERIAL_ARROW_FORWARD); fab.bindFabToContainer(this); fab.addActionListener(e -> { if(!isValid(toString(digits))) { error.setVisible(true); errorFields(digits); repaint(); return; } new EnterPasswordForm().show(); }); } private TextField[] createDigits(int count) { TextField[] response = new TextField[count]; for(int iter = 0 ; iter < count ; iter++) { TextField t = new TextField("", "0", 1, TextField.NUMERIC); t.setUIID("Digit"); t.getHintLabel().getAllStyles().setAlignment(CENTER); response[iter] = t; } EnterSMSVerificationDigitsForm When the floating action button is pressed we validate the input so we can decide whether to show an error or proceed
  • 14. FloatingActionButton fab = FloatingActionButton.createFAB( FontImage.MATERIAL_ARROW_FORWARD); fab.bindFabToContainer(this); fab.addActionListener(e -> { if(!isValid(toString(digits))) { error.setVisible(true); errorFields(digits); repaint(); return; } new EnterPasswordForm().show(); }); } private TextField[] createDigits(int count) { TextField[] response = new TextField[count]; for(int iter = 0 ; iter < count ; iter++) { TextField t = new TextField("", "0", 1, TextField.NUMERIC); t.setUIID("Digit"); t.getHintLabel().getAllStyles().setAlignment(CENTER); response[iter] = t; } EnterSMSVerificationDigitsForm The generic creation code creates the array of numeric text fields and aligns the hints to the center
  • 15. private TextField[] createDigits(int count) { TextField[] response = new TextField[count]; for(int iter = 0 ; iter < count ; iter++) { TextField t = new TextField("", "0", 1, TextField.NUMERIC); t.setUIID("Digit"); t.getHintLabel().getAllStyles().setAlignment(CENTER); response[iter] = t; } for(int iter = 0 ; iter < count - 1 ; iter++) { onTypeNext(response[iter], response[iter + 1]); } return response; } private void errorFields(TextField... fields) { for(TextField f : fields) { f.getAllStyles().setBorder(Border.createUnderlineBorder(2, 0xcc0000)); f.getSelectedStyle().setBorder(Border.createUnderlineBorder(4, 0xcc0000)); } } EnterSMSVerificationDigitsForm This logic makes sure that once we type a character the input will automatically move to the next text field
  • 16. private TextField[] createDigits(int count) { TextField[] response = new TextField[count]; for(int iter = 0 ; iter < count ; iter++) { TextField t = new TextField("", "0", 1, TextField.NUMERIC); t.setUIID("Digit"); t.getHintLabel().getAllStyles().setAlignment(CENTER); response[iter] = t; } for(int iter = 0 ; iter < count - 1 ; iter++) { onTypeNext(response[iter], response[iter + 1]); } return response; } private void errorFields(TextField... fields) { for(TextField f : fields) { f.getAllStyles().setBorder(Border.createUnderlineBorder(2, 0xcc0000)); f.getSelectedStyle().setBorder(Border.createUnderlineBorder(4, 0xcc0000)); } } EnterSMSVerificationDigitsForm In case of an error we just change the underline style. We could have also done this by invoking setUIID which might have been more elegant
  • 17. private void errorFields(TextField... fields) { for(TextField f : fields) { f.getAllStyles().setBorder(Border.createUnderlineBorder(2, 0xcc0000)); f.getSelectedStyle().setBorder(Border.createUnderlineBorder(4, 0xcc0000)); } } private String toString(TextField[] digits) { StringBuilder s = new StringBuilder(); for(TextField t : digits) { s.append(t.getAsInt(0)); } return s.toString(); } public boolean isValid(String s) { return s.startsWith("0"); } private void onTypeNext(TextField current, TextField next) { current.addDataChangedListener((i, ii) -> { if(current.getText().length() == 1) { current.stopEditing(); next.startEditingAsync(); } }); EnterSMSVerificationDigitsForm We bind a listener to each text field and if the length of the text is 1 we stop editing and move to the next text field. And this is pretty much it with the exception of the styles we had to add to make this happen…
  • 18. Digit © Codename One 2017 all rights reserved The Digit style is a special case of the text field specifically designed for this form. The main reason for a special style is the problematic center alignment in text field. Because of the way this works I preferred using a 1 millimeter padding on the sides to give the feel of center alignment in this case. Center alignment works in text area, label etc. However, it's flaky in text fields because it's really hard to get the position right when moving from lightweight to native editing
  • 19. Digit © Codename One 2017 all rights reserved Another important bit is the smaller margin that makes the fields stand closer to one another
  • 20. Digit © Codename One 2017 all rights reserved As I mentioned before since this is a specialization of text field we derive from the text field class. One thing to notice is that in the selected style we need to override the border as well to implement a 4 pixel underline border. It’s because we derive from the unselected digit and not from the selected version of text field so we need to re-define how a selected digit entry looks
  • 21. Digit © Codename One 2017 all rights reserved However, we also override the font size to make it slightly smaller and thus more consistent with the native Uber app
  • 22. ErrorLabel © Codename One 2017 all rights reserved The error label is just a red on white label
  • 23. ErrorLabel © Codename One 2017 all rights reserved It has a bit of a smaller padding so it can use up space
  • 24. ErrorLabel © Codename One 2017 all rights reserved It still has 0 margin like most components
  • 25. ErrorLabel © Codename One 2017 all rights reserved But it has a smaller light font at 2.8 millimeters which is more consistent with the material design aesthetic
  • 26. ResendCode © Codename One 2017 all rights reserved The ResendCode style just pads the text so it will align properly with the FloatingActionButton
  • 27. ResendCode © Codename One 2017 all rights reserved It leaves margin as 0 by default
  • 28. ResendCode © Codename One 2017 all rights reserved But it has smaller text size than a typical label
  • 29. Password Entry Form © Codename One 2017 all rights reserved The last form in the SMS activation flow is the password entry form. It’s a trivial form after the others we’ve been through here so I’ll gloss over it relatively quickly.
  • 30. public class EnterPasswordForm extends Form { public EnterPasswordForm() { super(new BorderLayout()); Form previous = getCurrentForm(); getToolbar().setBackCommand("", Toolbar.BackCommandPolicy.AS_ARROW, e -> previous.showBack()); Container box = new Container(BoxLayout.y()); box.setScrollableY(true); box.add(new SpanLabel("Welcome back, signin to continue", "FlagButton")); TextField password = new TextField("", "Enter your password", 80, TextField.PASSWORD); setEditOnShow(password); box.add(password); SpanLabel error = new SpanLabel("Password error", "ErrorLabel"); error.setVisible(false); box.add(error); add(CENTER, box); Button forgot = new Button("I forgot my password", "ForgotPassword"); Button account = new Button("I don't have an account", "ForgotPassword"); add(SOUTH, BoxLayout.encloseY(forgot, account)); FloatingActionButton fab = FloatingActionButton.createFAB( FontImage.MATERIAL_ARROW_FORWARD); fab.bindFabToContainer(this); fab.addActionListener(e -> { new MapForm().show(); }); } } EnterPasswordForm This is the entire form code literally in one page. After the activation form there is literally nothing new or interesting here. The only aspect that’s here and wasn’t there is the “ForgotPassword” UIID which we align with the floating action button. In this case we have 2 elements that we enclose in a box layout Y in the south. Most of the work here is in the UIID itself.
  • 31. ForgotPassword © Codename One 2017 all rights reserved The forgot password buttons have a bluish color and are transparent
  • 32. ForgotPassword © Codename One 2017 all rights reserved The padding is carefully measured to align properly with the floating action button
  • 33. ForgotPassword © Codename One 2017 all rights reserved Margin is zero as usual
  • 34. ForgotPassword © Codename One 2017 all rights reserved The font is a relatively small 2.5 millimeter size. And that concludes the SMS activation UI flow mockup!