feat: animate delegates in from visual position

Instead of suddenly appearing, create them at their visual position then
animate them to the layout pos
This commit is contained in:
2 * r + 2 * t 2026-04-10 02:36:56 +10:00
parent 6cd5758234
commit 0844013ca7
2 changed files with 30 additions and 5 deletions

View file

@ -65,8 +65,8 @@ LazyListView {
Component.onCompleted: modelData?.lock(this)
Component.onDestruction: modelData?.unlock(this)
LazyListView.preferredHeight: modelData?.closed ? 0 : notifInner.nonAnimHeight
LazyListView.visibleHeight: modelData?.closed ? 0 : notifInner.implicitHeight
LazyListView.preferredHeight: modelData?.closed || LazyListView.removing ? 0 : notifInner.nonAnimHeight
LazyListView.visibleHeight: modelData?.closed || LazyListView.removing ? 0 : notifInner.implicitHeight
implicitHeight: notifInner.implicitHeight
opacity: LazyListView.removing || LazyListView.adding ? 0 : 1

View file

@ -367,9 +367,29 @@ void LazyListView::updatePolish() {
it->pendingInsert = false;
it->readyDelayStarted = false;
// Position correctly before making visible
if (idx >= 0 && idx < static_cast<int>(m_layout.size()))
item->setY(m_layout[idx].targetY - m_contentY);
// Set initial y to visual position (based on current visible heights)
if (idx >= 0 && idx < static_cast<int>(m_layout.size())) {
qreal visualY = 0;
bool hasVisItem = false;
for (int i = 0; i < static_cast<int>(m_layout.size()); ++i) {
qreal h;
auto dit = m_delegates.find(i);
if (dit != m_delegates.end() && dit->item)
h = delegateVisibleHeight(dit->item);
else
h = m_layout[i].heightKnown ? m_layout[i].height : effectiveEstimatedHeight();
if (h > 0) {
if (hasVisItem)
visualY += m_spacing;
hasVisItem = true;
}
if (i == idx)
break;
if (h > 0)
visualY += h;
}
item->setY(visualY - m_contentY);
}
item->setVisible(true);
auto* att =
@ -378,6 +398,11 @@ void LazyListView::updatePolish() {
att->setAdding(false);
att->setReady(true);
}
// Animate from visual position to layout position
if (idx >= 0 && idx < static_cast<int>(m_layout.size()))
item->setProperty("y", m_layout[idx].targetY - m_contentY);
polish();
});
}