aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickitemview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick/items/qquickitemview.cpp')
-rw-r--r--src/quick/items/qquickitemview.cpp48
1 files changed, 32 insertions, 16 deletions
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 1f8a0de72b..95f1229b92 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -162,7 +162,7 @@ QQuickItemView::QQuickItemView(QQuickFlickablePrivate &dd, QQuickItem *parent)
QQuickItemView::~QQuickItemView()
{
Q_D(QQuickItemView);
- d->clear();
+ d->clear(true);
if (d->ownModel)
delete d->model;
delete d->header;
@@ -1662,7 +1662,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex)
releaseItem(oldCurrentItem);
}
-void QQuickItemViewPrivate::clear()
+void QQuickItemViewPrivate::clear(bool onDestruction)
{
Q_Q(QQuickItemView);
currentChanges.reset();
@@ -1683,7 +1683,7 @@ void QQuickItemViewPrivate::clear()
currentItem = nullptr;
if (oldCurrentItem)
emit q->currentItemChanged();
- createHighlight();
+ createHighlight(onDestruction);
trackedItem = nullptr;
if (requestedIndex >= 0) {
@@ -1724,8 +1724,14 @@ void QQuickItemViewPrivate::refill()
void QQuickItemViewPrivate::refill(qreal from, qreal to)
{
Q_Q(QQuickItemView);
- if (!isValid() || !q->isComponentComplete())
+ if (!model || !model->isValid() || !q->isComponentComplete())
+ return;
+ if (!model->count()) {
+ updateHeader();
+ updateFooter();
+ updateViewport();
return;
+ }
do {
bufferPause.stop();
@@ -1881,15 +1887,21 @@ void QQuickItemViewPrivate::layout()
prepareVisibleItemTransitions();
- for (QList<FxViewItem*>::Iterator it = releasePendingTransition.begin();
- it != releasePendingTransition.end(); ) {
- FxViewItem *item = *it;
- if (prepareNonVisibleItemTransition(item, viewBounds)) {
- ++it;
- } else {
- releaseItem(item);
+ for (auto it = releasePendingTransition.begin(); it != releasePendingTransition.end(); ) {
+ auto old_count = releasePendingTransition.count();
+ auto success = prepareNonVisibleItemTransition(*it, viewBounds);
+ // prepareNonVisibleItemTransition() may invalidate iterators while in fast flicking
+ // invisible animating items are kicked in or out the viewPort
+ // use old_count to test if the abrupt erasure occurs
+ if (old_count > releasePendingTransition.count()) {
+ continue;
+ }
+ if (!success) {
+ releaseItem(*it);
it = releasePendingTransition.erase(it);
+ continue;
}
+ ++it;
}
for (int i=0; i<visibleItems.count(); i++)
@@ -2232,7 +2244,10 @@ bool QQuickItemViewPrivate::prepareNonVisibleItemTransition(FxViewItem *item, co
if (item->scheduledTransitionType() == QQuickItemViewTransitioner::MoveTransition)
repositionItemAt(item, item->index, 0);
- if (item->prepareTransition(transitioner, viewBounds)) {
+ bool success = false;
+ ACTION_IF_DELETED(item, success = item->prepareTransition(transitioner, viewBounds), return success);
+
+ if (success) {
item->releaseAfterTransition = true;
return true;
}
@@ -2352,15 +2367,16 @@ void QQuickItemView::destroyingItem(QObject *object)
bool QQuickItemViewPrivate::releaseItem(FxViewItem *item)
{
Q_Q(QQuickItemView);
- if (!item || !model)
+ if (!item)
return true;
if (trackedItem == item)
trackedItem = nullptr;
item->trackGeometry(false);
- QQmlInstanceModel::ReleaseFlags flags = model->release(item->item);
- if (item->item) {
- if (flags == 0) {
+ QQmlInstanceModel::ReleaseFlags flags = {};
+ if (model && item->item) {
+ flags = model->release(item->item);
+ if (!flags) {
// item was not destroyed, and we no longer reference it.
QQuickItemPrivate::get(item->item)->setCulled(true);
unrequestedItems.insert(item->item, model->indexOf(item->item, q));