【问题标题】:There is more space than I need in ListViewListView 中的空间比我需要的多
【发布时间】:2016-11-30 19:48:57
【问题描述】:

我正在使用 StackLayout 和 ListView 来显示视图的某些部分,但 ListView 占用的空间超出了我的需要,并且在列表的最后一行和配置文件延续之间留下了一个空白空间。似乎我的 ListView 的行数比实际列表的长度多,或者它有一个固定的高度,我不知道......这是我的 XAML:

<ScrollView>
  <StackLayout Orientation="Vertical" Spacing="10">

    <Label Text="{Binding Establishment.Name}" TextColor="Black" HorizontalOptions="StartAndExpand" Style="{DynamicResource TitleStyle}" FontAttributes="Bold"/>

    <Label Text="{Binding Establishment.Category.Name,  StringFormat='Categoria: {0}'}" TextColor="Black" HorizontalOptions="StartAndExpand"  FontAttributes="Bold"/>

    <Label Text="{Binding Establishment.Description}" TextColor="Black" HorizontalOptions="StartAndExpand" LineBreakMode="WordWrap" XAlign="Start"/>

    <Label Text="Contatos" TextColor="Black" HorizontalOptions="StartAndExpand"  FontAttributes="Bold"/>

    <ListView  ItemsSource="{Binding Establishment.Contacts}" VerticalOptions="Start" HasUnevenRows="True">
      <ListView.ItemTemplate>
        <DataTemplate>
          <TextCell Text="{Binding Value}" Detail="{Binding StringType}" DetailColor="Gray"/>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>

    <Label Text="Endereço" TextColor="Black" HorizontalOptions="StartAndExpand"  FontAttributes="Bold"/>

    <Label Text="{Binding Establishment.FullAddress}" TextColor="Black" HorizontalOptions="StartAndExpand"  />

    <Button Text="Ver no mapa"/>

  </StackLayout>
</ScrollView>

我该如何解决?我看到有人使用HasUnevenRows="True",但它对我不起作用。

【问题讨论】:

  • 您是否尝试过在 ListView 上设置 HeightRequest 值?

标签: c# .net listview xamarin xamarin.forms


【解决方案1】:

首先,Xamarin 建议不要将 ListView 放在 ScrollView 中,因为它们都提供滚动和相互竞争。我亲自尝试过,它经常会导致奇怪的行为,尤其是在 Android 上。

相反,我将ListView.HeaderListView.HeaderTemplateListView.FooterListView.FooterTemplate 一起使用。 Xamarin 链接here 这允许您的确切情况,但没有奇怪的行为问题。如果你想看一个例子,请告诉我。

如果您必须使用当前的布局,您可以尝试查看this 帖子,讨论如何使用特定的HeightWidthLayoutOptions 调整ListView 的大小它不应该适合其内容的大小。那篇文章中有几个解决方案,我还没有尝试过。

this 中发布给出的解决方法之一,将ListView 添加到StackLayout 并将其添加到另一个StackLayout。然后将内部StackLayoutVerticalOptions设置为LayoutOptions.FillAndExpand

所以它可能看起来像这样:

<ScrollView>
  <StackLayout Orientation="Vertical" Spacing="10">

    ....

    <StackLayout VerticalOptions="FillAndExpand">
      <ListView ItemsSource="{Binding Establishment.Contacts}" VerticalOptions="Start" HasUnevenRows="True">
        <ListView.ItemTemplate>
          <DataTemplate>
            <TextCell Text="{Binding Value}" Detail="{Binding StringType}" DetailColor="Gray"/>
          </DataTemplate>
        </ListView.ItemTemplate>
      </ListView>
    </StackLayout>

    ....

  </StackLayout>
</ScrollView>

【讨论】:

  • 你觉得我的解决方案怎么样?
【解决方案2】:

正如 hvaughan3 所说,这确实不是一个好习惯。但我有同样的情况,我使用了行为的解决方法:

public class ListViewHeightBehavior : Behavior<ListView>
{
    private ListView _listView;

    public static readonly BindableProperty ExtraSpaceProperty =
        BindableProperty.Create(nameof(ExtraSpace),
                                typeof(double),
                                typeof(ListViewHeightBehavior),
                                0d);

    public double ExtraSpace
    {
        get { return (double)GetValue(ExtraSpaceProperty); }
        set { SetValue(ExtraSpaceProperty, value); }
    }

    protected override void OnAttachedTo(ListView bindable)
    {
        base.OnAttachedTo(bindable);

        _listView = bindable;
        _listView.PropertyChanged += (s, args) =>
        {
            var count = _listView.ItemsSource?.Count();
            if (args.PropertyName == nameof(_listView.ItemsSource)
                    && count.HasValue
                    && count.Value > 0)
            {
                _listView.HeightRequest = _listView.RowHeight * count.Value + ExtraSpace;
            }
        };
    }
}

XAML:

     <ListView ItemsSource="{Binding Items}"
               HasUnevenRows="True">
      <ListView.Behaviors>
        <behaviors:ListViewHeightBehavior ExtraSpace="180"/>
      </ListView.Behaviors>
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
             // Your template
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>

【讨论】:

  • 你觉得我的解决方案怎么样?
  • 如果只有5个项目,所以我希望这没什么大不了的。但我的行为对我有利,我认为,你在实施过程中遗漏了一些东西。
  • 可以。当我调试您的解决方案时,它对我有用,但我不知道为什么 RowHeight 有时会以 -1 的形式出现:/
【解决方案3】:

谢谢你们,但对我没有任何帮助。我自己认为的解决方案肯定不是最好的,但它对我有用.....

在 XAML 中,我留下了一个空的 StackLayout,如下所示:

    <StackLayout x:Name="ContactsList" Orientation="Vertical" Spacing="10" Padding="8,0">
      <!-- Empty because it will be filled in code mode -->
    </StackLayout>

然后,在 .cs 文件中,我在 InitializeComponent() 方法之后调用了这个方法:

    private void setUpContacts(Establishment establishment)
    {
        foreach(Contact contact in establishment.Contacts)
        {
            StackLayout row = new StackLayout
            {
                Orientation = StackOrientation.Vertical
            };

            row.Children.Add(new Label
            {
                TextColor = Color.Gray,
                Text = string.Format("{0}:", contact.StringType)
            });

            row.Children.Add(new Label
            {
                TextColor = Color.Black,
                FontAttributes = FontAttributes.Bold,
                Text = contact.Value,
            });

            row.GestureRecognizers.Add(new TapGestureRecognizer {
                Command = new Command(() => OnContactTapped(row, contact))
            });

            ContactsList.Children.Add(row);
        }
    }

我这样做是因为列表不是真正的 ListView,因为我不需要直接在列表中滚动功能,它只是视图的另一部分。我认为它不会导致任何性能问题,因为它的项目数量很少(最多 5 个)。我将此标记为正确答案,以帮助其他人解决此问题。

请,如果这是一个对其他人不起作用的解决方案,请告诉我,我会找到另一种方法来做到这一点。

【讨论】:

  • 如果列表中只有几件事,我认为您的解决方案很好,特别是如果它适合您。我在代码的不同位置使用Grid 做了一些类似的事情。感谢您发布解决方法。
【解决方案4】:

我对 Yehor Hromadskyi 的解决方案有疑问。

  • 首先,IEnumerable 没有 Count 方法。它必须首先转换为 IEnumerable
  • 其次,如果您不设置 RowHeight,那么整个列表就会崩溃,您会遇到相反的问题。

以下是解决这些问题的代码更改

public class ListViewHeightBehavior : Behavior<ListView>
{
    private ListView _listView;

    public static readonly BindableProperty ExtraSpaceProperty =
        BindableProperty.Create(nameof(ExtraSpace),
                                typeof(double),
                                typeof(ListViewHeightBehavior),
                                0d);

    public static readonly BindableProperty DefaultRowHeightProperty =
        BindableProperty.Create(nameof(DefaultRowHeight),
                          typeof(int),
                          typeof(ListViewHeightBehavior),
                          40);

    public int DefaultRowHeight
    {
        get => (int)GetValue(DefaultRowHeightProperty);
        set => SetValue(DefaultRowHeightProperty, value);
    }
    public double ExtraSpace
    {
        get { return (double)GetValue(ExtraSpaceProperty); }
        set { SetValue(ExtraSpaceProperty, value); }
    }

    protected override void OnAttachedTo(ListView bindable)
    {
        base.OnAttachedTo(bindable);

        _listView = bindable;
        _listView.PropertyChanged += (s, args) =>
        {
            var count = _listView.ItemsSource?.Cast<object>()?.Count();
            if (args.PropertyName == nameof(_listView.ItemsSource)
                    && count.HasValue
                    && count.Value > 0)
            {
                int rowHeight = _listView.RowHeight > 0 ? _listView.RowHeight : DefaultRowHeight;
                _listView.HeightRequest = rowHeight * count.Value + ExtraSpace;
            }
        };
    }
}

【讨论】:

    【解决方案5】:

    示例布局显示,您在 ScrollView 中使用 ListView 并且 ListView 有不同高度的子 (HasUnevenRows="True")

    <ScrollView>
         <ListView HasUnevenRows="True">
         </ListView>
    </ScrollView>
    

    这会导致列表的最后一行和 ScrollView 之间出现空白。

    因为您已经以 root 身份添加了滚动视图。您可以使用 StackLayout (BindableLayout) 用于相同目的。

    <ScrollView>
        <StackLayout
            x:Name="DummyList"
            BindableLayout.ItemsSource="{Binding ContactList}"
            Orientation="Vertical">
            <BindableLayout.ItemTemplate>
                <DataTemplate>
                    <TextCell
                        Detail="{Binding StringType}"
                        DetailColor="Gray"
                        Text="{Binding Value}" />
                </DataTemplate>
            </BindableLayout.ItemTemplate>
        </StackLayout>
    </ScrollView>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-27
      • 2020-10-29
      • 2021-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多