Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Highlighted
Developer
Posts: 385
Registered: ‎07-20-2012
My Device: Blackberry Z10 (White), BlackBerry Dev Alpha C
My Carrier: O2 UK
Accepted Solution

Activity Indicator for a loading Data Model

Hello, 

 

I am looking into using an activity indicator to show that my list view is loading to the user (as it takes 2-3 seconds for the list view to populate with data as it is getting the file from my server).

 

Here is my list view  & data source: 

 

ListView {
                                id: listView1
                                dataModel: dataModel1

                                leadingVisual: [
                                    Container {
                                        id: dropDownContainer1
                                        topPadding: 20
                                        leftPadding: 20
                                        rightPadding: 20
                                        bottomPadding: 20
                                        background: Color.create("#212121")
                                        DropDown {
                                            id: dropDown1
                                            title: qsTr("Date:") + Retranslate.onLocaleOrLanguageChanged
                                            Option {
                                                id: all
                                                text: qsTr("All") + Retranslate.onLocaleOrLanguageChanged
                                                selected: true
                                            }
                                            Option {
                                                text: qsTr("23/06/2014")
                                                value: "23/06/2014"
                                            }
                                            Option {
                                                text: qsTr("24/06/2014")
                                                value: "24/06/2014"
                                            }
                                            Option {
                                                text: qsTr("25/06/2014")
                                                value: "25/06/2014"
                                            }
                                            Option {
                                                text: qsTr("26/06/2014")
                                                value: "26/06/2014"
                                            }
                                            Option {
                                                text: qsTr("27/06/2014")
                                                value: "27/06/2014"
                                            }
                                            Option {
                                                text: qsTr("28/06/2014")
                                                value: "28/06/2014"
                                            }
                                            Option {
                                                text: qsTr("29/06/2014")
                                                value: "29/06/2014"
                                            }
                                            Option {
                                                text: qsTr("30/06/2014")
                                                value: "30/06/2014"
                                            }
                                            Option {
                                                text: qsTr("01/07/2014")
                                                value: "July 1 2014"
                                            }
                                            Option {
                                                text: qsTr("02/07/2014")
                                                value: "July 2 2014"
                                            }
                                            Option {
                                                text: qsTr("03/07/2014")
                                                value: "July 3 2014"
                                            }
                                            Option {
                                                text: qsTr("04/07/2014")
                                                value: "July 4 2014"
                                            }
                                            Option {
                                                text: qsTr("05/07/2014")
                                                value: "July 5 2014"
                                            }
                                            Option {
                                                text: qsTr("06/07/2014")
                                                value: "July 6 2014"
                                            }
                                            onSelectedIndexChanged: {
                                                if (selectedOption == all) {
                                                    dropDownDataSource1.sQuery = ""
                                                } else
                                                    dropDownDataSource1.sQuery = dropDown1.at(dropDown1.selectedIndex).value;
                                            }
                                        }
                                    }
                                ]

                                listItemComponents: [
                                    ListItemComponent {
                                        type: "item"
                                        StandardListItem {
                                            title: ListItemData.fixtureInfo
                                            description: Qt.formatTime(new Date(ListItemData.timestamp * 1))
                                        }
                                    }
                                ]

                                onTriggered: {
                                    var selectedItem = dataModel1.data(indexPath);
                                    var detail = fixtures.createObject();

                                    detail.fixtureInfo = selectedItem.fixtureInfo
                                    detail.dateInfo = selectedItem.dateInfo
                                    detail.timeInfo = selectedItem.timeInfo
                                    detail.timeZone = Qt.formatTime(new Date(selectedItem.timestamp * 1))
                                    detail.courtInfo = selectedItem.courtInfo
                                    detail.resultInfo = selectedItem.resultInfo

                                    navigationPane1.push(detail)
                                }
                            }

 

GroupDataModel {
                    id: dataModel1
                    sortingKeys: [ "dateNumber", "id" ]
                    grouping: ItemGrouping.ByFullValue
                    sortedAscending: false
                },
                DataSource {
                    id: dataSource1
                    property string sQuery: ""
                    onSQueryChanged: {
                        dataModel1.clear()
                        load()
                    }
                    source: "http://tundracorestudios.co.uk/wp-content/uploads/2014/06/Fixtures.json"
                    type: DataSourceType.Json

                    onDataLoaded: {
                        //create a temporary array tohold the data
                        var tempdata = new Array();
                        for (var i = 0; i < data.length; i ++) {

                            tempdata[i] = data[i]

                            //this is where we handle the search query
                            if (sQuery == "") {
                                //if no query is made, we load all the data
                                dataModel1.insert(tempdata[i])
                            } else {
                                //if the query matches any part of the country TITLE, we insert that into the list
                                //we use a regExp to compare the search query to the COUNTRY TITLE (case insenstive)
                                if (data[i].fixtureInfo.search(new RegExp(sQuery, "i")) != -1) {
                                    dataModel1.insert(tempdata[i])

                                    //Otherwise, we do nothingand donot insert the item
                                }

                            }

                        }

                        // this if statement below does the same as above,but handles the output if there is only one search result
                        if (tempdata[0] == undefined) {
                            tempdata = data

                            if (sQuery == "") {
                                dataModel1.insert(tempdata)
                            } else {
                                if (data.fixtureInfo.search(new RegExp(sQuery, "i")) != -1) {
                                    dataModel1.insert(tempdata)
                                }
                            }
                        }
                    }
                    onError: {
                        console.log(errorMessage)
                    }
                },

 

onCreationCompleted: {
                dataSource1.load()
            }

 In another part of my app, I am using an activity indicator to load a webView but I couldn't seem to remodel it for the list view.

 

Here's the code that works when my webView is loading: 

 

WebView {
                    id: detailsView
                    settings.zoomToFitEnabled: true
                    settings.activeTextEnabled: true
                    settings.background: Color.Transparent
                    onLoadingChanged: {
                        if (loadRequest.status == WebLoadStatus.Started) {

                        } else if (loadRequest.status == WebLoadStatus.Succeeded) {
                            webLoading.stop()
                        } else if (loadRequest.status == WebLoadStatus.Failed) {

                        }
                    }
                    settings.defaultFontSize: 16
                }

 

Container {
            id: loadMask
            background: Color.Black
            layout: DockLayout {

            }
            verticalAlignment: VerticalAlignment.Fill
            horizontalAlignment: HorizontalAlignment.Fill
            Container {
                leftPadding: 10.0
                rightPadding: 10.0
                topPadding: 10.0
                bottomPadding: 10.0
                horizontalAlignment: HorizontalAlignment.Center
                verticalAlignment: VerticalAlignment.Center
                ActivityIndicator {
                    id: webLoading
                    preferredHeight: 200.0
                    preferredWidth: 200.0
                    horizontalAlignment: HorizontalAlignment.Center
                    onStarted: {
                        loadMask.setVisible(true)
                    }
                    onStopping: {
                        loadMask.setVisible(false)
                    }
                }
                Label {
                    text: "Loading Content..."
                    horizontalAlignment: HorizontalAlignment.Center
                    textStyle.fontSize: FontSize.Large
                    textStyle.fontWeight: FontWeight.W100
                    textStyle.color: Color.White
                }
            }
        }

 

onCreationCompleted: {
        webLoading.start()
    }

 

Therefore, what I'm trying to do is: get the activity indicator to show when the list view is populating and when it has finished, for the activity indicator to be invisible. As well as that, if the user doesn't have a connection to the internet or loses signal whilst the data is populating: would it be possible to retreive the data from a locally stored file instead ("asset:///JSON/Fixtures.json")? 

 

Thanks in advance Smiley Happy

BlackBerry Development Advisor
Posts: 15,727
Registered: ‎07-09-2008
My Device: BlackBerry PRIV
My Carrier: Bell

Re: Activity Indicator for a loading Data Model

Here is a page in the Community 3 sample that displays an ActivityIndicator while the content is downloaded for use in the ListView.  BoardProvider.cpp is the class that fires the signal that triggers the hidding of the ActivityIndicator.

Mark Sohm
BlackBerry Development Advisor

Please refrain from posting new questions in solved threads.
Problem solved? Click the Accept As Solution button.
Found a bug? Report it using Issue Tracker
Developer
Posts: 385
Registered: ‎07-20-2012
My Device: Blackberry Z10 (White), BlackBerry Dev Alpha C
My Carrier: O2 UK

Re: Activity Indicator for a loading Data Model

Hi Mark,

Thanks for replying.

I'm just looking through the c++ code now but I was wondering if the same could be achieved purely in QML?
Developer
Posts: 265
Registered: ‎01-02-2011
My Device: Z30, PlayBook
My Carrier: AT&T

Re: Activity Indicator for a loading Data Model

You need a couple of JavaScript Functions to stop and start your inidicator.

 

function stopLoading() {
        if(myActivityIndicator.running) {
            myActivityIndicator.stop();
            myActivityIndicator.visible = false;
        }
    }
    function startLoading() {
        if(!myActivityIndicator.running) {
            myActivityIndicator.visible = true;
            myActivityIndicator.start();
        }
    }

 Then, when you start to load the DataModel, trigger the start.

When the datamodel of the ListView is finished, then you can call the stop loading.

 onDataModelChanged: {
   stopLoading();
}

 

_________________
Meetup for BlackBerry 10
Meetup Search Tool - not available at the moment
Developer
Posts: 385
Registered: ‎07-20-2012
My Device: Blackberry Z10 (White), BlackBerry Dev Alpha C
My Carrier: O2 UK

Re: Activity Indicator for a loading Data Model

Hello, 

 

Thanks for replying. 

 

I placed your functions just underneath my navigationPane like so:

 

Tab { //First tab
        id: tab1
        // Localized text with the dynamic translation and locale updates support
        title: qsTr("Fixtures") + Retranslate.onLocaleOrLanguageChanged
        imageSource: "asset:///IMG/ic_view_list.png"
        NavigationPane {
            function stopLoading() {
                if (myActivityIndicator.running) {
                    myActivityIndicator.stop();
                    myActivityIndicator.visible = false;
                }
            }
            function startLoading() {
                if (! myActivityIndicator.running) {
                    myActivityIndicator.visible = true;
                    myActivityIndicator.start();
                }
            }

            id: navigationPane1

            Page {

 & then I placed the activity indicator just before my listView:

 

Container {
                            layout: DockLayout {

                            }
                            verticalAlignment: VerticalAlignment.Fill
                            horizontalAlignment: HorizontalAlignment.Fill
                            Container {
                                id: loadMask
                                background: Color.Black
                                layout: DockLayout {

                                }
                                verticalAlignment: VerticalAlignment.Fill
                                horizontalAlignment: HorizontalAlignment.Fill
                                Container {
                                    leftPadding: 10.0
                                    rightPadding: 10.0
                                    topPadding: 10.0
                                    bottomPadding: 10.0
                                    horizontalAlignment: HorizontalAlignment.Center
                                    verticalAlignment: VerticalAlignment.Center
                                    ActivityIndicator {
                                        id: myActivityIndicator
                                        preferredHeight: 200.0
                                        preferredWidth: 200.0
                                        horizontalAlignment: HorizontalAlignment.Center
                                    }
                                    Label {
                                        text: "Loading Content..."
                                        horizontalAlignment: HorizontalAlignment.Center
                                        textStyle.fontSize: FontSize.Large
                                        textStyle.fontWeight: FontWeight.W100
                                        textStyle.color: Color.White
                                    }
                                }
                            }
                            ListView {

 To then add the onDataModelChanged: 

 

onDataModelChanged: {
                                    stopLoading();
                                }

 & onCreationCompleted:

 

onCreationCompleted: {
                dataSource1.load();
                startLoading()
            }

 Everything works fine: the app opens, the data source begins to load, the activity indiciator appears and then the data loads but there's one problem.

 

The activity indicator remains visible and the onDataModelChanged says:

 

"Unknown symbol 'stopLoading'"

 

Any suggestions? Smiley Happy

 

 

Developer
Posts: 265
Registered: ‎01-02-2011
My Device: Z30, PlayBook
My Carrier: AT&T

Re: Activity Indicator for a loading Data Model

[ Edited ]

Did you add the stopLoading() and startLoading() at the Page level?

 

It can't find the stopLoading()

 

So, it is possibly a scope issue.  Try putting it at different levels.

_________________
Meetup for BlackBerry 10
Meetup Search Tool - not available at the moment
Developer
Posts: 385
Registered: ‎07-20-2012
My Device: Blackberry Z10 (White), BlackBerry Dev Alpha C
My Carrier: O2 UK

Re: Activity Indicator for a loading Data Model

Yes, I added them there too which removed the unknown symbol issue but the activity indicator continues to be visible.

Therefore, I was wondering if I should check somehow when the listView is populated to then hide the activity indicator?
BlackBerry Development Advisor
Posts: 15,727
Registered: ‎07-09-2008
My Device: BlackBerry PRIV
My Carrier: Bell

Re: Activity Indicator for a loading Data Model

Have you verified your methods to show and hide the indicators are being called?  Add some console.log statements to check.  You might be misunderstanding when the onDataModelChanged fires.  It fires when the DataModel itself is changed (meaning a new DataModel specified), not when the data in the DataModel changes.

Mark Sohm
BlackBerry Development Advisor

Please refrain from posting new questions in solved threads.
Problem solved? Click the Accept As Solution button.
Found a bug? Report it using Issue Tracker
Developer
Posts: 385
Registered: ‎07-20-2012
My Device: Blackberry Z10 (White), BlackBerry Dev Alpha C
My Carrier: O2 UK

Re: Activity Indicator for a loading Data Model

With the help of a few other developers, I maneged to get everything to function correctly. 

 

Jeremy Duke pointed out to me that I would need to use onItemAdded function in my Group Data Model:

 

onItemAdded: {
                        myActivityIndicator.stop();
                        myActivityIndicator.visible = false;
                        loadMask.visible = false;
                        searchingLabel.visible = false;
                    }

 In adding that, the loading stops when an item has populated the list. 

 

Thanks for your help Smiley Happy