SlideShare a Scribd company logo
1 of 25
Download to read offline
Creating an Uber Clone - Part VII
In this section we finally get to “the map” UI, I hope you followed the instructions before for configuring the map. If not please follow through with that if things don’t work
and if you don’t see the map or it acts funny check out with us in the online support forums. You can also check out the map section in the deep dive into mobile
development course which comes bundled.

Before we begin we need a class we discussed before in the maps module. The MapLayout, I didn’t change much as left it “as is”. Since it’s already available elsewhere I
won’t go into the full discussion here and go right into the form itself.
The Map
© Codename One 2017 all rights reserved
Before we proceed I'd like to highlight some subtle things in this screenshot and discuss what we will and will not do.
The Map
© Codename One 2017 all rights reserved
✦The hamburger menu button above
represents the side menu
✦The "Where to?" field is really a button
✦For now I'll just place one unmoving Taxi
and we'll deal with the positioning later on
✦The two icons on the bottom represent
historic rides which I'll hardcode for now
✦The bottom notice is something I won't
implement within the app
I won’t do the side menu right now but I will do it soon…

The "Where to?" field is really a button that leads to a different UI. This UI is overlaid on top of the map so it is a part of this Form

I’ll position one taxi in a hardcoded location as part of the mockup

The icons at the bottom are historic rides, I’ll add two hardcoded historic rides for now

I won’t go into the notice at the bottom. It's possible but it would be non-trivial
public class MapForm extends Form {
private static final String MAP_JS_KEY = "AIza-------";
private Image square;
private Image dropShadow;
public MapForm() {
super(new LayeredLayout());
setScrollableY(false);
Display.getInstance().callSeriallyOnIdle(() -> {
dropShadow = LoginForm.squareShadow(getDisplayWidth(), 30,
convertToPixels(3), 0.40f);
});
setTransitionOutAnimator(CommonTransitions.createEmpty());
MapContainer mc = new MapContainer(MAP_JS_KEY);
mc.setShowMyLocation(true);
add(mc);
Container mapLayer = new Container();
mapLayer.setLayout(new MapLayout(mc, mapLayer));
add(mapLayer);
Coord telAviv = new Coord(32.072449, 34.778613);
mc.zoom(telAviv, mc.getMaxZoom() + 1);
Label car = new Label(Resources.getGlobalResources().
getImage("map-vehicle-icon-uberX.png"));
car.getAllStyles().setOpacity(140);
MapForm
Lets jump right into the code.

You need the JS key from Google Maps as explained in the map extension page. This must have a filled up value
public class MapForm extends Form {
private static final String MAP_JS_KEY = "AIza-------";
private Image square;
private Image dropShadow;
public MapForm() {
super(new LayeredLayout());
setScrollableY(false);
Display.getInstance().callSeriallyOnIdle(() -> {
dropShadow = LoginForm.squareShadow(getDisplayWidth(), 30,
convertToPixels(3), 0.40f);
});
setTransitionOutAnimator(CommonTransitions.createEmpty());
MapContainer mc = new MapContainer(MAP_JS_KEY);
mc.setShowMyLocation(true);
add(mc);
Container mapLayer = new Container();
mapLayer.setLayout(new MapLayout(mc, mapLayer));
add(mapLayer);
Coord telAviv = new Coord(32.072449, 34.778613);
mc.zoom(telAviv, mc.getMaxZoom() + 1);
Label car = new Label(Resources.getGlobalResources().
getImage("map-vehicle-icon-uberX.png"));
car.getAllStyles().setOpacity(140);
MapForm
We usually use BorderLayout which implicitly disables scrollability. LayeredLayout doesn't do that and the forms content pane is scrollable on the Y-axis by default
public class MapForm extends Form {
private static final String MAP_JS_KEY = "AIza-------";
private Image square;
private Image dropShadow;
public MapForm() {
super(new LayeredLayout());
setScrollableY(false);
Display.getInstance().callSeriallyOnIdle(() -> {
dropShadow = LoginForm.squareShadow(getDisplayWidth(), 30,
convertToPixels(3), 0.40f);
});
setTransitionOutAnimator(CommonTransitions.createEmpty());
MapContainer mc = new MapContainer(MAP_JS_KEY);
mc.setShowMyLocation(true);
add(mc);
Container mapLayer = new Container();
mapLayer.setLayout(new MapLayout(mc, mapLayer));
add(mapLayer);
Coord telAviv = new Coord(32.072449, 34.778613);
mc.zoom(telAviv, mc.getMaxZoom() + 1);
Label car = new Label(Resources.getGlobalResources().
getImage("map-vehicle-icon-uberX.png"));
car.getAllStyles().setOpacity(140);
MapForm
Notice we didn't use a thread here and instead used the callSeriallyOnIdle method. On the login Form I didn't use that because the animation might have prevented idle
from occurring. This shadow is used later on in the showNavigationToolbar method
public class MapForm extends Form {
private static final String MAP_JS_KEY = "AIza-------";
private Image square;
private Image dropShadow;
public MapForm() {
super(new LayeredLayout());
setScrollableY(false);
Display.getInstance().callSeriallyOnIdle(() -> {
dropShadow = LoginForm.squareShadow(getDisplayWidth(), 30,
convertToPixels(3), 0.40f);
});
setTransitionOutAnimator(CommonTransitions.createEmpty());
MapContainer mc = new MapContainer(MAP_JS_KEY);
mc.setShowMyLocation(true);
add(mc);
Container mapLayer = new Container();
mapLayer.setLayout(new MapLayout(mc, mapLayer));
add(mapLayer);
Coord telAviv = new Coord(32.072449, 34.778613);
mc.zoom(telAviv, mc.getMaxZoom() + 1);
Label car = new Label(Resources.getGlobalResources().
getImage("map-vehicle-icon-uberX.png"));
car.getAllStyles().setOpacity(140);
MapForm
The transitions in the main application are based on cover and the transition out will only be a problem
public class MapForm extends Form {
private static final String MAP_JS_KEY = "AIza-------";
private Image square;
private Image dropShadow;
public MapForm() {
super(new LayeredLayout());
setScrollableY(false);
Display.getInstance().callSeriallyOnIdle(() -> {
dropShadow = LoginForm.squareShadow(getDisplayWidth(), 30,
convertToPixels(3), 0.40f);
});
setTransitionOutAnimator(CommonTransitions.createEmpty());
MapContainer mc = new MapContainer(MAP_JS_KEY);
mc.setShowMyLocation(true);
add(mc);
Container mapLayer = new Container();
mapLayer.setLayout(new MapLayout(mc, mapLayer));
add(mapLayer);
Coord telAviv = new Coord(32.072449, 34.778613);
mc.zoom(telAviv, mc.getMaxZoom() + 1);
Label car = new Label(Resources.getGlobalResources().
getImage("map-vehicle-icon-uberX.png"));
car.getAllStyles().setOpacity(140);
MapForm
The map is on the lowest layer and everything is placed on top of it
public class MapForm extends Form {
private static final String MAP_JS_KEY = "AIza-------";
private Image square;
private Image dropShadow;
public MapForm() {
super(new LayeredLayout());
setScrollableY(false);
Display.getInstance().callSeriallyOnIdle(() -> {
dropShadow = LoginForm.squareShadow(getDisplayWidth(), 30,
convertToPixels(3), 0.40f);
});
setTransitionOutAnimator(CommonTransitions.createEmpty());
MapContainer mc = new MapContainer(MAP_JS_KEY);
mc.setShowMyLocation(true);
add(mc);
Container mapLayer = new Container();
mapLayer.setLayout(new MapLayout(mc, mapLayer));
add(mapLayer);
Coord telAviv = new Coord(32.072449, 34.778613);
mc.zoom(telAviv, mc.getMaxZoom() + 1);
Label car = new Label(Resources.getGlobalResources().
getImage("map-vehicle-icon-uberX.png"));
car.getAllStyles().setOpacity(140);
MapForm
This layer is on top of the map and uses the MapLayout. Here we will place the car and other landmarks we need
mapLayer.setLayout(new MapLayout(mc, mapLayer));
add(mapLayer);
Coord telAviv = new Coord(32.072449, 34.778613);
mc.zoom(telAviv, mc.getMaxZoom() + 1);
Label car = new Label(Resources.getGlobalResources().
getImage("map-vehicle-icon-uberX.png"));
car.getAllStyles().setOpacity(140);
mapLayer.add(telAviv, car);
square = Image.createImage(convertToPixels(0.7f),
convertToPixels(0.7f), 0xff000000);
Button whereTo = new Button("Where To?", square, "WhereTo");
whereTo.setGap(convertToPixels(3));
add(BoxLayout.encloseY(whereTo));
FloatingActionButton history1 = FloatingActionButton.createFAB(
FontImage.MATERIAL_HISTORY, "History");
FloatingActionButton history2 = FloatingActionButton.createFAB(
FontImage.MATERIAL_HISTORY, "History");
TextArea history1Label = new TextArea("Mikve Yisrael Str...", 3, 4);
TextArea history2Label = new TextArea("Burgeranch", 3, 4);
history1Label.setUIID("HistoryLabel");
history2Label.setUIID("HistoryLabel");
history1Label.setEditable(false);
MapForm
I place a car on top of the map in Tel Aviv. Notice that the car is just a label... I've set the opacity to 140 to match the translucent cars in the native app. Notice that the
`MapLayout` takes a `Coord` as a constraint so it can properly position the car…
mapLayer.setLayout(new MapLayout(mc, mapLayer));
add(mapLayer);
Coord telAviv = new Coord(32.072449, 34.778613);
mc.zoom(telAviv, mc.getMaxZoom() + 1);
Label car = new Label(Resources.getGlobalResources().
getImage("map-vehicle-icon-uberX.png"));
car.getAllStyles().setOpacity(140);
mapLayer.add(telAviv, car);
square = Image.createImage(convertToPixels(0.7f),
convertToPixels(0.7f), 0xff000000);
Button whereTo = new Button("Where To?", square, "WhereTo");
whereTo.setGap(convertToPixels(3));
add(BoxLayout.encloseY(whereTo));
FloatingActionButton history1 = FloatingActionButton.createFAB(
FontImage.MATERIAL_HISTORY, "History");
FloatingActionButton history2 = FloatingActionButton.createFAB(
FontImage.MATERIAL_HISTORY, "History");
TextArea history1Label = new TextArea("Mikve Yisrael Str...", 3, 4);
TextArea history2Label = new TextArea("Burgeranch", 3, 4);
history1Label.setUIID("HistoryLabel");
history2Label.setUIID("HistoryLabel");
history1Label.setEditable(false);
MapForm
This is the small square we place next to the "Where to?" button. I could have used a unicode value too but it wasn't available in all the fonts. Notice the "Where to?"
element is just a button as it moves us to a separate UI and isn't really a TextField
whereTo.setGap(convertToPixels(3));
add(BoxLayout.encloseY(whereTo));
FloatingActionButton history1 = FloatingActionButton.createFAB(
FontImage.MATERIAL_HISTORY, "History");
FloatingActionButton history2 = FloatingActionButton.createFAB(
FontImage.MATERIAL_HISTORY, "History");
TextArea history1Label = new TextArea("Mikve Yisrael Str...", 3, 4);
TextArea history2Label = new TextArea("Burgeranch", 3, 4);
history1Label.setUIID("HistoryLabel");
history2Label.setUIID("HistoryLabel");
history1Label.setEditable(false);
history1Label.setGrowByContent(false);
history2Label.setEditable(false);
history2Label.setGrowByContent(false);
Container h1 = BoxLayout.encloseY(history1, history1Label);
Container h2 = BoxLayout.encloseY(history2, history2Label);
h1.setLeadComponent(history1);
h2.setLeadComponent(history2);
ScaleImageLabel gradient = new ScaleImageLabel(Resources.
getGlobalResources().getImage("gradient-overlay.png"));
gradient.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
add(BorderLayout.south(gradient));
MapForm
The history buttons are FloatingActionButton instances that are customized in terms of styling. I used TextArea instead of SpanLabel because I wanted the history
element to act as a single component with lead component. Lead components can take over a hierarchy of several components and handle the events for everyone so in
this case a click on the text area below the history will trigger an event in the FloatingActionButton
whereTo.setGap(convertToPixels(3));
add(BoxLayout.encloseY(whereTo));
FloatingActionButton history1 = FloatingActionButton.createFAB(
FontImage.MATERIAL_HISTORY, "History");
FloatingActionButton history2 = FloatingActionButton.createFAB(
FontImage.MATERIAL_HISTORY, "History");
TextArea history1Label = new TextArea("Mikve Yisrael Str...", 3, 4);
TextArea history2Label = new TextArea("Burgeranch", 3, 4);
history1Label.setUIID("HistoryLabel");
history2Label.setUIID("HistoryLabel");
history1Label.setEditable(false);
history1Label.setGrowByContent(false);
history2Label.setEditable(false);
history2Label.setGrowByContent(false);
Container h1 = BoxLayout.encloseY(history1, history1Label);
Container h2 = BoxLayout.encloseY(history2, history2Label);
h1.setLeadComponent(history1);
h2.setLeadComponent(history2);
ScaleImageLabel gradient = new ScaleImageLabel(Resources.
getGlobalResources().getImage("gradient-overlay.png"));
gradient.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
add(BorderLayout.south(gradient));
MapForm
The bottom of the map has a gradient overlay that darkens the bottom. This is probably in place to make the history labels readable. I just generated a gradient image in
photoshop and placed it there
history1Label.setUIID("HistoryLabel");
history2Label.setUIID("HistoryLabel");
history1Label.setEditable(false);
history1Label.setGrowByContent(false);
history2Label.setEditable(false);
history2Label.setGrowByContent(false);
Container h1 = BoxLayout.encloseY(history1, history1Label);
Container h2 = BoxLayout.encloseY(history2, history2Label);
h1.setLeadComponent(history1);
h2.setLeadComponent(history2);
ScaleImageLabel gradient = new ScaleImageLabel(Resources.
getGlobalResources().getImage("gradient-overlay.png"));
gradient.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
add(BorderLayout.south(gradient));
add(BorderLayout.south(FlowLayout.encloseCenter(h1, h2)));
}
@Override
protected void initGlobalToolbar() {
setToolbar(new Toolbar(true));
CommonCode.constructSideMenu(getToolbar());
}
}
MapForm
We do two important things here... We use the overlay toolbar which "floats" on top of the UI. We initialize the side menu which we will discuss soon…

That was a lot to cover but there is a lot more... We did mention 3 new styles above which isn't that much all things considered.
WhereTo
© Codename One 2017 all rights reserved
The WhereTo style has some subtle nuances such as dark gray text
WhereTo
© Codename One 2017 all rights reserved
The padding is large and obvious, I played with it a bit to get it right
WhereTo
© Codename One 2017 all rights reserved
The margin is special, we want some margin from the sides so it won’t touch them. We need a lot of margin from the top to leave room for the title area
WhereTo
© Codename One 2017 all rights reserved
The corners are rounded on the native widget, this is very subtle so I left it at 0.3 millimeters which should be very easy. It also has a shadow which is more obvious and
80 opacity
WhereTo
© Codename One 2017 all rights reserved
The font isn’t big just slightly bigger than normal but the typical light font
History
© Codename One 2017 all rights reserved
The History button is the round button on the bottom of the map leading to historic rides. It’s black on white but is implemented as a floating action button
HistoryLabel
© Codename One 2017 all rights reserved
So it derives from that and uses the border settings from the floating action button
HistoryLabel
© Codename One 2017 all rights reserved
The history label is the text element below which is technically a text area but acts as a label. The text color for this is black
HistoryLabel
© Codename One 2017 all rights reserved
While the padding is 2 millimeters on all sides except for the top where we want to be as close as possible to the floating action button which is already well padded
HistoryLabel
© Codename One 2017 all rights reserved
Margin is zero as usual
HistoryLabel
© Codename One 2017 all rights reserved
And the font is relatively small at 2.2 millimeters so we can fit multiple rides in the form

More Related Content

Similar to Creating an Uber Clone - Part VII - Transcript.pdf

Creating an Uber Clone - Part XXIII - Transcript.pdf
Creating an Uber Clone - Part XXIII - Transcript.pdfCreating an Uber Clone - Part XXIII - Transcript.pdf
Creating an Uber Clone - Part XXIII - Transcript.pdfShaiAlmog1
 
Creating an Uber Clone - Part XIX - Transcript.pdf
Creating an Uber Clone - Part XIX - Transcript.pdfCreating an Uber Clone - Part XIX - Transcript.pdf
Creating an Uber Clone - Part XIX - Transcript.pdfShaiAlmog1
 
Creating an Uber Clone - Part XXI - Transcript.pdf
Creating an Uber Clone - Part XXI - Transcript.pdfCreating an Uber Clone - Part XXI - Transcript.pdf
Creating an Uber Clone - Part XXI - Transcript.pdfShaiAlmog1
 
Maps - Part 2 - Transcript.pdf
Maps - Part 2 - Transcript.pdfMaps - Part 2 - Transcript.pdf
Maps - Part 2 - Transcript.pdfShaiAlmog1
 
Leaving Flatland: getting started with WebGL
Leaving Flatland: getting started with WebGLLeaving Flatland: getting started with WebGL
Leaving Flatland: getting started with WebGLgerbille
 
Making the Most of Maps in Your Connect IQ Apps - Garmin Connect IQ Developer...
Making the Most of Maps in Your Connect IQ Apps - Garmin Connect IQ Developer...Making the Most of Maps in Your Connect IQ Apps - Garmin Connect IQ Developer...
Making the Most of Maps in Your Connect IQ Apps - Garmin Connect IQ Developer...Richard Süselbeck
 
Useful Tools for Making Video Games - XNA (2008)
Useful Tools for Making Video Games - XNA (2008)Useful Tools for Making Video Games - XNA (2008)
Useful Tools for Making Video Games - XNA (2008)Korhan Bircan
 
Creating an Uber Clone - Part XXI.pdf
Creating an Uber Clone - Part XXI.pdfCreating an Uber Clone - Part XXI.pdf
Creating an Uber Clone - Part XXI.pdfShaiAlmog1
 
Google Street View in Your Apps
Google Street View in Your AppsGoogle Street View in Your Apps
Google Street View in Your AppsCodemotion
 
Mashup caravan android-talks
Mashup caravan android-talksMashup caravan android-talks
Mashup caravan android-talkshonjo2
 
Creating an Uber Clone - Part XXIV - Transcript.pdf
Creating an Uber Clone - Part XXIV - Transcript.pdfCreating an Uber Clone - Part XXIV - Transcript.pdf
Creating an Uber Clone - Part XXIV - Transcript.pdfShaiAlmog1
 
Maps - Part 3.pdf
Maps - Part 3.pdfMaps - Part 3.pdf
Maps - Part 3.pdfShaiAlmog1
 
Creating an Uber Clone - Part XXIII.pdf
Creating an Uber Clone - Part XXIII.pdfCreating an Uber Clone - Part XXIII.pdf
Creating an Uber Clone - Part XXIII.pdfShaiAlmog1
 
Webgl para JavaScripters
Webgl para JavaScriptersWebgl para JavaScripters
Webgl para JavaScriptersgerbille
 
Maps - Part 2.pdf
Maps - Part 2.pdfMaps - Part 2.pdf
Maps - Part 2.pdfShaiAlmog1
 
OpenLayers Feature Frenzy
OpenLayers Feature FrenzyOpenLayers Feature Frenzy
OpenLayers Feature FrenzyAndreas Hocevar
 
write a MATLAB GUI program that implements an ultrasound image viewi.pdf
write a MATLAB GUI program that implements an ultrasound image viewi.pdfwrite a MATLAB GUI program that implements an ultrasound image viewi.pdf
write a MATLAB GUI program that implements an ultrasound image viewi.pdffootstatus
 
Google Maps API - DevFest Karlsruhe
Google Maps API - DevFest Karlsruhe Google Maps API - DevFest Karlsruhe
Google Maps API - DevFest Karlsruhe Martin Kleppe
 
Mini-curso JavaFX Aula3 UFPB
Mini-curso JavaFX Aula3 UFPBMini-curso JavaFX Aula3 UFPB
Mini-curso JavaFX Aula3 UFPBRaphael Marques
 

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

Creating an Uber Clone - Part XXIII - Transcript.pdf
Creating an Uber Clone - Part XXIII - Transcript.pdfCreating an Uber Clone - Part XXIII - Transcript.pdf
Creating an Uber Clone - Part XXIII - Transcript.pdf
 
Creating an Uber Clone - Part XIX - Transcript.pdf
Creating an Uber Clone - Part XIX - Transcript.pdfCreating an Uber Clone - Part XIX - Transcript.pdf
Creating an Uber Clone - Part XIX - Transcript.pdf
 
Creating an Uber Clone - Part XXI - Transcript.pdf
Creating an Uber Clone - Part XXI - Transcript.pdfCreating an Uber Clone - Part XXI - Transcript.pdf
Creating an Uber Clone - Part XXI - Transcript.pdf
 
Maps - Part 2 - Transcript.pdf
Maps - Part 2 - Transcript.pdfMaps - Part 2 - Transcript.pdf
Maps - Part 2 - Transcript.pdf
 
Leaving Flatland: getting started with WebGL
Leaving Flatland: getting started with WebGLLeaving Flatland: getting started with WebGL
Leaving Flatland: getting started with WebGL
 
Google Maps Api
Google Maps ApiGoogle Maps Api
Google Maps Api
 
Making the Most of Maps in Your Connect IQ Apps - Garmin Connect IQ Developer...
Making the Most of Maps in Your Connect IQ Apps - Garmin Connect IQ Developer...Making the Most of Maps in Your Connect IQ Apps - Garmin Connect IQ Developer...
Making the Most of Maps in Your Connect IQ Apps - Garmin Connect IQ Developer...
 
Useful Tools for Making Video Games - XNA (2008)
Useful Tools for Making Video Games - XNA (2008)Useful Tools for Making Video Games - XNA (2008)
Useful Tools for Making Video Games - XNA (2008)
 
Creating an Uber Clone - Part XXI.pdf
Creating an Uber Clone - Part XXI.pdfCreating an Uber Clone - Part XXI.pdf
Creating an Uber Clone - Part XXI.pdf
 
Google Street View in Your Apps
Google Street View in Your AppsGoogle Street View in Your Apps
Google Street View in Your Apps
 
Mashup caravan android-talks
Mashup caravan android-talksMashup caravan android-talks
Mashup caravan android-talks
 
Creating an Uber Clone - Part XXIV - Transcript.pdf
Creating an Uber Clone - Part XXIV - Transcript.pdfCreating an Uber Clone - Part XXIV - Transcript.pdf
Creating an Uber Clone - Part XXIV - Transcript.pdf
 
Maps - Part 3.pdf
Maps - Part 3.pdfMaps - Part 3.pdf
Maps - Part 3.pdf
 
Creating an Uber Clone - Part XXIII.pdf
Creating an Uber Clone - Part XXIII.pdfCreating an Uber Clone - Part XXIII.pdf
Creating an Uber Clone - Part XXIII.pdf
 
Webgl para JavaScripters
Webgl para JavaScriptersWebgl para JavaScripters
Webgl para JavaScripters
 
Maps - Part 2.pdf
Maps - Part 2.pdfMaps - Part 2.pdf
Maps - Part 2.pdf
 
OpenLayers Feature Frenzy
OpenLayers Feature FrenzyOpenLayers Feature Frenzy
OpenLayers Feature Frenzy
 
write a MATLAB GUI program that implements an ultrasound image viewi.pdf
write a MATLAB GUI program that implements an ultrasound image viewi.pdfwrite a MATLAB GUI program that implements an ultrasound image viewi.pdf
write a MATLAB GUI program that implements an ultrasound image viewi.pdf
 
Google Maps API - DevFest Karlsruhe
Google Maps API - DevFest Karlsruhe Google Maps API - DevFest Karlsruhe
Google Maps API - DevFest Karlsruhe
 
Mini-curso JavaFX Aula3 UFPB
Mini-curso JavaFX Aula3 UFPBMini-curso JavaFX Aula3 UFPB
Mini-curso JavaFX Aula3 UFPB
 

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 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 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
 

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 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 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
 

Recently uploaded

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 

Recently uploaded (20)

Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 

Creating an Uber Clone - Part VII - Transcript.pdf

  • 1. Creating an Uber Clone - Part VII In this section we finally get to “the map” UI, I hope you followed the instructions before for configuring the map. If not please follow through with that if things don’t work and if you don’t see the map or it acts funny check out with us in the online support forums. You can also check out the map section in the deep dive into mobile development course which comes bundled. Before we begin we need a class we discussed before in the maps module. The MapLayout, I didn’t change much as left it “as is”. Since it’s already available elsewhere I won’t go into the full discussion here and go right into the form itself.
  • 2. The Map © Codename One 2017 all rights reserved Before we proceed I'd like to highlight some subtle things in this screenshot and discuss what we will and will not do.
  • 3. The Map © Codename One 2017 all rights reserved ✦The hamburger menu button above represents the side menu ✦The "Where to?" field is really a button ✦For now I'll just place one unmoving Taxi and we'll deal with the positioning later on ✦The two icons on the bottom represent historic rides which I'll hardcode for now ✦The bottom notice is something I won't implement within the app I won’t do the side menu right now but I will do it soon… The "Where to?" field is really a button that leads to a different UI. This UI is overlaid on top of the map so it is a part of this Form I’ll position one taxi in a hardcoded location as part of the mockup The icons at the bottom are historic rides, I’ll add two hardcoded historic rides for now I won’t go into the notice at the bottom. It's possible but it would be non-trivial
  • 4. public class MapForm extends Form { private static final String MAP_JS_KEY = "AIza-------"; private Image square; private Image dropShadow; public MapForm() { super(new LayeredLayout()); setScrollableY(false); Display.getInstance().callSeriallyOnIdle(() -> { dropShadow = LoginForm.squareShadow(getDisplayWidth(), 30, convertToPixels(3), 0.40f); }); setTransitionOutAnimator(CommonTransitions.createEmpty()); MapContainer mc = new MapContainer(MAP_JS_KEY); mc.setShowMyLocation(true); add(mc); Container mapLayer = new Container(); mapLayer.setLayout(new MapLayout(mc, mapLayer)); add(mapLayer); Coord telAviv = new Coord(32.072449, 34.778613); mc.zoom(telAviv, mc.getMaxZoom() + 1); Label car = new Label(Resources.getGlobalResources(). getImage("map-vehicle-icon-uberX.png")); car.getAllStyles().setOpacity(140); MapForm Lets jump right into the code. You need the JS key from Google Maps as explained in the map extension page. This must have a filled up value
  • 5. public class MapForm extends Form { private static final String MAP_JS_KEY = "AIza-------"; private Image square; private Image dropShadow; public MapForm() { super(new LayeredLayout()); setScrollableY(false); Display.getInstance().callSeriallyOnIdle(() -> { dropShadow = LoginForm.squareShadow(getDisplayWidth(), 30, convertToPixels(3), 0.40f); }); setTransitionOutAnimator(CommonTransitions.createEmpty()); MapContainer mc = new MapContainer(MAP_JS_KEY); mc.setShowMyLocation(true); add(mc); Container mapLayer = new Container(); mapLayer.setLayout(new MapLayout(mc, mapLayer)); add(mapLayer); Coord telAviv = new Coord(32.072449, 34.778613); mc.zoom(telAviv, mc.getMaxZoom() + 1); Label car = new Label(Resources.getGlobalResources(). getImage("map-vehicle-icon-uberX.png")); car.getAllStyles().setOpacity(140); MapForm We usually use BorderLayout which implicitly disables scrollability. LayeredLayout doesn't do that and the forms content pane is scrollable on the Y-axis by default
  • 6. public class MapForm extends Form { private static final String MAP_JS_KEY = "AIza-------"; private Image square; private Image dropShadow; public MapForm() { super(new LayeredLayout()); setScrollableY(false); Display.getInstance().callSeriallyOnIdle(() -> { dropShadow = LoginForm.squareShadow(getDisplayWidth(), 30, convertToPixels(3), 0.40f); }); setTransitionOutAnimator(CommonTransitions.createEmpty()); MapContainer mc = new MapContainer(MAP_JS_KEY); mc.setShowMyLocation(true); add(mc); Container mapLayer = new Container(); mapLayer.setLayout(new MapLayout(mc, mapLayer)); add(mapLayer); Coord telAviv = new Coord(32.072449, 34.778613); mc.zoom(telAviv, mc.getMaxZoom() + 1); Label car = new Label(Resources.getGlobalResources(). getImage("map-vehicle-icon-uberX.png")); car.getAllStyles().setOpacity(140); MapForm Notice we didn't use a thread here and instead used the callSeriallyOnIdle method. On the login Form I didn't use that because the animation might have prevented idle from occurring. This shadow is used later on in the showNavigationToolbar method
  • 7. public class MapForm extends Form { private static final String MAP_JS_KEY = "AIza-------"; private Image square; private Image dropShadow; public MapForm() { super(new LayeredLayout()); setScrollableY(false); Display.getInstance().callSeriallyOnIdle(() -> { dropShadow = LoginForm.squareShadow(getDisplayWidth(), 30, convertToPixels(3), 0.40f); }); setTransitionOutAnimator(CommonTransitions.createEmpty()); MapContainer mc = new MapContainer(MAP_JS_KEY); mc.setShowMyLocation(true); add(mc); Container mapLayer = new Container(); mapLayer.setLayout(new MapLayout(mc, mapLayer)); add(mapLayer); Coord telAviv = new Coord(32.072449, 34.778613); mc.zoom(telAviv, mc.getMaxZoom() + 1); Label car = new Label(Resources.getGlobalResources(). getImage("map-vehicle-icon-uberX.png")); car.getAllStyles().setOpacity(140); MapForm The transitions in the main application are based on cover and the transition out will only be a problem
  • 8. public class MapForm extends Form { private static final String MAP_JS_KEY = "AIza-------"; private Image square; private Image dropShadow; public MapForm() { super(new LayeredLayout()); setScrollableY(false); Display.getInstance().callSeriallyOnIdle(() -> { dropShadow = LoginForm.squareShadow(getDisplayWidth(), 30, convertToPixels(3), 0.40f); }); setTransitionOutAnimator(CommonTransitions.createEmpty()); MapContainer mc = new MapContainer(MAP_JS_KEY); mc.setShowMyLocation(true); add(mc); Container mapLayer = new Container(); mapLayer.setLayout(new MapLayout(mc, mapLayer)); add(mapLayer); Coord telAviv = new Coord(32.072449, 34.778613); mc.zoom(telAviv, mc.getMaxZoom() + 1); Label car = new Label(Resources.getGlobalResources(). getImage("map-vehicle-icon-uberX.png")); car.getAllStyles().setOpacity(140); MapForm The map is on the lowest layer and everything is placed on top of it
  • 9. public class MapForm extends Form { private static final String MAP_JS_KEY = "AIza-------"; private Image square; private Image dropShadow; public MapForm() { super(new LayeredLayout()); setScrollableY(false); Display.getInstance().callSeriallyOnIdle(() -> { dropShadow = LoginForm.squareShadow(getDisplayWidth(), 30, convertToPixels(3), 0.40f); }); setTransitionOutAnimator(CommonTransitions.createEmpty()); MapContainer mc = new MapContainer(MAP_JS_KEY); mc.setShowMyLocation(true); add(mc); Container mapLayer = new Container(); mapLayer.setLayout(new MapLayout(mc, mapLayer)); add(mapLayer); Coord telAviv = new Coord(32.072449, 34.778613); mc.zoom(telAviv, mc.getMaxZoom() + 1); Label car = new Label(Resources.getGlobalResources(). getImage("map-vehicle-icon-uberX.png")); car.getAllStyles().setOpacity(140); MapForm This layer is on top of the map and uses the MapLayout. Here we will place the car and other landmarks we need
  • 10. mapLayer.setLayout(new MapLayout(mc, mapLayer)); add(mapLayer); Coord telAviv = new Coord(32.072449, 34.778613); mc.zoom(telAviv, mc.getMaxZoom() + 1); Label car = new Label(Resources.getGlobalResources(). getImage("map-vehicle-icon-uberX.png")); car.getAllStyles().setOpacity(140); mapLayer.add(telAviv, car); square = Image.createImage(convertToPixels(0.7f), convertToPixels(0.7f), 0xff000000); Button whereTo = new Button("Where To?", square, "WhereTo"); whereTo.setGap(convertToPixels(3)); add(BoxLayout.encloseY(whereTo)); FloatingActionButton history1 = FloatingActionButton.createFAB( FontImage.MATERIAL_HISTORY, "History"); FloatingActionButton history2 = FloatingActionButton.createFAB( FontImage.MATERIAL_HISTORY, "History"); TextArea history1Label = new TextArea("Mikve Yisrael Str...", 3, 4); TextArea history2Label = new TextArea("Burgeranch", 3, 4); history1Label.setUIID("HistoryLabel"); history2Label.setUIID("HistoryLabel"); history1Label.setEditable(false); MapForm I place a car on top of the map in Tel Aviv. Notice that the car is just a label... I've set the opacity to 140 to match the translucent cars in the native app. Notice that the `MapLayout` takes a `Coord` as a constraint so it can properly position the car…
  • 11. mapLayer.setLayout(new MapLayout(mc, mapLayer)); add(mapLayer); Coord telAviv = new Coord(32.072449, 34.778613); mc.zoom(telAviv, mc.getMaxZoom() + 1); Label car = new Label(Resources.getGlobalResources(). getImage("map-vehicle-icon-uberX.png")); car.getAllStyles().setOpacity(140); mapLayer.add(telAviv, car); square = Image.createImage(convertToPixels(0.7f), convertToPixels(0.7f), 0xff000000); Button whereTo = new Button("Where To?", square, "WhereTo"); whereTo.setGap(convertToPixels(3)); add(BoxLayout.encloseY(whereTo)); FloatingActionButton history1 = FloatingActionButton.createFAB( FontImage.MATERIAL_HISTORY, "History"); FloatingActionButton history2 = FloatingActionButton.createFAB( FontImage.MATERIAL_HISTORY, "History"); TextArea history1Label = new TextArea("Mikve Yisrael Str...", 3, 4); TextArea history2Label = new TextArea("Burgeranch", 3, 4); history1Label.setUIID("HistoryLabel"); history2Label.setUIID("HistoryLabel"); history1Label.setEditable(false); MapForm This is the small square we place next to the "Where to?" button. I could have used a unicode value too but it wasn't available in all the fonts. Notice the "Where to?" element is just a button as it moves us to a separate UI and isn't really a TextField
  • 12. whereTo.setGap(convertToPixels(3)); add(BoxLayout.encloseY(whereTo)); FloatingActionButton history1 = FloatingActionButton.createFAB( FontImage.MATERIAL_HISTORY, "History"); FloatingActionButton history2 = FloatingActionButton.createFAB( FontImage.MATERIAL_HISTORY, "History"); TextArea history1Label = new TextArea("Mikve Yisrael Str...", 3, 4); TextArea history2Label = new TextArea("Burgeranch", 3, 4); history1Label.setUIID("HistoryLabel"); history2Label.setUIID("HistoryLabel"); history1Label.setEditable(false); history1Label.setGrowByContent(false); history2Label.setEditable(false); history2Label.setGrowByContent(false); Container h1 = BoxLayout.encloseY(history1, history1Label); Container h2 = BoxLayout.encloseY(history2, history2Label); h1.setLeadComponent(history1); h2.setLeadComponent(history2); ScaleImageLabel gradient = new ScaleImageLabel(Resources. getGlobalResources().getImage("gradient-overlay.png")); gradient.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); add(BorderLayout.south(gradient)); MapForm The history buttons are FloatingActionButton instances that are customized in terms of styling. I used TextArea instead of SpanLabel because I wanted the history element to act as a single component with lead component. Lead components can take over a hierarchy of several components and handle the events for everyone so in this case a click on the text area below the history will trigger an event in the FloatingActionButton
  • 13. whereTo.setGap(convertToPixels(3)); add(BoxLayout.encloseY(whereTo)); FloatingActionButton history1 = FloatingActionButton.createFAB( FontImage.MATERIAL_HISTORY, "History"); FloatingActionButton history2 = FloatingActionButton.createFAB( FontImage.MATERIAL_HISTORY, "History"); TextArea history1Label = new TextArea("Mikve Yisrael Str...", 3, 4); TextArea history2Label = new TextArea("Burgeranch", 3, 4); history1Label.setUIID("HistoryLabel"); history2Label.setUIID("HistoryLabel"); history1Label.setEditable(false); history1Label.setGrowByContent(false); history2Label.setEditable(false); history2Label.setGrowByContent(false); Container h1 = BoxLayout.encloseY(history1, history1Label); Container h2 = BoxLayout.encloseY(history2, history2Label); h1.setLeadComponent(history1); h2.setLeadComponent(history2); ScaleImageLabel gradient = new ScaleImageLabel(Resources. getGlobalResources().getImage("gradient-overlay.png")); gradient.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); add(BorderLayout.south(gradient)); MapForm The bottom of the map has a gradient overlay that darkens the bottom. This is probably in place to make the history labels readable. I just generated a gradient image in photoshop and placed it there
  • 14. history1Label.setUIID("HistoryLabel"); history2Label.setUIID("HistoryLabel"); history1Label.setEditable(false); history1Label.setGrowByContent(false); history2Label.setEditable(false); history2Label.setGrowByContent(false); Container h1 = BoxLayout.encloseY(history1, history1Label); Container h2 = BoxLayout.encloseY(history2, history2Label); h1.setLeadComponent(history1); h2.setLeadComponent(history2); ScaleImageLabel gradient = new ScaleImageLabel(Resources. getGlobalResources().getImage("gradient-overlay.png")); gradient.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); add(BorderLayout.south(gradient)); add(BorderLayout.south(FlowLayout.encloseCenter(h1, h2))); } @Override protected void initGlobalToolbar() { setToolbar(new Toolbar(true)); CommonCode.constructSideMenu(getToolbar()); } } MapForm We do two important things here... We use the overlay toolbar which "floats" on top of the UI. We initialize the side menu which we will discuss soon… That was a lot to cover but there is a lot more... We did mention 3 new styles above which isn't that much all things considered.
  • 15. WhereTo © Codename One 2017 all rights reserved The WhereTo style has some subtle nuances such as dark gray text
  • 16. WhereTo © Codename One 2017 all rights reserved The padding is large and obvious, I played with it a bit to get it right
  • 17. WhereTo © Codename One 2017 all rights reserved The margin is special, we want some margin from the sides so it won’t touch them. We need a lot of margin from the top to leave room for the title area
  • 18. WhereTo © Codename One 2017 all rights reserved The corners are rounded on the native widget, this is very subtle so I left it at 0.3 millimeters which should be very easy. It also has a shadow which is more obvious and 80 opacity
  • 19. WhereTo © Codename One 2017 all rights reserved The font isn’t big just slightly bigger than normal but the typical light font
  • 20. History © Codename One 2017 all rights reserved The History button is the round button on the bottom of the map leading to historic rides. It’s black on white but is implemented as a floating action button
  • 21. HistoryLabel © Codename One 2017 all rights reserved So it derives from that and uses the border settings from the floating action button
  • 22. HistoryLabel © Codename One 2017 all rights reserved The history label is the text element below which is technically a text area but acts as a label. The text color for this is black
  • 23. HistoryLabel © Codename One 2017 all rights reserved While the padding is 2 millimeters on all sides except for the top where we want to be as close as possible to the floating action button which is already well padded
  • 24. HistoryLabel © Codename One 2017 all rights reserved Margin is zero as usual
  • 25. HistoryLabel © Codename One 2017 all rights reserved And the font is relatively small at 2.2 millimeters so we can fit multiple rides in the form