fix: use visible height to calc contentHeight
This commit is contained in:
parent
051b8caee6
commit
916b702562
3 changed files with 59 additions and 4 deletions
|
|
@ -73,6 +73,7 @@ LazyListView {
|
|||
}
|
||||
|
||||
LazyListView.preferredHeight: closed ? 0 : notifInner.nonAnimHeight
|
||||
LazyListView.visibleHeight: notifInner.implicitHeight
|
||||
implicitHeight: notifInner.implicitHeight
|
||||
|
||||
opacity: LazyListView.removing || closed || LazyListView.adding ? 0 : 1
|
||||
|
|
|
|||
|
|
@ -22,6 +22,17 @@ void LazyListViewAttached::setPreferredHeight(qreal height) {
|
|||
emit preferredHeightChanged();
|
||||
}
|
||||
|
||||
qreal LazyListViewAttached::visibleHeight() const {
|
||||
return m_visibleHeight;
|
||||
}
|
||||
|
||||
void LazyListViewAttached::setVisibleHeight(qreal height) {
|
||||
if (qFuzzyCompare(m_visibleHeight, height))
|
||||
return;
|
||||
m_visibleHeight = height;
|
||||
emit visibleHeightChanged();
|
||||
}
|
||||
|
||||
bool LazyListViewAttached::adding() const {
|
||||
return m_adding;
|
||||
}
|
||||
|
|
@ -210,6 +221,22 @@ qreal LazyListView::delegateHeight(QQuickItem* item) {
|
|||
return item->implicitHeight();
|
||||
}
|
||||
|
||||
qreal LazyListView::delegateVisibleHeight(QQuickItem* item) {
|
||||
if (!item)
|
||||
return 0;
|
||||
|
||||
auto* attached = qobject_cast<LazyListViewAttached*>(
|
||||
qmlAttachedPropertiesObject<LazyListView>(item, false));
|
||||
if (attached) {
|
||||
if (attached->visibleHeight() >= 0)
|
||||
return attached->visibleHeight();
|
||||
if (attached->preferredHeight() >= 0)
|
||||
return attached->preferredHeight();
|
||||
}
|
||||
|
||||
return item->implicitHeight();
|
||||
}
|
||||
|
||||
// --- Add Animation ---
|
||||
|
||||
int LazyListView::addDuration() const {
|
||||
|
|
@ -388,15 +415,33 @@ void LazyListView::updatePolish() {
|
|||
// --- Layout Engine ---
|
||||
|
||||
void LazyListView::relayout() {
|
||||
// Layout positioning uses preferredHeight (final/non-animated)
|
||||
qreal y = 0;
|
||||
for (auto& record : m_layout) {
|
||||
record.targetY = y;
|
||||
y += (record.heightKnown ? record.height : effectiveEstimatedHeight()) + m_spacing;
|
||||
}
|
||||
|
||||
const qreal newHeight = m_layout.isEmpty() ? 0 : y - m_spacing;
|
||||
if (!qFuzzyCompare(m_contentHeight, newHeight)) {
|
||||
m_contentHeight = newHeight;
|
||||
// Content height tracks actual visible heights so scrolling follows animations
|
||||
qreal visY = 0;
|
||||
for (int i = 0; i < static_cast<int>(m_layout.size()); ++i) {
|
||||
qreal h;
|
||||
if (m_delegates.contains(i) && m_delegates[i].item)
|
||||
h = delegateVisibleHeight(m_delegates[i].item);
|
||||
else
|
||||
h = m_layout[i].heightKnown ? m_layout[i].height : effectiveEstimatedHeight();
|
||||
visY += h + m_spacing;
|
||||
}
|
||||
qreal maxBottom = m_layout.isEmpty() ? 0 : visY - m_spacing;
|
||||
|
||||
// Account for dying delegates still visually present
|
||||
for (const auto& dying : m_dyingDelegates) {
|
||||
if (dying.item)
|
||||
maxBottom = std::max(maxBottom, dying.item->y() + delegateVisibleHeight(dying.item));
|
||||
}
|
||||
|
||||
if (!qFuzzyCompare(m_contentHeight, maxBottom)) {
|
||||
m_contentHeight = maxBottom;
|
||||
emit contentHeightChanged();
|
||||
}
|
||||
}
|
||||
|
|
@ -591,12 +636,14 @@ LazyListView::DelegateEntry LazyListView::createDelegate(int modelIndex) {
|
|||
// Watch implicitHeight as fallback
|
||||
connect(entry.item, &QQuickItem::implicitHeightChanged, this, onHeightChanged);
|
||||
|
||||
// Watch attached preferredHeight if the delegate uses it
|
||||
// Watch attached properties if the delegate uses them
|
||||
auto* attached = qobject_cast<LazyListViewAttached*>(
|
||||
qmlAttachedPropertiesObject<LazyListView>(entry.item, false));
|
||||
if (attached) {
|
||||
entry.attachedConnection = connect(attached, &LazyListViewAttached::preferredHeightChanged,
|
||||
this, onHeightChanged);
|
||||
connect(attached, &LazyListViewAttached::visibleHeightChanged,
|
||||
this, [this] { polish(); });
|
||||
}
|
||||
|
||||
return entry;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ class LazyListViewAttached : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(qreal preferredHeight READ preferredHeight WRITE setPreferredHeight NOTIFY preferredHeightChanged)
|
||||
Q_PROPERTY(qreal visibleHeight READ visibleHeight WRITE setVisibleHeight NOTIFY visibleHeightChanged)
|
||||
Q_PROPERTY(bool adding READ adding NOTIFY addingChanged)
|
||||
Q_PROPERTY(bool removing READ removing NOTIFY removingChanged)
|
||||
|
||||
|
|
@ -27,6 +28,9 @@ public:
|
|||
[[nodiscard]] qreal preferredHeight() const;
|
||||
void setPreferredHeight(qreal height);
|
||||
|
||||
[[nodiscard]] qreal visibleHeight() const;
|
||||
void setVisibleHeight(qreal height);
|
||||
|
||||
[[nodiscard]] bool adding() const;
|
||||
void setAdding(bool adding);
|
||||
|
||||
|
|
@ -35,11 +39,13 @@ public:
|
|||
|
||||
signals:
|
||||
void preferredHeightChanged();
|
||||
void visibleHeightChanged();
|
||||
void addingChanged();
|
||||
void removingChanged();
|
||||
|
||||
private:
|
||||
qreal m_preferredHeight = -1;
|
||||
qreal m_visibleHeight = -1;
|
||||
bool m_adding = false;
|
||||
bool m_removing = false;
|
||||
};
|
||||
|
|
@ -209,6 +215,7 @@ private:
|
|||
[[nodiscard]] QRectF effectiveViewport() const;
|
||||
[[nodiscard]] qreal effectiveEstimatedHeight() const;
|
||||
[[nodiscard]] static qreal delegateHeight(QQuickItem* item);
|
||||
[[nodiscard]] static qreal delegateVisibleHeight(QQuickItem* item);
|
||||
void trackHeight(qreal height);
|
||||
void untrackHeight(qreal height);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue