Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 58056

Memory leaks when adding items to stacklayout

$
0
0

Hi!
I create custom control (root element is stacklayout) and have collection of custom elements. When I set collection to control from viewmodel I have started fill root element by my items: create some template for every item in collection and add it to children of root item. Here is template of my item:
(black - grid, red - layout, green - boxview)

image

Problem consist in long loading time (for ex. creation of all children are more than 2 seconds when I have around 10 items (2 max lines of text)).
What could be the problem?

Here is code of my control:

public class ContentView : StackLayout
{
    public static BindableProperty ContentsProperty = BindableProperty.Create(propertyName: "Contents", returnType: typeof(List<ContentItem>), declaringType: typeof(ContentView), defaultValue: null, propertyChanged: ContentsChanged);

    public List<ContentItem> Contents
    {
        get { return (List<ContentItem>)GetValue(ContentsProperty); }
        set { SetValue(ContentsProperty, value); }
    }

    private static void ContentsChanged(BindableObject sender, object oldValue, object newValue)
    {
        var control = sender as ContentView;
        if (control != null)
        {
            if (oldValue != null)
            {
                control.ClearContent();
            }

            if (newValue != null)
            {
                control.ApplyNewContent();
            }
        }
    }

    private void ClearContent()
    {
        this.Children.Clear();
    }

    private async void ApplyNewContent()
    {
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();

        if (this.Contents != null && this.Contents.Any())
        {
            for (int i = 0; i < this.Contents.Count; i++)
            {
                View newView = null;
                if (this.Contents[i].Image != null)
                {
                    newView = this.CreateImage(this.Contents[i].Image);
                }
                else if (this.Contents[i].Text != null)
                {
                    newView = this.CreateLabel(this.Contents[i].Text, i != this.Contents.Count - 1);
                }

                if (newView != null)
                {
                    this.Children.Add(newView);
                }
            }
        }

        System.Diagnostics.Debug.WriteLine(sw.Elapsed);
    }

    private View CreateLabel(TopicText topicText, bool isNeedAddLine)
    {
        Grid result = null;
        if (topicText != null && !string.IsNullOrEmpty(topicText.Text))
        {
            result = new Grid()
            {
                Padding = new Thickness(0),
                RowSpacing = 0,
                ColumnSpacing = 15,
            };

            var textColor = Color.FromHex("5c5c5c");
            var elementColor = Color.FromHex("03a9f4");
            if (topicText.IsNote)
            {
                textColor = Color.FromHex("61b300");
                elementColor = Color.FromHex("61b300");
            }
            else if (topicText.IsAttention)
            {
                textColor = Color.FromHex("f44336");
                elementColor = Color.FromHex("f44336");
            }

            // create 2 columns
            result.ColumnDefinitions = new ColumnDefinitionCollection()
            {
                new ColumnDefinition() { Width = GridLength.Auto},
                new ColumnDefinition(),
            };

            // grid for first colum
            var firstColumnGrid = new Grid()
            {
                Padding = new Thickness(0),
                RowSpacing = 0
            };

            firstColumnGrid.RowDefinitions = new RowDefinitionCollection() 
            {
                new RowDefinition() { Height = GridLength.Auto},
                new RowDefinition(),
            };

            // round box in top left part of item template
            var roundedBox = new RoundedBoxView()
            {
                WidthRequest = 20,
                HeightRequest = 20,
                StrokeWidth = 5,
                StrokeColor = elementColor,
                BackgroundColor = Color.White,
            };

            firstColumnGrid.Children.Add(roundedBox);
            // add bottom line if it isn't last element in list
            if (isNeedAddLine)
            {
                // vertical separator in left part of item template
                var contentView = new Frame()
                {
                    Padding = new Thickness(1, -2, 0, -2),
                };

                var line = new BoxView()
                {
                    Color = elementColor,
                    WidthRequest = 3,
                    HeightRequest = 0,
                    HorizontalOptions = LayoutOptions.Center,
                };

                contentView.Content = line;
                firstColumnGrid.Children.Add(contentView, 0, 1);
            }

            var label = new ExtendedLabel()
            {
                FontSize = 15,
                Text = topicText.Text.Trim() + "\n",
                TextColor = textColor,
                Margin = new Thickness(0, -10, 0, 0),
            };

            result.Children.Add(firstColumnGrid);
            result.Children.Add(label, 1, 0);
        }

        return result;
    }
}

Thanks!


Viewing all articles
Browse latest Browse all 58056

Trending Articles