Learn to build Gluon Mobile Apps with three new samples


After achieving the important milestone of releasing Gluon Mobile 1.0 yesterday, today we release three samples that heavily use the main features of Gluon Mobile, so you can get started building your own applications more easily.

The first sample is simply called Notes. This sample makes use of Gluon Mobile’s ‘Charm Glisten’ features to give a polished user interface, and only makes use of local storage. Because of this, Notes is an app you can use for your own purposes only (as we purposefully did not include cloud connectivity in this sample). Install it on your phone, and create your own notes. You could read or edit them later at any time. With a fresh and modern UI, the app adapts responsively to any form factor of any kind of mobile, tablet, or desktop.

The second sample is called Comments 2.0. This sample focuses on Gluon Mobile’s ‘Charm Connect’ features, and is a revamped version of Comments 1.0. This sample is a chat-like app, where registered users can interchange comments, and see what others say. Using sliding effects to discover and execute possible actions, like many well-known mail apps do, we combine Gluon Charm Glisten and Connect features seamlessly to deliver an excellent user experience. This app also connects to Gluon Cloud, with bi-directional and automatic data synchronization. User authentication is done using popular web services such as Twitter, Facebook or Google+.

Finally the third sample, GoNative, demonstrates the power of Gluon Mobile’s ‘Charm Down’ features. With Charm Down we make use of hardware features on mobile devices in a platform-agnostic way, creating a device-independent API. In the process of creating this API, as we posted a few days ago, we have to face native code. This sample only covers the Android approach, in order to demonstrate building custom functionality. When time permits, we’ll add the iOS part and move the single API to Down.


Sample #1: Notes

The beauty of this simple app comes from Gluon Mobile’s ‘Charm Glisten’ features, with its out of the box ‘material design’ style. Focus only on what matters: your app. Don’t worry about boring UI guidelines. Glisten has this handled for you.

Using local storage, you don’t need to worry either about finding a local path, opening files, writing or updating your notes… Again, Gluon Charm Connect does it for you.

We use this functionality to store both notes (as a list) and settings (as an object).

The former benefits from using CharmObservableList: any change (new note, delete note, modify some field of any note) on the app side is immediately observed by the local storage.

public void retrieveNotes() {
    CharmObservableList charmNotes = userStorage.retrieveList(NOTES,
                                                  Note.class, 
                                                  StorageWhere.DEVICE, 
                                                  SyncFlag.LIST_WRITE_THROUGH, SyncFlag.OBJECT_WRITE_THROUGH);

    notes.set(charmNotes);
}

The latter, uses a CharmObservableObject and two convenient methods for retrieving and storing settings:

private void retrieveSettings() {
    CharmObservableObject charmSettings = userStorage.retrieveObject(NOTES_SETTINGS, 
                                                           Settings.class, 
                                                           StorageWhere.DEVICE);

    charmSettings.stateProperty().addListener((obs, ov, nv) -> {
        if (CharmObservable.State.INITIALIZED.equals(nv) && charmSettings.get() != null) {
            settingsProperty().set(charmSettings.get());
        }
    });
}

public void storeSettings() {
    userStorage.storeObject(NOTES_SETTINGS, settings.get(), StorageWhere.DEVICE);
}

And Glisten does the rest. With specific CSS for the built in JavaFX controls, or with our own controls, specifically designed for mobile devices, like the ListTile control, we just need to design our views: a main one, the home view, to list the notes, and other views for adding or editing notes. And our layers: a side menu with the settings. No matter if we will deploy the app on an android phone or an an iOS tablet, views, layers, text and icons will adapt seamlessly to any device.


Sample #2: Comments 2.0

If you were an early adopter of Gluon Mobile developer previews, you will know about the first version Comments 1.0. We have enhanced this application with new features to show all the potential of Gluon Mobile.

App sign in

App sign in

For starters, we have added user authentication: comments can be created only by registered users of the app, so only the author of one comment can edit or delete it. Out of the box, Gluon Mobile has a sign-in view. You just need to provide the key and secret tokens for each of the login methods required. Follow this very detailed step by step guide for this.

Once we have a valid user, we have a valid url to retrieve the user avatar. Glisten has an Avatar control that allows you to easily insert their avatar image any place you want, like in the list of comments on the main view, or in the add/edit comment view.

Delete comments on a tablet

Delete comments on a tablet

The custom cell we use for each comment is a clear sample of the use of custom controls created in Glisten. Besides the Avatar and the ListTile controls, we’ll wrap the latter in a SlidingListTile, allowing a sliding effect on any of the comments on the list view. Once the swipe effect is performed, the tile is translated, uncovering one button underneath. Providing two consumers for the actions of those buttons, we allow different actions when the swipe effect ends.

The code snippet below is from the CommentListCell class, which shows how we create a custom cell.

public class CommentListCell extends ListCell {

    private final SlidingListTile slidingTile;
    private final ListTile tile;
    private final Avatar avatar;
    private final String userId;

    public CommentListCell(String userId, Consumer consumerLeft, Consumer consumerRight) {
        this.userId = userId;
        avatar = new Avatar();
        tile = new ListTile();
        tile.setPrimaryGraphic(avatar);
        slidingTile = new SlidingListTile(tile);
        
        // edit mode, swipping from right to the left
        slidingTile.swipedLeftProperty().addListener((obs,b,b1)->{
            if (b1 && consumerRight != null) {
                consumerRight.accept(currentItem);
            }
            slidingTile.resetTilePosition();
        });
        
        // delete mode, swipping from left to right
        slidingTile.swipedRightProperty().addListener((obs,b,b1)->{
            if (b1 && consumerLeft != null) {
                consumerLeft.accept(currentItem);
            }
            slidingTile.resetTilePosition();
        });
    }

    @Override protected void updateItem(Comment item, boolean empty) {
        super.updateItem(item, empty);
        if (!empty && item != null) {
            avatar.setImage(CommentsService.getUserImage(item.getImageUrl()));
            slidingTile.allowedProperty().set(userId.equals(item.getNetworkId()));
            tile.textProperty().setAll(item.getAuthor());
            tile.textProperty().addAll(getContent(item));
            setGraphic(slidingTile);
        } else {
            setGraphic(null);
        }
    }
}

The screenshots below are taken from phone and tablet devices, on Android and iOS.


Sample #3: GoNative

Warning: While the application runs in any platform, for now the functionality is only added for Android, so it’s intended only for those devices.

This sample shows how to handle native interaction with hardware devices, and it was explained in detail in this post how to add Android native code to the project.

In this sample we have added API to get a picture with the camera, load a picture from the device gallery, activate the device vibration service, and read the accelerometer and plot a JavaFX chart.

Using FXActivity.getInstance().getSystemService(String name) we can access to many different services, like battery, wifi, or a sensor manager.

We can create a class that implements SensorEventListener, to listen to changes in the sensor, and retrieve the new values and return them to our JavaFX thread.

private final DoubleProperty x = new SimpleDoubleProperty();
private final DoubleProperty y = new SimpleDoubleProperty();
private final DoubleProperty z = new SimpleDoubleProperty();

private final SensorManager sensorManager;

public Accelerometer() {
    sensorManager = (SensorManager) FXActivity.getInstance().getSystemService(SENSOR_SERVICE);
}

public final void start() {
    if (!initialized) {
        sensorManager.registerListener(this, 
                sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 
                SensorManager.SENSOR_DELAY_NORMAL);
        initialized = true;
    }
}

@Override public void onSensorChanged(SensorEvent se) {
    if (se.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
        Platform.runLater(()->{
            // filter to remove gravity
            gravity[0] = alpha * gravity[0] + (1 - alpha) * se.values[0];
            gravity[1] = alpha * gravity[1] + (1 - alpha) * se.values[1];
            gravity[2] = alpha * gravity[2] + (1 - alpha) * se.values[2];

            x.set(se.values[0] - gravity[0]);
            y.set(se.values[1] - gravity[1]);
            z.set(se.values[2] - gravity[2]);
        });
    }
}


Conclusions

With these three complete samples, available already for free in our repository, we have provided enough material to get you started with the brand new Gluon Mobile 1.0.

Please, go ahead and try the samples, see for yourself the results and if you have any issue, report it to our forums.

If you want to learn more about Gluon Mobile on JavaFX on mobile, find out about our training offerings.

Hopefully you are convinced that it is worth giving Gluon Mobile a try. If you are interested in purchasing commercial licenses, please check out our pricing details here.