Add custom components

To format the information about a place on our UI, we create two custom UI components: a FieldLabel and a FieldNumber. These components make it easy to reuse the formatting for similar fields on our UI. For more information about this technique, see Custom QML components.

The field label component

First we create the FieldLabel component. Go ahead and create a file called FieldLabel.qml in the assets folder of your project. The FieldLabel component contains a Label for the title of the SelectedPlace property and a Label for the value of the SelectedPlace property. The custom component defines a textStyle for each of these properties and some characteristics of the Label to make the labels consistent in the UI. For more information about text styling, see Text controls and Text styles. You can also read more about Labels.

Notice that we set the visible property of the Container to false when the field that we are displaying has an empty value.

import bb.cascades 1.2

Container {
    id: root

    property alias title : titleLabel.text
    property string field
    property variant selectedPlace

    visible: (selectedPlace ? (selectedPlace[field] != "") : false)

    layout: StackLayout {
        orientation: LayoutOrientation.LeftToRight
    }

    // The title label
    Label {
        id: titleLabel

        layoutProperties: StackLayoutProperties {
            spaceQuota: 1
        }

        opacity: 0.7

        textStyle {
            base: SystemDefaults.TextStyles.BodyText
            color: Color.White
            fontStyle: FontStyle.Italic
        }
    }

    // The field value label
    Label {
        layoutProperties: StackLayoutProperties {
            spaceQuota: 1
        }

        text: selectedPlace ? selectedPlace[field] : ""

        textStyle {
            base: SystemDefaults.TextStyles.BodyText
            color: Color.White
        }

        multiline: true
    }
}

The field number component

Next we create the FieldNumber custom component. Create a file called FieldNumber.qml in the assets folder of your project. The only difference between this component and the FieldName component is the handling of whether the field that we are displaying should be visible in the UI.

For the FieldLabel component, we decide if this field is visible in the UI by checking the value of the field. If the field value is undefined, we don't need to include it in the UI, so we set the visible property of the Container to false.

import bb.cascades 1.2

Container {
    id: root

    property alias title : titleLabel.text
    property string field
    property variant selectedPlace

    visible: (selectedPlace ? !((selectedPlace[field] > 1000000) || 
             (selectedPlace[field] == -1)) : false)

    layout: StackLayout {
        orientation: LayoutOrientation.LeftToRight
    }

    // The title label
    Label {
        id: titleLabel

        layoutProperties: StackLayoutProperties {
            spaceQuota: 1
        }

        opacity: 0.7

        textStyle {
            base: SystemDefaults.TextStyles.BodyText
            color: Color.White
            fontStyle: FontStyle.Italic
        }
    }

    // The field value label
    Label {
        layoutProperties: StackLayoutProperties {
            spaceQuota: 1
        }

        text: selectedPlace ? selectedPlace[field] : ""

        textStyle {
            base: SystemDefaults.TextStyles.BodyText
            color: Color.White
        }

        multiline: true
    }
}

Handle different device types

We can use a custom component to handle different screen resolutions. When we created the Container for our UI, we decided that if our app runs on a device with a physical keyboard, we want to create our UI in a ScrollView so that we can allow users to scroll to see more of the UI. We don't need to code the logic for this decision; we just need to use the static asset selector.

For an all-touch device, you just need a Container for your UI. We assume that our default UI is suited to an all-touch device, so we create a file called PlacepickerScrollView.qml in the assets folder of our project.

import bb.cascades 1.2

// In the default resolution we do not add a scroll to the UI, 
// since we do not want rubberbanding at the top and bottom. 
// For a smaller screen this component will contain a vertical 
// ScrollView.
Container {
}

To make sure that our UI fits correctly on a device with a physical keyboard, we need to create a slightly different container. We let the static asset selector decide which container to select based on the device that our app is running on.

To use the static asset selector, create a folder called 720x720 in your assets folder. Right-click the assets folder of your project, click New > Folder and name your folder 720x720. Now we create a file called PlacepickerScrollView.qml in the 720x720 folder of our project. The PlacepickerScrollView component contains a ScrollView that allows vertical scrolling of the UI on the device.

import bb.cascades 1.2

// For the 720x720 resolution a ScrollView is used. For the standard
// resolution this would lead to rubberbanding of a full screen UI,
// which we do not want.
ScrollView {
    scrollViewProperties {
        scrollMode: ScrollMode.Vertical
    }
}

For more information about asset selectors, see Resolution independence and Static asset selection.

We're done! Build and run the app to see the results.

Screen showing the Place picker sample.

Last modified: 2013-12-21

comments powered by Disqus