nix
nix

Reputation: 2285

How to extend ListView to auto-resize itself?

After finding out that there is not clear way to resize ListView to fit the content, I decided to extend ListView to resize itself every time the child is added. I tried this code but it didn't work. What could be the problem? How can I resolve it?

public class SmartListView : ListView
{
    public SmartListView() : base()
    {
        ChildAdded += Resize;
    }

    private void Resize(object sender, ElementEventArgs e)
    {
        HeightRequest = Height + ((ViewCell)sender).Height;
    }
}

However the callback Resize is never even hit.

Upvotes: 3

Views: 3183

Answers (2)

Rodrigo Elias
Rodrigo Elias

Reputation: 783

Subscribe to CollectionChanged of your ObservableCollection to something like this:

MyObservableCollection.CollectionChanged += (sender, e) =>
            {
                var adjust = Device.OS != TargetPlatform.Android ? 1 : -MyObservableCollection.Count + 1;
                myListView.HeightRequest = (MyObservableCollection.Count * myListView.RowHeight) - adjust;
            };

Upvotes: 5

YumeYume
YumeYume

Reputation: 991

I faced a similar problem but with Xamarin.Android. I'll still post my solution, but I can't gurarantee that it'll work with Forms.

This code is calculating the height based on the ListView's content, by making a sum of all children's height, then applying it to the ListView itself.

EDIT : Not working directly on Xamarin.Forms, as Adapters seems to be specific to Xamarin.Android. As I never used Xamarin.Forms, I can't modify my code, but you can use it as a base. You will need to adapt the code to get the children as Views somehow, then do the height calculation.

public static void SetListViewHeightBasedOnChildren(ListView list)
{
    var adapter = list.Adapter;
    if (adapter == null) {
        return;
    }

    int height = 0;
    for (int i = 0; i < adapter.Count; i++) {
        View listItem = adapter.GetView(i, null, list);
        listItem.Measure(0, 0);
        height += listItem.MeasuredHeight;
    }

    ViewGroup.LayoutParams parameters = list.LayoutParameters;
    parameters.Height = height + (list.DividerHeight * adapter.Count);
    list.LayoutParameters = parameters;
}

You can call this code when adding a child to your view. Never used the ChildAdded event though. You might want to try calling this method manually after adding a child.

Upvotes: 0

Related Questions