SlideShare a Scribd company logo
1 of 22
Download to read offline
Creating a Facebook Clone - Part XIII
The hardest part in the mockup is behind us. The next stage is the FriendsContainer which lists friend requests and potential friend suggestions.
© Codename One 2017 all rights reserved
The friends container is a simple UI & a simple class. We have a few UIID’s within this class that I’ll cover soon when I get to the CSS related changes
public class FriendsContainer extends Container {
public FriendsContainer() {
super(BoxLayout.y());
setScrollableY(true);
init();
addPullToRefresh(() -> {
removeAll();
init();
revalidate();
});
}
private void init() {
int friendCount = ServerAPI.me().friendRequests.size();
int imageSize = convertToPixels(18);
EncodedImage placeholder = EncodedImage.createFromImage(
Image.createImage(imageSize, imageSize), false);
add(createTitle("FRIEND REQUESTS", friendCount));
if(friendCount == 0) {
Container padded = new Container(new BorderLayout(),
FriendsContainer
Lets look at the code…

We extend Container instead of InfiniteContainer as we don’t need it in this case. Technically I could have gone with an infinite approach but I wanted to keep things
simple
public class FriendsContainer extends Container {
public FriendsContainer() {
super(BoxLayout.y());
setScrollableY(true);
init();
addPullToRefresh(() -> {
removeAll();
init();
revalidate();
});
}
private void init() {
int friendCount = ServerAPI.me().friendRequests.size();
int imageSize = convertToPixels(18);
EncodedImage placeholder = EncodedImage.createFromImage(
Image.createImage(imageSize, imageSize), false);
add(createTitle("FRIEND REQUESTS", friendCount));
if(friendCount == 0) {
Container padded = new Container(new BorderLayout(),
FriendsContainer
The Container arranges elements vertically using box layout, since this isn’t a form it's not scrollable by default so we need to enable scrollability because the parent form
isn't scrollable.
public class FriendsContainer extends Container {
public FriendsContainer() {
super(BoxLayout.y());
setScrollableY(true);
init();
addPullToRefresh(() -> {
removeAll();
init();
revalidate();
});
}
private void init() {
int friendCount = ServerAPI.me().friendRequests.size();
int imageSize = convertToPixels(18);
EncodedImage placeholder = EncodedImage.createFromImage(
Image.createImage(imageSize, imageSize), false);
add(createTitle("FRIEND REQUESTS", friendCount));
if(friendCount == 0) {
Container padded = new Container(new BorderLayout(),
FriendsContainer
addPullToRefresh removes the elements and re-creates the UI
revalidate();
});
}
private void init() {
int friendCount = ServerAPI.me().friendRequests.size();
int imageSize = convertToPixels(18);
EncodedImage placeholder = EncodedImage.createFromImage(
Image.createImage(imageSize, imageSize), false);
add(createTitle("FRIEND REQUESTS", friendCount));
if(friendCount == 0) {
Container padded = new Container(new BorderLayout(),
"PaddedContainer");
padded.add(CENTER,
new Label("No new Friend Requests", "CenterLabel"));
} else {
for(User u : ServerAPI.me().friendRequests) {
Image i = URLImage.createCachedImage(u.id.get() +
"-avatar.jpg",
u.avatar.get(), placeholder,
URLImage.FLAG_RESIZE_SCALE_TO_FILL);
add(friendRequestEntry(u, i, true));
add(UIUtils.createHalfSpace());
FriendsContainer
init() fills up the Container. It's invoked when the class is created or refreshed
revalidate();
});
}
private void init() {
int friendCount = ServerAPI.me().friendRequests.size();
int imageSize = convertToPixels(18);
EncodedImage placeholder = EncodedImage.createFromImage(
Image.createImage(imageSize, imageSize), false);
add(createTitle("FRIEND REQUESTS", friendCount));
if(friendCount == 0) {
Container padded = new Container(new BorderLayout(),
"PaddedContainer");
padded.add(CENTER,
new Label("No new Friend Requests", "CenterLabel"));
} else {
for(User u : ServerAPI.me().friendRequests) {
Image i = URLImage.createCachedImage(u.id.get() +
"-avatar.jpg",
u.avatar.get(), placeholder,
URLImage.FLAG_RESIZE_SCALE_TO_FILL);
add(friendRequestEntry(u, i, true));
add(UIUtils.createHalfSpace());
FriendsContainer
The avatar in the side of the friend appears as an 18 millimeter image
revalidate();
});
}
private void init() {
int friendCount = ServerAPI.me().friendRequests.size();
int imageSize = convertToPixels(18);
EncodedImage placeholder = EncodedImage.createFromImage(
Image.createImage(imageSize, imageSize), false);
add(createTitle("FRIEND REQUESTS", friendCount));
if(friendCount == 0) {
Container padded = new Container(new BorderLayout(),
"PaddedContainer");
padded.add(CENTER,
new Label("No new Friend Requests", "CenterLabel"));
} else {
for(User u : ServerAPI.me().friendRequests) {
Image i = URLImage.createCachedImage(u.id.get() +
"-avatar.jpg",
u.avatar.get(), placeholder,
URLImage.FLAG_RESIZE_SCALE_TO_FILL);
add(friendRequestEntry(u, i, true));
add(UIUtils.createHalfSpace());
FriendsContainer
We use a blank image as the placeholder for the URLImage so the avatar will download dynamically to the locale cache
int imageSize = convertToPixels(18);
EncodedImage placeholder = EncodedImage.createFromImage(
Image.createImage(imageSize, imageSize), false);
add(createTitle("FRIEND REQUESTS", friendCount));
if(friendCount == 0) {
Container padded = new Container(new BorderLayout(),
"PaddedContainer");
padded.add(CENTER,
new Label("No new Friend Requests", "CenterLabel"));
} else {
for(User u : ServerAPI.me().friendRequests) {
Image i = URLImage.createCachedImage(u.id.get() +
"-avatar.jpg",
u.avatar.get(), placeholder,
URLImage.FLAG_RESIZE_SCALE_TO_FILL);
add(friendRequestEntry(u, i, true));
add(UIUtils.createHalfSpace());
}
}
add(UIUtils.createHalfSpace());
add(createTitle("PEOPLE YOU MAY KNOW", 0));
for(User u : ServerAPI.me().peopleYouMayKnow) {
FriendsContainer
If we have friend suggestions we loop over friend requests and add them with the avatar for each one. Notice we used the URLImage.createCachedImage() API to fetch
the avatar URL instead of getAvatar(). Facebook used square images here so it made sense to use something else for this functionality.
padded.add(CENTER,
new Label("No new Friend Requests", "CenterLabel"));
} else {
for(User u : ServerAPI.me().friendRequests) {
Image i = URLImage.createCachedImage(u.id.get() +
"-avatar.jpg",
u.avatar.get(), placeholder,
URLImage.FLAG_RESIZE_SCALE_TO_FILL);
add(friendRequestEntry(u, i, true));
add(UIUtils.createHalfSpace());
}
}
add(UIUtils.createHalfSpace());
add(createTitle("PEOPLE YOU MAY KNOW", 0));
for(User u : ServerAPI.me().peopleYouMayKnow) {
Image i = URLImage.createCachedImage(u.id.get() + "-avatar.jpg",
u.avatar.get(), placeholder,
URLImage.FLAG_RESIZE_SCALE_TO_FILL);
add(friendRequestEntry(u, i, false));
add(UIUtils.createHalfSpace());
}
}
private Container friendRequestEntry(User u, Image avatar,
FriendsContainer
We do the same for the friend suggestion list under a different title
add(friendRequestEntry(u, i, false));
add(UIUtils.createHalfSpace());
}
}
private Container friendRequestEntry(User u, Image avatar,
boolean request) {
Label name = new Label(u.fullName(), "FriendName");
Button confirm;
Button delete;
if(request) {
confirm = new Button("Confirm", "FriendConfirm");
delete = new Button("Delete", "FriendDelete");
} else {
confirm = new Button("Add Friend", "FriendConfirm");
delete = new Button("Remove", "FriendDelete");
}
Container cnt =
BoxLayout.encloseY(name,
GridLayout.encloseIn(2, confirm, delete));
cnt.setUIID("PaddedContainer");
return BorderLayout.centerEastWest(cnt, null,
new Label(avatar, "Container"));
}
FriendsContainer
Next we have the friendRequestEntry method…
add(friendRequestEntry(u, i, false));
add(UIUtils.createHalfSpace());
}
}
private Container friendRequestEntry(User u, Image avatar,
boolean request) {
Label name = new Label(u.fullName(), "FriendName");
Button confirm;
Button delete;
if(request) {
confirm = new Button("Confirm", "FriendConfirm");
delete = new Button("Delete", "FriendDelete");
} else {
confirm = new Button("Add Friend", "FriendConfirm");
delete = new Button("Remove", "FriendDelete");
}
Container cnt =
BoxLayout.encloseY(name,
GridLayout.encloseIn(2, confirm, delete));
cnt.setUIID("PaddedContainer");
return BorderLayout.centerEastWest(cnt, null,
new Label(avatar, "Container"));
}
FriendsContainer
We create the button labels based on the type of request
add(friendRequestEntry(u, i, false));
add(UIUtils.createHalfSpace());
}
}
private Container friendRequestEntry(User u, Image avatar,
boolean request) {
Label name = new Label(u.fullName(), "FriendName");
Button confirm;
Button delete;
if(request) {
confirm = new Button("Confirm", "FriendConfirm");
delete = new Button("Delete", "FriendDelete");
} else {
confirm = new Button("Add Friend", "FriendConfirm");
delete = new Button("Remove", "FriendDelete");
}
Container cnt =
BoxLayout.encloseY(name,
GridLayout.encloseIn(2, confirm, delete));
cnt.setUIID("PaddedContainer");
return BorderLayout.centerEastWest(cnt, null,
new Label(avatar, "Container"));
}
FriendsContainer
We place the name above the buttons using a box layout on the Y axis then place the two buttons within a grid layout giving them the same size
add(friendRequestEntry(u, i, false));
add(UIUtils.createHalfSpace());
}
}
private Container friendRequestEntry(User u, Image avatar,
boolean request) {
Label name = new Label(u.fullName(), "FriendName");
Button confirm;
Button delete;
if(request) {
confirm = new Button("Confirm", "FriendConfirm");
delete = new Button("Delete", "FriendDelete");
} else {
confirm = new Button("Add Friend", "FriendConfirm");
delete = new Button("Remove", "FriendDelete");
}
Container cnt =
BoxLayout.encloseY(name,
GridLayout.encloseIn(2, confirm, delete));
cnt.setUIID("PaddedContainer");
return BorderLayout.centerEastWest(cnt, null,
new Label(avatar, "Container"));
}
FriendsContainer
The avatar is placed in the west since its size is constant, we place the content in the center which gives it space to grow
Button delete;
if(request) {
confirm = new Button("Confirm", "FriendConfirm");
delete = new Button("Delete", "FriendDelete");
} else {
confirm = new Button("Add Friend", "FriendConfirm");
delete = new Button("Remove", "FriendDelete");
}
Container cnt =
BoxLayout.encloseY(name,
GridLayout.encloseIn(2, confirm, delete));
cnt.setUIID("PaddedContainer");
return BorderLayout.centerEastWest(cnt, null,
new Label(avatar, "Container"));
}
private Component createTitle(String title, int count) {
Label titleLabel = new Label(title, "FriendSubtitle");
if(count > 0) {
Label countLabel = new Label("" + count, "SmallRedCircle");
return FlowLayout.encloseMiddle(titleLabel, countLabel);
}
return titleLabel;
}
}
FriendsContainer
The titles above the listings are created in the init() method with this code block
Button delete;
if(request) {
confirm = new Button("Confirm", "FriendConfirm");
delete = new Button("Delete", "FriendDelete");
} else {
confirm = new Button("Add Friend", "FriendConfirm");
delete = new Button("Remove", "FriendDelete");
}
Container cnt =
BoxLayout.encloseY(name,
GridLayout.encloseIn(2, confirm, delete));
cnt.setUIID("PaddedContainer");
return BorderLayout.centerEastWest(cnt, null,
new Label(avatar, "Container"));
}
private Component createTitle(String title, int count) {
Label titleLabel = new Label(title, "FriendSubtitle");
if(count > 0) {
Label countLabel = new Label("" + count, "SmallRedCircle");
return FlowLayout.encloseMiddle(titleLabel, countLabel);
}
return titleLabel;
}
}
FriendsContainer
This handles the red circle with the number next to the title
© Codename One 2017 all rights reserved
In order to complete this we need a few CSS changes
FriendSubtitle {
color: #999999;
font-size: 3mm;
font-family: "native:MainRegular";
padding: 1.5mm;
}
SmallRedCircle {
border: cn1-round-border;
background-color: red;
padding: 1mm;
margin: 1mm;
color: white;
font-family: "native:MainRegular";
font-size: 2.2mm;
}
FriendName {
color: black;
font-size: 3mm;
font-family: "native:MainLight";
}
FriendConfirm {
padding: 2mm;
theme.css
In order to complete this we need a few CSS changes. 

The subtitle is just a gray slightly larger font
FriendSubtitle {
color: #999999;
font-size: 3mm;
font-family: "native:MainRegular";
padding: 1.5mm;
}
SmallRedCircle {
border: cn1-round-border;
background-color: red;
padding: 1mm;
margin: 1mm;
color: white;
font-family: "native:MainRegular";
font-size: 2.2mm;
}
FriendName {
color: black;
font-size: 3mm;
font-family: "native:MainLight";
}
FriendConfirm {
padding: 2mm;
theme.css
The red circle has padding that is large enough to make it visible. The size is close enough so it will align reasonably with the FriendSubtitle
SmallRedCircle {
border: cn1-round-border;
background-color: red;
padding: 1mm;
margin: 1mm;
color: white;
font-family: "native:MainRegular";
font-size: 2.2mm;
}
FriendName {
color: black;
font-size: 3mm;
font-family: "native:MainLight";
}
FriendConfirm {
padding: 2mm;
margin: 1mm;
border-radius: 1mm;
background: #587EBE;
font-family: "native:MainLight";
cn1-derive: BaseButton;
font-size: 2mm;
}
FriendDelete {
background: white;
theme.css
FriendName looks smaller than FriendSubtitle but it's really because FriendSubtitle is written in uppercase
font-family: "native:MainRegular";
font-size: 2.2mm;
}
FriendName {
color: black;
font-size: 3mm;
font-family: "native:MainLight";
}
FriendConfirm {
padding: 2mm;
margin: 1mm;
border-radius: 1mm;
background: #587EBE;
font-family: "native:MainLight";
cn1-derive: BaseButton;
font-size: 2mm;
}
FriendDelete {
background: white;
border-color: #999999;
border-width: 1px;
color: #999999;
cn1-derive: FriendConfirm;
}
theme.css
The confirm button is a standard button with rounded corners and a specific background
font-family: "native:MainRegular";
font-size: 2.2mm;
}
FriendName {
color: black;
font-size: 3mm;
font-family: "native:MainLight";
}
FriendConfirm {
padding: 2mm;
margin: 1mm;
border-radius: 1mm;
background: #587EBE;
font-family: "native:MainLight";
cn1-derive: BaseButton;
font-size: 2mm;
}
FriendDelete {
background: white;
border-color: #999999;
border-width: 1px;
color: #999999;
cn1-derive: FriendConfirm;
}
theme.css
The delete button removes the background and adds a pixel wide border around it. With that the friend suggestion UI should work and run as expected.

More Related Content

Similar to Creating a Facebook Clone - Part XIII - Transcript.pdf

Creating a Facebook Clone - Part XXVIII.pdf
Creating a Facebook Clone - Part XXVIII.pdfCreating a Facebook Clone - Part XXVIII.pdf
Creating a Facebook Clone - Part XXVIII.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 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
 
Initial UI Mockup - Part 3.pdf
Initial UI Mockup - Part 3.pdfInitial UI Mockup - Part 3.pdf
Initial UI Mockup - Part 3.pdfShaiAlmog1
 
i need a remove button to remove the image from my favourites- however.pdf
i need a remove button to remove the image from my favourites- however.pdfi need a remove button to remove the image from my favourites- however.pdf
i need a remove button to remove the image from my favourites- however.pdfshreeaadithyaacellso
 
Creating a Facebook Clone - Part XLI.pdf
Creating a Facebook Clone - Part XLI.pdfCreating a Facebook Clone - Part XLI.pdf
Creating a Facebook Clone - Part XLI.pdfShaiAlmog1
 
UI Design From Scratch - Part 5 - transcript.pdf
UI Design From Scratch - Part 5 - transcript.pdfUI Design From Scratch - Part 5 - transcript.pdf
UI Design From Scratch - Part 5 - transcript.pdfShaiAlmog1
 
Creating an Uber Clone - Part XXII.pdf
Creating an Uber Clone - Part XXII.pdfCreating an Uber Clone - Part XXII.pdf
Creating an Uber Clone - Part XXII.pdfShaiAlmog1
 
Creating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdfCreating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdfShaiAlmog1
 
Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of usOSCON Byrum
 
Creating a Facebook Clone - Part X - Transcript.pdf
Creating a Facebook Clone - Part X - Transcript.pdfCreating a Facebook Clone - Part X - Transcript.pdf
Creating a Facebook Clone - Part X - Transcript.pdfShaiAlmog1
 
Why am I getting an out of memory error and no window of my .pdf
Why am I getting an out of memory error and no window of my .pdfWhy am I getting an out of memory error and no window of my .pdf
Why am I getting an out of memory error and no window of my .pdfaakarcreations1
 
Creating a Facebook Clone - Part XXIX - Transcript.pdf
Creating a Facebook Clone - Part XXIX - Transcript.pdfCreating a Facebook Clone - Part XXIX - Transcript.pdf
Creating a Facebook Clone - Part XXIX - Transcript.pdfShaiAlmog1
 
i am unsure how to make the button below the image instead of on it- a.pdf
i am unsure how to make the button below the image instead of on it- a.pdfi am unsure how to make the button below the image instead of on it- a.pdf
i am unsure how to make the button below the image instead of on it- a.pdfMattU5mLambertq
 
Creating a Facebook Clone - Part XXXVII.pdf
Creating a Facebook Clone - Part XXXVII.pdfCreating a Facebook Clone - Part XXXVII.pdf
Creating a Facebook Clone - Part XXXVII.pdfShaiAlmog1
 
Android Studio (Java)The SimplePaint app (full code given below).docx
Android Studio (Java)The SimplePaint app (full code given below).docxAndroid Studio (Java)The SimplePaint app (full code given below).docx
Android Studio (Java)The SimplePaint app (full code given below).docxamrit47
 
Creating custom views
Creating custom viewsCreating custom views
Creating custom viewsMu Chun Wang
 
Making Games in JavaScript
Making Games in JavaScriptMaking Games in JavaScript
Making Games in JavaScriptSam Cartwright
 

Similar to Creating a Facebook Clone - Part XIII - Transcript.pdf (20)

Creating a Facebook Clone - Part XXVIII.pdf
Creating a Facebook Clone - Part XXVIII.pdfCreating a Facebook Clone - Part XXVIII.pdf
Creating a Facebook Clone - Part XXVIII.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 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
 
Initial UI Mockup - Part 3.pdf
Initial UI Mockup - Part 3.pdfInitial UI Mockup - Part 3.pdf
Initial UI Mockup - Part 3.pdf
 
i need a remove button to remove the image from my favourites- however.pdf
i need a remove button to remove the image from my favourites- however.pdfi need a remove button to remove the image from my favourites- however.pdf
i need a remove button to remove the image from my favourites- however.pdf
 
Creating a Facebook Clone - Part XLI.pdf
Creating a Facebook Clone - Part XLI.pdfCreating a Facebook Clone - Part XLI.pdf
Creating a Facebook Clone - Part XLI.pdf
 
UI Design From Scratch - Part 5 - transcript.pdf
UI Design From Scratch - Part 5 - transcript.pdfUI Design From Scratch - Part 5 - transcript.pdf
UI Design From Scratch - Part 5 - transcript.pdf
 
Creating an Uber Clone - Part XXII.pdf
Creating an Uber Clone - Part XXII.pdfCreating an Uber Clone - Part XXII.pdf
Creating an Uber Clone - Part XXII.pdf
 
Vaadin7
Vaadin7Vaadin7
Vaadin7
 
Creating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdfCreating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdf
 
Big Data for each one of us
Big Data for each one of usBig Data for each one of us
Big Data for each one of us
 
Creating a Facebook Clone - Part X - Transcript.pdf
Creating a Facebook Clone - Part X - Transcript.pdfCreating a Facebook Clone - Part X - Transcript.pdf
Creating a Facebook Clone - Part X - Transcript.pdf
 
Why am I getting an out of memory error and no window of my .pdf
Why am I getting an out of memory error and no window of my .pdfWhy am I getting an out of memory error and no window of my .pdf
Why am I getting an out of memory error and no window of my .pdf
 
Creating a Facebook Clone - Part XXIX - Transcript.pdf
Creating a Facebook Clone - Part XXIX - Transcript.pdfCreating a Facebook Clone - Part XXIX - Transcript.pdf
Creating a Facebook Clone - Part XXIX - Transcript.pdf
 
i am unsure how to make the button below the image instead of on it- a.pdf
i am unsure how to make the button below the image instead of on it- a.pdfi am unsure how to make the button below the image instead of on it- a.pdf
i am unsure how to make the button below the image instead of on it- a.pdf
 
Creating a Facebook Clone - Part XXXVII.pdf
Creating a Facebook Clone - Part XXXVII.pdfCreating a Facebook Clone - Part XXXVII.pdf
Creating a Facebook Clone - Part XXXVII.pdf
 
Android Studio (Java)The SimplePaint app (full code given below).docx
Android Studio (Java)The SimplePaint app (full code given below).docxAndroid Studio (Java)The SimplePaint app (full code given below).docx
Android Studio (Java)The SimplePaint app (full code given below).docx
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
Creating custom views
Creating custom viewsCreating custom views
Creating custom views
 
Making Games in JavaScript
Making Games in JavaScriptMaking Games in JavaScript
Making Games in JavaScript
 

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

Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGDSC PJATK
 
ECS 2024 Teams Premium - Pretty Secure
ECS 2024   Teams Premium - Pretty SecureECS 2024   Teams Premium - Pretty Secure
ECS 2024 Teams Premium - Pretty SecureFemke de Vroome
 
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...FIDO Alliance
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlPeter Udo Diehl
 
Oauth 2.0 Introduction and Flows with MuleSoft
Oauth 2.0 Introduction and Flows with MuleSoftOauth 2.0 Introduction and Flows with MuleSoft
Oauth 2.0 Introduction and Flows with MuleSoftshyamraj55
 
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdfHow Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdfFIDO Alliance
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutesconfluent
 
Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge
 
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone KomSalesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone KomCzechDreamin
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Julian Hyde
 
AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101vincent683379
 
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdfSimplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdfFIDO Alliance
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfFIDO Alliance
 
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
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeCzechDreamin
 
Designing for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at ComcastDesigning for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at ComcastUXDXConf
 
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...FIDO Alliance
 
Using IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & IrelandUsing IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & IrelandIES VE
 
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...FIDO Alliance
 
TopCryptoSupers 12thReport OrionX May2024
TopCryptoSupers 12thReport OrionX May2024TopCryptoSupers 12thReport OrionX May2024
TopCryptoSupers 12thReport OrionX May2024Stephen Perrenod
 

Recently uploaded (20)

Google I/O Extended 2024 Warsaw
Google I/O Extended 2024 WarsawGoogle I/O Extended 2024 Warsaw
Google I/O Extended 2024 Warsaw
 
ECS 2024 Teams Premium - Pretty Secure
ECS 2024   Teams Premium - Pretty SecureECS 2024   Teams Premium - Pretty Secure
ECS 2024 Teams Premium - Pretty Secure
 
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
 
Oauth 2.0 Introduction and Flows with MuleSoft
Oauth 2.0 Introduction and Flows with MuleSoftOauth 2.0 Introduction and Flows with MuleSoft
Oauth 2.0 Introduction and Flows with MuleSoft
 
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdfHow Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
How Red Hat Uses FDO in Device Lifecycle _ Costin and Vitaliy at Red Hat.pdf
 
Speed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in MinutesSpeed Wins: From Kafka to APIs in Minutes
Speed Wins: From Kafka to APIs in Minutes
 
Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024Enterprise Knowledge Graphs - Data Summit 2024
Enterprise Knowledge Graphs - Data Summit 2024
 
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone KomSalesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
 
AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101
 
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdfSimplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
 
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
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
 
Designing for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at ComcastDesigning for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at Comcast
 
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
 
Using IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & IrelandUsing IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & Ireland
 
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
 
TopCryptoSupers 12thReport OrionX May2024
TopCryptoSupers 12thReport OrionX May2024TopCryptoSupers 12thReport OrionX May2024
TopCryptoSupers 12thReport OrionX May2024
 

Creating a Facebook Clone - Part XIII - Transcript.pdf

  • 1. Creating a Facebook Clone - Part XIII The hardest part in the mockup is behind us. The next stage is the FriendsContainer which lists friend requests and potential friend suggestions.
  • 2. © Codename One 2017 all rights reserved The friends container is a simple UI & a simple class. We have a few UIID’s within this class that I’ll cover soon when I get to the CSS related changes
  • 3. public class FriendsContainer extends Container { public FriendsContainer() { super(BoxLayout.y()); setScrollableY(true); init(); addPullToRefresh(() -> { removeAll(); init(); revalidate(); }); } private void init() { int friendCount = ServerAPI.me().friendRequests.size(); int imageSize = convertToPixels(18); EncodedImage placeholder = EncodedImage.createFromImage( Image.createImage(imageSize, imageSize), false); add(createTitle("FRIEND REQUESTS", friendCount)); if(friendCount == 0) { Container padded = new Container(new BorderLayout(), FriendsContainer Lets look at the code… We extend Container instead of InfiniteContainer as we don’t need it in this case. Technically I could have gone with an infinite approach but I wanted to keep things simple
  • 4. public class FriendsContainer extends Container { public FriendsContainer() { super(BoxLayout.y()); setScrollableY(true); init(); addPullToRefresh(() -> { removeAll(); init(); revalidate(); }); } private void init() { int friendCount = ServerAPI.me().friendRequests.size(); int imageSize = convertToPixels(18); EncodedImage placeholder = EncodedImage.createFromImage( Image.createImage(imageSize, imageSize), false); add(createTitle("FRIEND REQUESTS", friendCount)); if(friendCount == 0) { Container padded = new Container(new BorderLayout(), FriendsContainer The Container arranges elements vertically using box layout, since this isn’t a form it's not scrollable by default so we need to enable scrollability because the parent form isn't scrollable.
  • 5. public class FriendsContainer extends Container { public FriendsContainer() { super(BoxLayout.y()); setScrollableY(true); init(); addPullToRefresh(() -> { removeAll(); init(); revalidate(); }); } private void init() { int friendCount = ServerAPI.me().friendRequests.size(); int imageSize = convertToPixels(18); EncodedImage placeholder = EncodedImage.createFromImage( Image.createImage(imageSize, imageSize), false); add(createTitle("FRIEND REQUESTS", friendCount)); if(friendCount == 0) { Container padded = new Container(new BorderLayout(), FriendsContainer addPullToRefresh removes the elements and re-creates the UI
  • 6. revalidate(); }); } private void init() { int friendCount = ServerAPI.me().friendRequests.size(); int imageSize = convertToPixels(18); EncodedImage placeholder = EncodedImage.createFromImage( Image.createImage(imageSize, imageSize), false); add(createTitle("FRIEND REQUESTS", friendCount)); if(friendCount == 0) { Container padded = new Container(new BorderLayout(), "PaddedContainer"); padded.add(CENTER, new Label("No new Friend Requests", "CenterLabel")); } else { for(User u : ServerAPI.me().friendRequests) { Image i = URLImage.createCachedImage(u.id.get() + "-avatar.jpg", u.avatar.get(), placeholder, URLImage.FLAG_RESIZE_SCALE_TO_FILL); add(friendRequestEntry(u, i, true)); add(UIUtils.createHalfSpace()); FriendsContainer init() fills up the Container. It's invoked when the class is created or refreshed
  • 7. revalidate(); }); } private void init() { int friendCount = ServerAPI.me().friendRequests.size(); int imageSize = convertToPixels(18); EncodedImage placeholder = EncodedImage.createFromImage( Image.createImage(imageSize, imageSize), false); add(createTitle("FRIEND REQUESTS", friendCount)); if(friendCount == 0) { Container padded = new Container(new BorderLayout(), "PaddedContainer"); padded.add(CENTER, new Label("No new Friend Requests", "CenterLabel")); } else { for(User u : ServerAPI.me().friendRequests) { Image i = URLImage.createCachedImage(u.id.get() + "-avatar.jpg", u.avatar.get(), placeholder, URLImage.FLAG_RESIZE_SCALE_TO_FILL); add(friendRequestEntry(u, i, true)); add(UIUtils.createHalfSpace()); FriendsContainer The avatar in the side of the friend appears as an 18 millimeter image
  • 8. revalidate(); }); } private void init() { int friendCount = ServerAPI.me().friendRequests.size(); int imageSize = convertToPixels(18); EncodedImage placeholder = EncodedImage.createFromImage( Image.createImage(imageSize, imageSize), false); add(createTitle("FRIEND REQUESTS", friendCount)); if(friendCount == 0) { Container padded = new Container(new BorderLayout(), "PaddedContainer"); padded.add(CENTER, new Label("No new Friend Requests", "CenterLabel")); } else { for(User u : ServerAPI.me().friendRequests) { Image i = URLImage.createCachedImage(u.id.get() + "-avatar.jpg", u.avatar.get(), placeholder, URLImage.FLAG_RESIZE_SCALE_TO_FILL); add(friendRequestEntry(u, i, true)); add(UIUtils.createHalfSpace()); FriendsContainer We use a blank image as the placeholder for the URLImage so the avatar will download dynamically to the locale cache
  • 9. int imageSize = convertToPixels(18); EncodedImage placeholder = EncodedImage.createFromImage( Image.createImage(imageSize, imageSize), false); add(createTitle("FRIEND REQUESTS", friendCount)); if(friendCount == 0) { Container padded = new Container(new BorderLayout(), "PaddedContainer"); padded.add(CENTER, new Label("No new Friend Requests", "CenterLabel")); } else { for(User u : ServerAPI.me().friendRequests) { Image i = URLImage.createCachedImage(u.id.get() + "-avatar.jpg", u.avatar.get(), placeholder, URLImage.FLAG_RESIZE_SCALE_TO_FILL); add(friendRequestEntry(u, i, true)); add(UIUtils.createHalfSpace()); } } add(UIUtils.createHalfSpace()); add(createTitle("PEOPLE YOU MAY KNOW", 0)); for(User u : ServerAPI.me().peopleYouMayKnow) { FriendsContainer If we have friend suggestions we loop over friend requests and add them with the avatar for each one. Notice we used the URLImage.createCachedImage() API to fetch the avatar URL instead of getAvatar(). Facebook used square images here so it made sense to use something else for this functionality.
  • 10. padded.add(CENTER, new Label("No new Friend Requests", "CenterLabel")); } else { for(User u : ServerAPI.me().friendRequests) { Image i = URLImage.createCachedImage(u.id.get() + "-avatar.jpg", u.avatar.get(), placeholder, URLImage.FLAG_RESIZE_SCALE_TO_FILL); add(friendRequestEntry(u, i, true)); add(UIUtils.createHalfSpace()); } } add(UIUtils.createHalfSpace()); add(createTitle("PEOPLE YOU MAY KNOW", 0)); for(User u : ServerAPI.me().peopleYouMayKnow) { Image i = URLImage.createCachedImage(u.id.get() + "-avatar.jpg", u.avatar.get(), placeholder, URLImage.FLAG_RESIZE_SCALE_TO_FILL); add(friendRequestEntry(u, i, false)); add(UIUtils.createHalfSpace()); } } private Container friendRequestEntry(User u, Image avatar, FriendsContainer We do the same for the friend suggestion list under a different title
  • 11. add(friendRequestEntry(u, i, false)); add(UIUtils.createHalfSpace()); } } private Container friendRequestEntry(User u, Image avatar, boolean request) { Label name = new Label(u.fullName(), "FriendName"); Button confirm; Button delete; if(request) { confirm = new Button("Confirm", "FriendConfirm"); delete = new Button("Delete", "FriendDelete"); } else { confirm = new Button("Add Friend", "FriendConfirm"); delete = new Button("Remove", "FriendDelete"); } Container cnt = BoxLayout.encloseY(name, GridLayout.encloseIn(2, confirm, delete)); cnt.setUIID("PaddedContainer"); return BorderLayout.centerEastWest(cnt, null, new Label(avatar, "Container")); } FriendsContainer Next we have the friendRequestEntry method…
  • 12. add(friendRequestEntry(u, i, false)); add(UIUtils.createHalfSpace()); } } private Container friendRequestEntry(User u, Image avatar, boolean request) { Label name = new Label(u.fullName(), "FriendName"); Button confirm; Button delete; if(request) { confirm = new Button("Confirm", "FriendConfirm"); delete = new Button("Delete", "FriendDelete"); } else { confirm = new Button("Add Friend", "FriendConfirm"); delete = new Button("Remove", "FriendDelete"); } Container cnt = BoxLayout.encloseY(name, GridLayout.encloseIn(2, confirm, delete)); cnt.setUIID("PaddedContainer"); return BorderLayout.centerEastWest(cnt, null, new Label(avatar, "Container")); } FriendsContainer We create the button labels based on the type of request
  • 13. add(friendRequestEntry(u, i, false)); add(UIUtils.createHalfSpace()); } } private Container friendRequestEntry(User u, Image avatar, boolean request) { Label name = new Label(u.fullName(), "FriendName"); Button confirm; Button delete; if(request) { confirm = new Button("Confirm", "FriendConfirm"); delete = new Button("Delete", "FriendDelete"); } else { confirm = new Button("Add Friend", "FriendConfirm"); delete = new Button("Remove", "FriendDelete"); } Container cnt = BoxLayout.encloseY(name, GridLayout.encloseIn(2, confirm, delete)); cnt.setUIID("PaddedContainer"); return BorderLayout.centerEastWest(cnt, null, new Label(avatar, "Container")); } FriendsContainer We place the name above the buttons using a box layout on the Y axis then place the two buttons within a grid layout giving them the same size
  • 14. add(friendRequestEntry(u, i, false)); add(UIUtils.createHalfSpace()); } } private Container friendRequestEntry(User u, Image avatar, boolean request) { Label name = new Label(u.fullName(), "FriendName"); Button confirm; Button delete; if(request) { confirm = new Button("Confirm", "FriendConfirm"); delete = new Button("Delete", "FriendDelete"); } else { confirm = new Button("Add Friend", "FriendConfirm"); delete = new Button("Remove", "FriendDelete"); } Container cnt = BoxLayout.encloseY(name, GridLayout.encloseIn(2, confirm, delete)); cnt.setUIID("PaddedContainer"); return BorderLayout.centerEastWest(cnt, null, new Label(avatar, "Container")); } FriendsContainer The avatar is placed in the west since its size is constant, we place the content in the center which gives it space to grow
  • 15. Button delete; if(request) { confirm = new Button("Confirm", "FriendConfirm"); delete = new Button("Delete", "FriendDelete"); } else { confirm = new Button("Add Friend", "FriendConfirm"); delete = new Button("Remove", "FriendDelete"); } Container cnt = BoxLayout.encloseY(name, GridLayout.encloseIn(2, confirm, delete)); cnt.setUIID("PaddedContainer"); return BorderLayout.centerEastWest(cnt, null, new Label(avatar, "Container")); } private Component createTitle(String title, int count) { Label titleLabel = new Label(title, "FriendSubtitle"); if(count > 0) { Label countLabel = new Label("" + count, "SmallRedCircle"); return FlowLayout.encloseMiddle(titleLabel, countLabel); } return titleLabel; } } FriendsContainer The titles above the listings are created in the init() method with this code block
  • 16. Button delete; if(request) { confirm = new Button("Confirm", "FriendConfirm"); delete = new Button("Delete", "FriendDelete"); } else { confirm = new Button("Add Friend", "FriendConfirm"); delete = new Button("Remove", "FriendDelete"); } Container cnt = BoxLayout.encloseY(name, GridLayout.encloseIn(2, confirm, delete)); cnt.setUIID("PaddedContainer"); return BorderLayout.centerEastWest(cnt, null, new Label(avatar, "Container")); } private Component createTitle(String title, int count) { Label titleLabel = new Label(title, "FriendSubtitle"); if(count > 0) { Label countLabel = new Label("" + count, "SmallRedCircle"); return FlowLayout.encloseMiddle(titleLabel, countLabel); } return titleLabel; } } FriendsContainer This handles the red circle with the number next to the title
  • 17. © Codename One 2017 all rights reserved In order to complete this we need a few CSS changes
  • 18. FriendSubtitle { color: #999999; font-size: 3mm; font-family: "native:MainRegular"; padding: 1.5mm; } SmallRedCircle { border: cn1-round-border; background-color: red; padding: 1mm; margin: 1mm; color: white; font-family: "native:MainRegular"; font-size: 2.2mm; } FriendName { color: black; font-size: 3mm; font-family: "native:MainLight"; } FriendConfirm { padding: 2mm; theme.css In order to complete this we need a few CSS changes. The subtitle is just a gray slightly larger font
  • 19. FriendSubtitle { color: #999999; font-size: 3mm; font-family: "native:MainRegular"; padding: 1.5mm; } SmallRedCircle { border: cn1-round-border; background-color: red; padding: 1mm; margin: 1mm; color: white; font-family: "native:MainRegular"; font-size: 2.2mm; } FriendName { color: black; font-size: 3mm; font-family: "native:MainLight"; } FriendConfirm { padding: 2mm; theme.css The red circle has padding that is large enough to make it visible. The size is close enough so it will align reasonably with the FriendSubtitle
  • 20. SmallRedCircle { border: cn1-round-border; background-color: red; padding: 1mm; margin: 1mm; color: white; font-family: "native:MainRegular"; font-size: 2.2mm; } FriendName { color: black; font-size: 3mm; font-family: "native:MainLight"; } FriendConfirm { padding: 2mm; margin: 1mm; border-radius: 1mm; background: #587EBE; font-family: "native:MainLight"; cn1-derive: BaseButton; font-size: 2mm; } FriendDelete { background: white; theme.css FriendName looks smaller than FriendSubtitle but it's really because FriendSubtitle is written in uppercase
  • 21. font-family: "native:MainRegular"; font-size: 2.2mm; } FriendName { color: black; font-size: 3mm; font-family: "native:MainLight"; } FriendConfirm { padding: 2mm; margin: 1mm; border-radius: 1mm; background: #587EBE; font-family: "native:MainLight"; cn1-derive: BaseButton; font-size: 2mm; } FriendDelete { background: white; border-color: #999999; border-width: 1px; color: #999999; cn1-derive: FriendConfirm; } theme.css The confirm button is a standard button with rounded corners and a specific background
  • 22. font-family: "native:MainRegular"; font-size: 2.2mm; } FriendName { color: black; font-size: 3mm; font-family: "native:MainLight"; } FriendConfirm { padding: 2mm; margin: 1mm; border-radius: 1mm; background: #587EBE; font-family: "native:MainLight"; cn1-derive: BaseButton; font-size: 2mm; } FriendDelete { background: white; border-color: #999999; border-width: 1px; color: #999999; cn1-derive: FriendConfirm; } theme.css The delete button removes the background and adds a pixel wide border around it. With that the friend suggestion UI should work and run as expected.