You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Xamarin.Forms中设置ListView高度以显示所有项无需滚动?

实现Xamarin.Forms ListView完整显示所有项(无滚动)

嘿,这个需求我之前做项目时也碰到过,其实有几种靠谱的方案,根据你的场景选就行:

方案1:用BindableLayout替代ListView(最推荐)

ListView本身就是为滚动展示大量数据设计的,如果你不需要滚动,用BindableLayout配合StackLayout反而更省心,它会自动根据内容调整高度,完全不需要额外设置。

示例代码(XAML):

<StackLayout>
    <BindableLayout.ItemsSource>
        <x:Array Type="{x:Type x:String}">
            <x:String>列表项1</x:String>
            <x:String>列表项2</x:String>
            <x:String>列表项3</x:String>
        </x:Array>
    </BindableLayout.ItemsSource>
    <BindableLayout.ItemTemplate>
        <DataTemplate>
            <Label Text="{Binding}" Padding="10" />
        </DataTemplate>
    </BindableLayout.ItemTemplate>
</StackLayout>

如果是绑定ViewModel里的集合,直接把ItemsSource绑定到你的集合属性就行,完全不用管高度的事,StackLayout会自动撑开显示所有内容。

方案2:自定义渲染器强制ListView自适应高度

如果一定要用ListView,可以通过自定义渲染器让它自适应内容高度,同时禁用滚动:

iOS端渲染器

[assembly: ExportRenderer(typeof(ListView), typeof(NonScrollingListViewRenderer))]
namespace YourApp.iOS.Renderers
{
    public class NonScrollingListViewRenderer : ListViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
        {
            base.OnElementChanged(e);
            if (Control != null)
            {
                // 禁用滚动
                Control.ScrollEnabled = false;
                // 自动计算内容高度
                Control.SizeToFit();
            }
        }
    }
}

Android端渲染器

[assembly: ExportRenderer(typeof(ListView), typeof(NonScrollingListViewRenderer))]
namespace YourApp.Droid.Renderers
{
    public class NonScrollingListViewRenderer : ListViewRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
        {
            base.OnElementChanged(e);
            if (Control != null)
            {
                // 禁用滚动
                Control.VerticalScrollBarEnabled = false;
                Control.SetOnTouchListener(new DisableScrollListener());
                // 计算并设置总高度
                Control.Post(() =>
                {
                    int totalHeight = 0;
                    for (int i = 0; i < Control.Count; i++)
                    {
                        totalHeight += Control.GetChildAt(i)?.Height ?? 0;
                    }
                    totalHeight += Control.DividerHeight * (Control.Count - 1);
                    Control.LayoutParameters.Height = totalHeight;
                    Control.RequestLayout();
                });
            }
        }

        private class DisableScrollListener : Java.Lang.Object, Android.Views.View.IOnTouchListener
        {
            public bool OnTouch(Android.Views.View v, Android.Views.MotionEvent e)
            {
                return e.Action == Android.Views.MotionEventActions.Move;
            }
        }
    }
}

方案3:手动计算并绑定高度(适合固定项高的场景)

如果你的列表项高度是固定的,可以在ViewModel里计算总高度,然后绑定到ListView的HeightRequest属性:

ViewModel代码

private ObservableCollection<string> _items;
public ObservableCollection<string> Items
{
    get => _items;
    set
    {
        _items = value;
        OnPropertyChanged();
        // 计算总高度:每项高度 * 数量 + 分隔符高度 * (数量-1)
        ListViewHeight = 40 * Items.Count + 2 * (Items.Count - 1);
    }
}

private double _listViewHeight;
public double ListViewHeight
{
    get => _listViewHeight;
    set
    {
        _listViewHeight = value;
        OnPropertyChanged();
    }
}

XAML绑定

<ListView ItemsSource="{Binding Items}" HeightRequest="{Binding ListViewHeight}"
          VerticalOptions="Start" ScrollEnabled="False">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell Height="40">
                <Label Text="{Binding}" VerticalOptions="Center" Padding="10"/>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

提醒一下:如果列表项高度是动态的,这个方法就不太好用了,因为没法准确计算每个项的高度,这时候方案1或方案2更合适。

内容的提问来源于stack exchange,提问作者Drake

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:01:43