Forums

OverviewV-Play 2 Support (Qt 5) › AppListView + PullToRefreshHandler + VisibilityRefreshHandler works only once

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #18546

    Arne

    Hello,

    I am in struggle with 2 components and I can’t find my mistake.

    I have an AppListView with a model that gets filled by my backend, a PullToRefreshHandler that loads new elements when I pull down the list and a VisibilityRefreshHandler when the end of the list at the bottom is visible to load more elements (pagination). This whole setup works only once.

    The initial model has 10 elements provided by the backend response, when I pull down the trigger it loads more elements. When I scroll down to load older elements, it populates the model again but now I can’t pull to refresh anymore. The indicator does not respond anymore.

    Here is some of my code:

    AppListView {
            id: listView
            anchors.top: customBar.bottom
            model: []
            delegate: TimelineRow {
                id: timelineRow
                onSelected: {
                    navigationStack.push(articlePageComponent, { post_url: Backend.getUrl( timelineRow.post_external_url, timelineRow.post_url ) })
                }
                onEmojiUpdate: { // onEmojiUpdate(int post_id, int total, var most_reactions)
                    // store the emoji state into temporary database
                    var _obj = {id: post_id, total: total, reactions: most_reactions};
                    database.setValue(_obj.id, _obj)
                }
            }
            spacing: dp(5)
            backgroundColor: "#000000"
            scrollIndicatorVisible: false
            footer: VisibilityRefreshHandler {
                id: footerRefreshHandler
                onRefresh: {
                    listPageComponent.currentPage++;
                    listView.refreshModel(false)
                }
            }
    
            Component.onCompleted: {
                // init model
                if(listPageComponent.currentPage == 1){
                    refreshModel();
                }
            }
    
            PullToRefreshHandler {
                id: refreshHandler
                contentColor: Theme.navigationBar.titleColor
                onRefresh: listView.refreshModel( true )
                refreshing: listPageComponent.isRefreshing
            }
    
            // refresh model and update emoji list state data
            function refreshModel(pullToRefresh) {
                // if we are not pulling for refresh, set to false
                if( typeof pullToRefresh === 'undefined' ){
                    pullToRefresh = false;
                }
    
                // if we are in a refreshing state, return
                if( listPageComponent.isRefreshing ){
                    return;
                }
    
                // pull to refresh means ask for new posts
                if( pullToRefresh ){
                    listView.model = [];
                    listPageComponent.currentPage = 1;
                }
    
                var _currentPage = listPageComponent.currentPage;
    
                listPageComponent.isRefreshing = true;
                var scrollPos = getScrollPosition()
                customBar.play()
    
                // ask backend for new posts
                Backend.getPosts( {page: _currentPage, category: listPageComponent.currentCategory }, function( listElements, cfg ){
                    // attach more posts
                    var _oldModel = listView.model || [];
                    var _oldModelLen = _oldModel.length;
    
                    var _newPostLen = listElements.length;
                    for(var a = 0; a < _newPostLen; a++){
                        _oldModel.push(listElements[a]);
                    }
    
                    // update emoji status with old state
                    for(var b = 0; b < _oldModelLen; b++){
                        var _set = database.getValue(_oldModel[b].post_id);
                        if(typeof _set !== 'undefined' && _set.id !== 'undefined'){
                            _oldModel[b].post_most_reactions = _set.reactions;
                            _oldModel[b].post_total_reactions = _set.total;
                        }
                    }
    
                    // assign updated list to listview model
                    listView.model = _oldModel;
    
                    if( _newPostLen > 0 ){
                        // restore scroll position
                        listView.restoreScrollPosition(scrollPos)
                    }
    
                    // set timeline banner from api app config
                    if(typeof cfg.timeline_banner_url !== 'undefined'){
                        if(cfg.timeline_banner_url.length > 0){
                            // set banner image url
                            customBar.bannerUrl = cfg.timeline_banner_url;
    
                            // set external url
                            if( typeof cfg.timeline_banner_partner_url !== 'undefined' ){
                                customBar.bannerPartnerUrl = cfg.timeline_banner_partner_url;
                            }
                        } else {
                            customBar.bannerUrl = "";
                            customBar.bannerPartnerUrl = "";
                        }
                    } else {
                        customBar.bannerUrl = "";
                        customBar.bannerPartnerUrl = "";
                    }
    
                    // set menu
                    if( typeof cfg.menu !== 'undefined' ){
                        leftBarMenuDrawer.setMenu(cfg.menu);
                    }
    
                    // set refresh status
                    listPageComponent.isRefreshing = false;
                    customBar.stop()
                } );
            } // - Backend callback end
        } // - AppListView end

    What is the problem here? Do I have to reset the model first or reset the state of the AppListView somehow? I don’t get it. Does somebody has a hint for me?

    Thanks, Arne

    #18562

    Günther
    V-Play Team

    Hi Arne,

    I tested a simplified version of your code (plain integer model + SimpleRow items):

    import VPlayApps 1.0
    import QtQuick 2.9
    import QtQuick.Controls 2.2 as Quick2
    
    App {
      property int currentPage: 1
      property bool isRefreshing
    
    
      AppListView {
        id: listView
        model: []
        delegate: SimpleRow {
          text: "Item: "+index
        }
        backgroundColor: "#000000"
        scrollIndicatorVisible: false
        footer: VisibilityRefreshHandler {
          id: footerRefreshHandler
          onRefresh: {
            currentPage++;
            listView.refreshModel(false)
          }
        }
    
        Component.onCompleted: {
          // init model
          if(currentPage == 1){
            refreshModel();
          }
        }
    
        PullToRefreshHandler {
          id: refreshHandler
          contentColor: Theme.navigationBar.titleColor
          onRefresh: listView.refreshModel( true )
          refreshing: isRefreshing
        }
    
        // refresh model and update emoji list state data
        function refreshModel(pullToRefresh) {
          // if we are not pulling for refresh, set to false
          if( typeof pullToRefresh === 'undefined' ){
            pullToRefresh = false;
          }
    
          // if we are in a refreshing state, return
          if( isRefreshing ){
            return;
          }
    
          // pull to refresh means ask for new posts
          if( pullToRefresh ){
            listView.model = 0;
            currentPage = 1;
          }
    
          var _currentPage = currentPage;
    
          isRefreshing = true;
          var scrollPos = getScrollPosition()
    
            // attach more posts
            var _oldModel = listView.model > 0 ? listView.model : 0;
            var _newPostLen = 9; // add 9
            _oldModel += _newPostLen;
    
            // assign updated list to listview model
            listView.model = _oldModel;
    
            if( _newPostLen > 0 ){
              // restore scroll position
              listView.restoreScrollPosition(scrollPos)
            }
    
            // set refresh status
            isRefreshing = false;
        } // - Backend callback end
      } // - AppListView end
    }
    

    After loading additional items with VisibilityRefreshHandler, it is still possible to reset the list with PullToRefresh for me. Are you able to reproduce the issue with this scenario?

    A minor suggestion: By calling listView.modelChanged(), you can signal a change in your model if the model is not replaced completely, but items within the model change. Maybe this can help?

    Best,
    Günther

     

     

     

    #18570

    Arne

    Hi Günther,

    sorry for the delay. Thanks for your time!

    You are right, if I change the delegate to SimpleRow it’s working for me too. So it has something to do with my TimelineRow Component. Thanks for pointing me on this. I will investigate and give report.

    Best,

    Arne

Viewing 3 posts - 1 through 3 (of 3 total)

RSS feed for this thread

You must be logged in to reply to this topic.

Voted #1 for:

  • Easiest to learn
  • Most time saving
  • Best support

Develop Cross-Platform Apps and Games 50% Faster!

  • Voted the best supported, most time-saving and easiest to learn cross-platform development tool
  • Based on the Qt framework, with native performance and appearance on all platforms including iOS and Android
  • Offers a variety of plugins to monetize, analyze and engage users
FREE!
create apps
create games
cross platform
native performance
3rd party services
game network
multiplayer
level editor
easiest to learn
biggest time saving
best support