Always re-render visible elements in List

This commit is contained in:
Antonio Scandurra 2022-05-31 09:52:44 +02:00
parent 0fd47da880
commit e067212ad4

View file

@ -131,13 +131,24 @@ impl Element for List {
let mut cursor = old_items.cursor::<Count>(); let mut cursor = old_items.cursor::<Count>();
cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &()); cursor.seek(&Count(scroll_top.item_ix), Bias::Right, &());
for (ix, item) in cursor.by_ref().enumerate() { for (ix, item) in cursor.by_ref().enumerate() {
if rendered_height - scroll_top.offset_in_item >= size.y() + state.overdraw { let visible_height = rendered_height - scroll_top.offset_in_item;
if visible_height >= size.y() + state.overdraw {
break; break;
} }
if let Some(element) = // Force re-render if the item is visible, but attempt to re-use an existing one
state.render_item(scroll_top.item_ix + ix, item, item_constraint, cx) // if we are inside the overdraw.
{ let existing_element = if visible_height >= size.y() {
Some(item)
} else {
None
};
if let Some(element) = state.render_item(
scroll_top.item_ix + ix,
existing_element,
item_constraint,
cx,
) {
rendered_height += element.size().y(); rendered_height += element.size().y();
rendered_items.push_back(ListItem::Rendered(element)); rendered_items.push_back(ListItem::Rendered(element));
} }
@ -151,9 +162,9 @@ impl Element for List {
if rendered_height - scroll_top.offset_in_item < size.y() { if rendered_height - scroll_top.offset_in_item < size.y() {
while rendered_height < size.y() { while rendered_height < size.y() {
cursor.prev(&()); cursor.prev(&());
if let Some(item) = cursor.item() { if cursor.item().is_some() {
if let Some(element) = if let Some(element) =
state.render_item(cursor.start().0, item, item_constraint, cx) state.render_item(cursor.start().0, None, item_constraint, cx)
{ {
rendered_height += element.size().y(); rendered_height += element.size().y();
rendered_items.push_front(ListItem::Rendered(element)); rendered_items.push_front(ListItem::Rendered(element));
@ -189,7 +200,7 @@ impl Element for List {
cursor.prev(&()); cursor.prev(&());
if let Some(item) = cursor.item() { if let Some(item) = cursor.item() {
if let Some(element) = if let Some(element) =
state.render_item(cursor.start().0, item, item_constraint, cx) state.render_item(cursor.start().0, Some(item), item_constraint, cx)
{ {
leading_overdraw += element.size().y(); leading_overdraw += element.size().y();
rendered_items.push_front(ListItem::Rendered(element)); rendered_items.push_front(ListItem::Rendered(element));
@ -426,11 +437,11 @@ impl StateInner {
fn render_item( fn render_item(
&mut self, &mut self,
ix: usize, ix: usize,
existing_item: &ListItem, existing_element: Option<&ListItem>,
constraint: SizeConstraint, constraint: SizeConstraint,
cx: &mut LayoutContext, cx: &mut LayoutContext,
) -> Option<ElementRc> { ) -> Option<ElementRc> {
if let ListItem::Rendered(element) = existing_item { if let Some(ListItem::Rendered(element)) = existing_element {
Some(element.clone()) Some(element.clone())
} else { } else {
let mut element = (self.render_item)(ix, cx)?; let mut element = (self.render_item)(ix, cx)?;