Forum Xamarin Xamarin.Android

Frame causes a Java.Lang.OutOfMemoryError

I posted a similar question to this and no answer so I thought I would scale it down to a small reproducible example.

I have a loop that adds a grid to a StackLayout for each patient (about 70 records). The grid has a column for a picture (the source of which is a url) and a column for the name. I thought it was the pictures that were causing the out of memory condition, but after hours of stepping through the code, I stumbled on what seems to be the culprit. If I wrap the grids in a frame, that seems to be an issue. I am using Xamarin 4.2.1.62.

I really do want a frame around each patient so I can have a border around each one. Anyone have any ideas?

To reproduce, create a page with a single StackLayout:

`<StackLayout  VerticalOptions="FillAndExpand" x:Name="StackPatientList"></StackLayout>`

Then, right after your InitializeComponent() call in the page, call this function:

`private void InitPatients()
{

    ObservableCollection<Patient> PatientsList = new ObservableCollection<Patient>();
    for (int i = 0; i < 100; i++)
    {
        PatientsList.Add(new Patient() { FirstName = "First " + i.ToString(), LastName = "Last " + i.ToString() });
    }

    StackLayout oStack = new StackLayout() { };
    this.StackPatientList.Children.Clear();

    foreach (Patient oPat in PatientsList)
    {
        Grid oGrid = new Grid();

        oGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(100, GridUnitType.Auto) });
        oGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });

        oGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(100, GridUnitType.Absolute) });
        oGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });

        Image oPatImage = new Image() { Source = oPat.Picture, WidthRequest = 100, HeightRequest = 100 };
        Label oPatLabel = new Label() { Text = oPat.FullName, FontSize = 15, VerticalTextAlignment = TextAlignment.Center };
        oGrid.Children.Add(oPatLabel, 0, 0);
        oGrid.Children.Add(oPatImage, 1, 0);

        Frame oFrame = new Frame() { OutlineColor = Color.Black, Padding = 5, VerticalOptions = LayoutOptions.FillAndExpand };
        oFrame.Content = oGrid;

        //this.StackPatientList.Children.Add(oGrid);  // Using this works fine
        this.StackPatientList.Children.Add(oFrame);  // This causes an out of memory error
    }

}`

This is your Patient class:

public class Patient { public string LastName { get; set; } public string FirstName { get; set; } public string FullName { get { return LastName + ", " + FirstName; } } public string Picture { get; set; } }

Run it on an android device (I use an LG-G3) and you will get an out of memory error. Then comment out the line that adds the frame and un-comment the line that just adds the grid and it will work fine.

Tagged:

Answers

  • AlexDunnAlexDunn USMember ✭✭✭

    @BobHoward the issue is similar to when many images are rendered, but with the shadows. One thing I would recommend is using a ListView instead of adding children to the StackPanel because the ListView supports virtualization. You can still use a custom DataTemplate and use a Frame as the wrapper of the list item, without hitting the OOM exception. Let me know if there is some outstanding reason why you can't use a ListView and I can try to suggest some other approaches.

  • BobHowardBobHoward USMember ✭✭

    Listview would be excellent, but I need items arranged side-by-side and wrapped vs just a vertical list. I searched high and low for such a control with no luck.

    Basically need the items to go from right-to-left then wrap to the next line when needed.

  • BobHowardBobHoward USMember ✭✭

    Anyone have any ideas of how I could use a Listview (or some other bindable control) with items that wrap from left to right?

Sign In or Register to comment.