[app] Workaround for positionViewAtIndex not working for the first time
This is probably a bug in QQuickListView - it first calculates the item position and then starts instantiating the delegates. The very first time the item position always turns out to be zero because the average item size isn't known yet. So if we are trying to position the list at a non-zero index and instead we got positioned at zero, try it again.
This commit is contained in:
parent
32013a8ac5
commit
77be4b68e8
2 changed files with 29 additions and 2 deletions
|
@ -48,6 +48,7 @@ BooksListWatcher::BooksListWatcher(QObject* aParent) :
|
||||||
iListView(NULL),
|
iListView(NULL),
|
||||||
iCenterMode(-1),
|
iCenterMode(-1),
|
||||||
iPositionIsChanging(false),
|
iPositionIsChanging(false),
|
||||||
|
iCanRetry(true),
|
||||||
iResizeTimer(new QTimer(this))
|
iResizeTimer(new QTimer(this))
|
||||||
{
|
{
|
||||||
iResizeTimer->setSingleShot(true);
|
iResizeTimer->setSingleShot(true);
|
||||||
|
@ -62,6 +63,7 @@ void BooksListWatcher::setListView(QQuickItem* aView)
|
||||||
if (iListView) iListView->disconnect(this);
|
if (iListView) iListView->disconnect(this);
|
||||||
iListView = aView;
|
iListView = aView;
|
||||||
iCenterMode = -1;
|
iCenterMode = -1;
|
||||||
|
iCanRetry = true;
|
||||||
if (iListView) {
|
if (iListView) {
|
||||||
connect(iListView,
|
connect(iListView,
|
||||||
SIGNAL(widthChanged()),
|
SIGNAL(widthChanged()),
|
||||||
|
@ -139,13 +141,36 @@ void BooksListWatcher::positionViewAtIndex(int aIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iPositionIsChanging = true;
|
iPositionIsChanging = true;
|
||||||
QMetaObject::invokeMethod(iListView, LISTVIEW_POSITION_VIEW_AT_INDEX,
|
positionViewAtIndex(aIndex, iCenterMode);
|
||||||
Q_ARG(int,aIndex), Q_ARG(int,iCenterMode));
|
if (iCanRetry) {
|
||||||
|
// This is probably a bug in QQuickListView - it first calculates
|
||||||
|
// the item position and then starts instantiating the delegates.
|
||||||
|
// The very first time the item position always turns out to be
|
||||||
|
// zero because the average item size isn't known yet. So if we
|
||||||
|
// are trying to position the list at a non-zero index and instead
|
||||||
|
// we got positioned at zero, try it again. It doesn't make sense
|
||||||
|
// to retry more than once though.
|
||||||
|
if (aIndex > 0 && getCurrentIndex() == 0) {
|
||||||
|
// Didn't work from the first try, give it another go
|
||||||
|
HDEBUG("retrying...");
|
||||||
|
positionViewAtIndex(aIndex, iCenterMode);
|
||||||
|
}
|
||||||
|
iCanRetry = false;
|
||||||
|
}
|
||||||
iPositionIsChanging = false;
|
iPositionIsChanging = false;
|
||||||
updateCurrentIndex();
|
updateCurrentIndex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BooksListWatcher::positionViewAtIndex(int aIndex, int aMode)
|
||||||
|
{
|
||||||
|
if (iListView) {
|
||||||
|
QMetaObject::invokeMethod(iListView,
|
||||||
|
LISTVIEW_POSITION_VIEW_AT_INDEX,
|
||||||
|
Q_ARG(int,aIndex), Q_ARG(int,aMode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
qreal BooksListWatcher::contentX()
|
qreal BooksListWatcher::contentX()
|
||||||
{
|
{
|
||||||
return getRealProperty(LISTVIEW_CONTENT_X);
|
return getRealProperty(LISTVIEW_CONTENT_X);
|
||||||
|
|
|
@ -66,6 +66,7 @@ private:
|
||||||
qreal contentY();
|
qreal contentY();
|
||||||
qreal getRealProperty(const char *name, qreal defaultValue = 0.0);
|
qreal getRealProperty(const char *name, qreal defaultValue = 0.0);
|
||||||
int getCurrentIndex();
|
int getCurrentIndex();
|
||||||
|
void positionViewAtIndex(int aIndex, int aMode);
|
||||||
void updateCurrentIndex();
|
void updateCurrentIndex();
|
||||||
void updateSize();
|
void updateSize();
|
||||||
|
|
||||||
|
@ -92,6 +93,7 @@ private:
|
||||||
QQuickItem* iListView;
|
QQuickItem* iListView;
|
||||||
int iCenterMode;
|
int iCenterMode;
|
||||||
bool iPositionIsChanging;
|
bool iPositionIsChanging;
|
||||||
|
bool iCanRetry;
|
||||||
QTimer* iResizeTimer;
|
QTimer* iResizeTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue