【问题标题】:Xamarin.Forms: ListView Not Recycling CellsXamarin.Forms:ListView 不回收单元格
【发布时间】:2018-01-10 14:39:45
【问题描述】:

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

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

这是我的列表视图

    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(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;
        }
    }

【问题讨论】:

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


    【解决方案1】:

    当我根据您的代码组合一个示例时,我只创建了 6 个单元格,其中包含一千个项目,除非 menuItemGridHeight (RowHeight) 太小,在这种情况下我会实例化一千个单元格。

    你能查一下menuItemGridHeight吗?我会考虑完全删除设置 RowHeight 属性。

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

    【讨论】:

    • 行高为 100 个单位。删除设置行高的行确实使一切正常工作(非常奇怪),但现在我遇到了我的行没有正确高度的新问题。给自定义单元格的网格一个高度请求似乎也没有削减它,所以我必须找到另一种方法。
    • 好的,我现在可以正常工作了。为了给行提供适当的高度而不会导致列表视图不回收单元格的这种奇怪行为,我所做的是设置 ListView.HasUnevenRows = true 然后在我的自定义视图单元的构造函数中将继承的 Height 属性设置为我想要的高度.我仍然不知道为什么将 ListView.RowHeight 设置为 100 这样的数字会破坏单元回收。
    猜你喜欢
    • 2017-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    相关资源
    最近更新 更多