Xamarin.Forms:ListView不回收单元格

时间:2017-08-03 06:36:57

标签: listview xamarin.forms out-of-memory

我正在使用ListView来显示一长串自定义ViewCell。我正在使用ListViewCachingStrategy.RecycleElement,以便仅加载可见单元格并在它们离开屏幕时回收它们。它不起作用。

我的自定义viewcell的构造函数中的断点显示它被调用的次数与ListView的ItemSource中的项目一样多,因此我知道它为每个项目而不仅仅是可见的项目实例化一个单元格。那是不对的。此外,如果我的单元格内存足够重,那么应用程序崩溃,因为它无法为所有单元格分配足够的内存。

这是我的ListView

    menuContainer.Content = new ListView(ListViewCachingStrategy.RecycleElement) 
    {
        ItemsSource = menuItems, // about 800 objects
        ItemTemplate = new DataTemplate(typeof(CustomCell)),
        RowHeight = (int)menuItemGridHeight 
    };

这是我的自定义ViewCell,只是一个带按钮的网格

    class CustomCell : ViewCell
    {
        public CustomCell()
        {
            Button button = new Button
            {
                BorderRadius = 0,
                BackgroundColor = Color.Transparent
            };

            Grid grid = new Grid
            {
                ColumnSpacing = 0,
                BackgroundColor = Color.FromRgba(255, 255, 255, 0.8),
                ColumnDefinitions = new ColumnDefinitionCollection
                {
                    new ColumnDefinition { Width = new GridLength(15, GridUnitType.Star) },
                    new ColumnDefinition { Width = new GridLength(100, GridUnitType.Star) }
                }
            };

            grid.Children.Add(button, 1, 0);

            View = grid;
        }
    }

在Android模拟器上我得到一个Java.Lang.OutOfMemoryError。 iOS似乎有足够的备用内存,不会崩溃。我还验证了应用程序正在加载ItemSource中的所有对象,所以我知道问题是为所有单元对象分配内存,而不是ItemSource对象。

为什么我的ListView不能回收其ViewCells?

编辑:这是有效的代码。单元格可以按原样回收,并保持适当的高度。

ListView ...

ListView(ListViewCachingStrategy.RecycleElement) 
    {
        ItemsSource = menuItems, // about 800 objects
        ItemTemplate = new DataTemplate(typeof(CustomCell)),
        HasUnevenRows = true
    };

自定义视图单元格......

    class CustomCell : ViewCell
    {
        public CustomCell()
        {
            Height = 100;

            Button button = new Button
            {
                BorderRadius = 0,
                BackgroundColor = Color.Transparent
            };

            Grid grid = new Grid
            {
                ColumnSpacing = 0,
                BackgroundColor = Color.FromRgba(255, 255, 255, 0.8),
                ColumnDefinitions = new ColumnDefinitionCollection
                {
                    new ColumnDefinition { Width = new GridLength(15, GridUnitType.Star) },
                    new ColumnDefinition { Width = new GridLength(100, GridUnitType.Star) }
                }
            };

            grid.Children.Add(button, 1, 0);

            View = grid;
        }
    }

1 个答案:

答案 0 :(得分:1)

当我根据你的代码整理一个样本时,除了menuItemGridHeightRowHeight)太小外,我只会创建六个单元格,在这种情况下,我得到一千个单元格实例化。

您可以查看menuItemGridHeight吗?我会考虑完全删除RowHeight属性。

0或1的值得到你的行为...... 100不...不确定截止位置在哪里,但我认为在决定是否可以重复使用单元格时,它会查看现有单元格是否会适合要呈现的新项目的内容。