We’ve been very busy the past few weeks despite the summer time but August is always problematic, I will personally take some time off from the blog next week and near the end of August. To allow that I want to clear my table from a lot of the features that went into Codename One over the past couple of weeks and didn’t get sufficient or any documentation…
I wrote about some of these features before in the pixel perfect posts but I glossed over them. Some of the other features I didn’t cover at all!
Google Plus is Dead
Even when we wrote the blog posts detailing google plus login we new the end was near for that social network…
Google has pretty much ended support for the old Google+ login API’s and Steve migrated our existing Google+ support to use standard Google account connect. The cool thing is that the integration should now be MUCH easier and can be summed up with:
Follow the steps to create an App
Enable Google Sign-In
Download the google-services.json file into your project’s native/android directory
Download the GoogleService-Info.plist file into your project’s native/ios directory
This is the super short version… Steve updated the developer guide section on Google Cconnect with a longer more detailed explanation of the steps.
This is a pretty big feature, currently the only way you can use this is by compiling your own version of the Codename One Designer but it will be around with plugin update 3.7.3 (we don’t have an ETA for that yet but I hope it won’t be too long).
This essentially means you would be able to use fractions to define padding and margin in the designer UI:
This won’t work for pixels, it will get rounded down. But it should work great for millimeters where 1mm often proved to be too much in newer devices.
The reason we didn’t have that around sooner is that it requires a deep change to the resource file format which is always a painful nuanced process. We bundled this with another big change to the file format…
Rethinking Round Rect
Border in the LWUIT days and it grew very old. The goals it set out to accomplish were radically different from the ones we have today which is why we created
RoundBorder when we needed something more expressive.
RoundBorder works great for round and pill shapes but the classic square with rounded corners is still only available in the
Border class. Normally, this would be enough but there is a lot of nuance we wanted to introduce to that API and a lot that we learned from the
RoundBorder. So we created a new class RoundRectBorder which allows you to create a round border that’s more refined. Here I adapted the original RoundBorder sample to work with
Form hi = new Form("RoundRect", new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER)); Button ok = new Button("OK"); Button cancel = new Button("Cancel"); Label loginLabel = new Label("Login", "Container"); loginLabel.getAllStyles().setAlignment(Component.CENTER); Label passwordLabel = new Label("Password", "Container"); passwordLabel.getAllStyles().setAlignment(Component.CENTER); TextField login = new TextField("", "Login", 20, TextArea.ANY); TextField password = new TextField("", "Password", 20, TextArea.PASSWORD); Style loginStyle = login.getAllStyles(); Stroke borderStroke = new Stroke(2, Stroke.CAP_SQUARE, Stroke.JOIN_MITER, 1); loginStyle.setBorder(RoundRectBorder.create(). strokeColor(0). strokeOpacity(120). stroke(borderStroke)); loginStyle.setBgColor(0xffffff); loginStyle.setBgTransparency(255); loginStyle.setMarginUnit(Style.UNIT_TYPE_DIPS); loginStyle.setMargin(Component.BOTTOM, 3); Style passwordStyle = password.getAllStyles(); passwordStyle.setBorder(RoundRectBorder.create(). strokeColor(0). strokeOpacity(120). stroke(borderStroke)); passwordStyle.setBgColor(0xffffff); passwordStyle.setBgTransparency(255); Container box = BoxLayout.encloseY( loginLabel, login, passwordLabel, password, GridLayout.encloseIn(2, cancel, ok)); Button closeButton = new Button(); Style closeStyle = closeButton.getAllStyles(); closeStyle.setFgColor(0xffffff); closeStyle.setBgTransparency(0); closeStyle.setPaddingUnit(Style.UNIT_TYPE_DIPS); closeStyle.setPadding(3, 3, 3, 3); closeStyle.setBorder(RoundBorder.create().shadowOpacity(100)); FontImage.setMaterialIcon(closeButton, FontImage.MATERIAL_CLOSE); Container layers = LayeredLayout.encloseIn(box, FlowLayout.encloseRight(closeButton)); Style boxStyle = box.getUnselectedStyle(); boxStyle.setBgTransparency(255); boxStyle.setBgColor(0xeeeeee); boxStyle.setMarginUnit(Style.UNIT_TYPE_DIPS); boxStyle.setPaddingUnit(Style.UNIT_TYPE_DIPS); boxStyle.setMargin(4, 3, 3, 3); boxStyle.setPadding(2, 2, 2, 2); hi.add(BorderLayout.CENTER, layers); hi.show();
There are several things we learned from doing the
RoundBorder that we applied and did differently in
We use the UIID for the background color that just makes sense. We didn’t do the same for the stroke color/foreground color though. The background should now behave nicely including gradients and images!
We use millimeters where it makes sense, so a stroke can be in pixels since a 1 or 2 pixel stoke is something you might need but corner radius is always in millimeters as pixels just don’t fit here
This can also be customized via the designer tool which is another reason we had to change the resource file format:
The ripple effect is an Android effect that occurs when you press and hold a button. It ripples slightly.
It’s actually pretty nice and assuring that your touch was intercepted. This effect is implemented in the component level but at the moment it was only turned on for
Button. Moving forward this will probably be enabled for
SpanButton and other component types.
Every component has a ripple effect flag now that you can check and toggle via
setRippleEffect(boolean). In buttons that flag is set from the default state which you can tune via the theme constant
buttonRippleBool or via the
When a component is pressed and it has the ripple effect we keep painting it until it’s released. During that time we draw a translucent black color on top as a growing circle until it fills up the available space. You can customize the behavior of this painting by overriding
paintRippleOverlay(Graphics g, int x, int y, int position). I wouldn’t recommend doing that unless you are going for a completely unique application look.
One of the more controversial changes we made was to upcase all the button text by default for Android. You can disable that behavior by using the theme constant
capsButtonTextBool and set it to false or invoking
Android buttons should be upper case but iOS should have correct casing. This is very obvious when looking at iOS/Android UI’s critically. If you want to leave the global behavior but have case correctness for one individual button you can do this by invoking
In order to reduce the impact of this behavior we didn’t apply it to every
Button in existence even when it’s turned on. This only applies to
Dialog buttons and buttons with the UIID’s
RaisedButton. That means that if you have a custom button UIID you will need to explicitly call
setCapsText(Button.isCapsTextDefault()) to force this feature on for that