floem icon indicating copy to clipboard operation
floem copied to clipboard

VirtualList: multiple items are selected at the same time when inserting new elements

Open dajoha opened this issue 1 year ago • 1 comments

With VirtualList, when adding new elements in the middle of the source list, 2 (or more) items can be selected at the same time, like if they were considered as the same item:

image

Can be reproduced with this code:

use floem::{
    reactive::create_signal,
    view::View,
    views::{h_stack, label, scroll, Decorators, VirtualDirection, VirtualItemSize},
    widgets::{button, virtual_list},
};

fn app_view() -> impl View {
    let long_list: im::Vector<i32> = [10, 50, 200].into_iter().collect();
    let (long_list, set_long_list) = create_signal(long_list);

    h_stack((
        button(|| "Update").on_click_stop(move |_| {
            set_long_list.set([10, 20, 50, 200].into_iter().collect());
        }),
        button(|| "Update2").on_click_stop(move |_| {
            set_long_list.set([10, 20, 35, 50, 200].into_iter().collect());
        }),
        scroll(
            virtual_list(
                VirtualDirection::Vertical,
                VirtualItemSize::Fixed(Box::new(|| 20.0)),
                move || long_list.get(),
                move |item| *item,
                move |item| label(move || item.to_string()).style(|s| s.height(20.0)),
            )
            .style(|s| s.flex_col().width_full()),
        )
        .style(|s| s.width(100.0).height_full().border(1.0)),
    ))
    .style(|s| s
        .size_full()
        .padding_vert(20.0)
        .flex_col()
        .items_center()
    )
}

fn main() {
    floem::launch(app_view);
}

Then:

  1. First click on button "Update", which creates the bug => items "20" and "50" are selected together.
  2. Click on button "Update2" => items "20" and "50" are still selected together, even when separated by other items.

dajoha avatar Apr 28 '24 10:04 dajoha

@dajoha sorry for the late reply.

This is because of the way you are using the virtual list. When using a stack or list, the items are checked for uniqueness using the key function. Because you have items that the same between the two lists, the stack isn't going to register that there has been a change on those items. You would instead need to use a different key that shows that the items are unique.

jrmoulton avatar Oct 12 '24 07:10 jrmoulton