【问题标题】:ListView doesn't update Cell height in Android and iOSListView 不会更新 Android 和 iOS 中的单元格高度
【发布时间】:2020-02-01 20:30:00
【问题描述】:

我正在尝试制作一个可扩展的 ListView,但在 Android 和 iOS 中遇到问题(不工作)(在 UWP 中工作)。尝试了很多布局,还尝试在列表中创建一个列表并面临相同的结果。 Android 和 iOS 拒绝更新 Cell 的高度。

我的 Xaml

                    <ListView ItemsSource="{Binding groups}"
                          IsGroupingEnabled="true"
                          HasUnevenRows="False"
                          SelectionMode="None"
                          VerticalScrollBarVisibility="Never"  

                           >
                        <ListView.GroupHeaderTemplate>
                            <DataTemplate>
                                <ViewCell>
                                    <StackLayout  Padding="5" VerticalOptions="FillAndExpand">
                                        <StackLayout.GestureRecognizers>
                                            <TapGestureRecognizer Command="{Binding HideShowItems}" CommandParameter="{Binding .}" />
                                        </StackLayout.GestureRecognizers>
                                        <Label  Text="{Binding GroupKey}" HorizontalOptions="Center" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" VerticalOptions="FillAndExpand"/>
                                    </StackLayout>
                                </ViewCell>
                            </DataTemplate>      
                        </ListView.GroupHeaderTemplate>
                    <ListView.ItemTemplate>
                        <DataTemplate>
                                <ViewCell>
                                    <ViewCell.View>
                                        <Grid Padding="0" HeightRequest="{Binding rowHeight}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
                                            <Grid.RowDefinitions>
                                                <RowDefinition Height="*"/>
                                            </Grid.RowDefinitions>
                                            <BoxView Grid.Row="0" HorizontalOptions="FillAndExpand" 
                                                     BackgroundColor="{Binding BtnColour}"  />
                                        </Grid>
                                    </ViewCell.View>
                                </ViewCell>

                            </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>

处理更改的命令

        public Command HideShowItems => new Command(async (sender) =>
        {            
            var dropDown = sender as DropDownMenu;

            foreach(DropDownButton dr in dropDown)
            {
                if (dr.rowHeight > 0)
                {
                    while(dr.rowHeight > 0)
                    {
                        dr.rowHeight = dr.rowHeight - 5;
                        await Task.Delay(5);
                    }

                }
                else
                {
                    while(dr.rowHeight < 40)
                    {
                        dr.rowHeight = dr.rowHeight + 5;
                        await Task.Delay(5);
                    }

                }
            }
        });

尝试了很多网上找到的示例,但似乎没有一个。

仍处于学习阶段,如果您在看到代码中有任何可以做得更好的地方时提供反馈,将会很有帮助。

非常感谢!

【问题讨论】:

  • 使用 CollectionView。它应该能够比 ListView 更好地处理动态大小
  • 如果将 hasunevenrows 设置为 true 会发生什么?
  • @RodrigoJuarez 什么都没有。设置为“true”或“false”都没有关系。
  • @Jason 我对 CollectionView 有过一些不好的经历。但如果有机会,我会在未来的项目中尝试。谢谢!

标签: xamarin.forms xamarin.forms.listview


【解决方案1】:

根据你的描述,你想更新ListView Row的高度,我建议你可以绑定BoxView的高度而不是Grid。

从你的代码,我不知道DropDownMenu,所以我使用Button click来改变ListView Row,请看我的代码:

<StackLayout>
        <ListView
            HasUnevenRows="False"
            IsGroupingEnabled="true"
            ItemsSource="{Binding groups}"
            SelectionMode="None"
            VerticalScrollBarVisibility="Never">
            <ListView.GroupHeaderTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Padding="5" VerticalOptions="FillAndExpand">
                            <!--<StackLayout.GestureRecognizers>
                                <TapGestureRecognizer Command="{Binding HideShowItems}" CommandParameter="{Binding .}" />
                            </StackLayout.GestureRecognizers>-->
                            <Label
                                HorizontalOptions="Center"
                                HorizontalTextAlignment="Center"
                                Text="{Binding GroupKey}"
                                VerticalOptions="FillAndExpand"
                                VerticalTextAlignment="Center" />
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.GroupHeaderTemplate>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <ViewCell.View>
                            <Grid
                                Padding="0"
                                HorizontalOptions="FillAndExpand"
                                VerticalOptions="FillAndExpand">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" />
                                </Grid.RowDefinitions>
                                <BoxView
                                    BackgroundColor="{Binding BtnColour}"
                                    HeightRequest="{Binding rowHeight}"
                                    HorizontalOptions="FillAndExpand" />
                            </Grid>
                        </ViewCell.View>

                    </ViewCell>

                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <Button
            x:Name="btn1"
            Clicked="Btn1_Clicked"
            Text="change listview row height" />
    </StackLayout>

 public partial class Page1 : ContentPage
{
    public ObservableCollection<GroupModel> groups { get; set; }

    public Page1()
    {
        InitializeComponent();

        groups = new ObservableCollection<GroupModel>();
        var group1 = new GroupModel() { GroupKey = "Group 1 key" };
        var group2 = new GroupModel() { GroupKey = "Group 2 key" };
        group1.Add(new model1() { rowHeight = 20, BtnColour = Color.Red });
        group1.Add(new model1() { rowHeight = 30, BtnColour = Color.Blue });
        group1.Add(new model1() { rowHeight = 40, BtnColour = Color.Green });

        group2.Add(new model1() { rowHeight = 20, BtnColour = Color.Gray });
        group2.Add(new model1() { rowHeight = 30, BtnColour = Color.Black });
        group2.Add(new model1() { rowHeight = 50, BtnColour = Color.Gold });

        groups.Add(group1);
        groups.Add(group2);
        this.BindingContext = this;


    }

    private void Btn1_Clicked(object sender, EventArgs e)
    {
        groups[0][0].rowHeight = 60;
    }
}


public class GroupModel:ObservableCollection<model1>
{
    public string GroupKey { get; set; }
}
public class model1:ViewModelBase
{
    private double _rowHeight;
    public double rowHeight
    {
        get { return _rowHeight; }
        set
        {
            _rowHeight = value;
            RaisePropertyChanged("rowHeight");
        }
    }


    public Color BtnColour { get; set; }
}

ViewModelBase 是实现 INotifyPropertychanged 接口的类。

 public class ViewModelBase : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler PropertyChanged;

          public void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

【讨论】:

  • 卜。非常感谢您的回复,但这不是我想要的结果。列表视图的行不会改变高度。我共享的代码在 UWP 中以这种方式工作,我也希望在其他平台上使用这种方式。 Video
  • 嗨,卜!我已经使用基本形式重新创建了整个东西,并让它按照我想要的方式工作。希望有人可以使用 ListView 做到这一点,因为代码更干净,更易于阅读。
  • @Andrei,看来你的问题已经解决了?如果是的话,您可以给一个回复并将您的回复标记为答案,或者您可以将一个有用的回复标记为答案,这对面临相同问题的其他社区成员有所帮助,谢谢。
  • @Cherry Bu。我通过创建其他做同样事情的东西解决了这个问题。它没有回答这个问题。不过,我会把代码放上来……但不能接受任何正确的答案……甚至我的也不行。
【解决方案2】:

我已经使用其他 Xamarin 表单创建了所需的逻辑。这并不是说我已经回答了有关 ListView 的问题,并且更改可能需要由 Xamarin 团队完成,但这就是我创建可扩展列表的目的。

XAML

        <ScrollView x:Name="ScrollActivity"  VerticalScrollBarVisibility="Never" >
            <Grid x:Name="GridContent" >
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="20*"/>
                <ColumnDefinition Width="80*"/>

            </Grid.ColumnDefinitions>

            <StackLayout BackgroundColor="#f0dfe2" x:Name="buttonHolder" BindableLayout.ItemsSource="{Binding sideMenu}" >
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            <StackLayout BackgroundColor="#f0dfe2">
                                <StackLayout HeightRequest="50" BackgroundColor="#38292c">
                                    <StackLayout.GestureRecognizers>
                                        <TapGestureRecognizer Command="{Binding Source={x:Reference buttonHolder}, Path=BindingContext.ShowHideCommand}"  
                                                              CommandParameter="{Binding .}"/>


                                    </StackLayout.GestureRecognizers>
                                    <Label FontSize="Medium" HorizontalOptions="Center" VerticalOptions="Center" HorizontalTextAlignment="Center" VerticalTextAlignment="Center"  TextColor="White" Text="{Binding title}"/>
                                </StackLayout>


                                    <StackLayout HeightRequest="{Binding rowHeight}" 

                                                 BindableLayout.ItemsSource="{Binding device}" >
                                        <BindableLayout.ItemTemplate>
                                            <DataTemplate>
                                            <Frame Padding="0" CornerRadius="10">
                                                <Frame.GestureRecognizers>
                                                    <PanGestureRecognizer PanUpdated="PanGestureRecognizer_PanUpdated_1">

                                                    </PanGestureRecognizer>
                                                </Frame.GestureRecognizers>

                                                <Grid HeightRequest="40" BackgroundColor="{Binding btnBkColour}" IsVisible="{Binding visibility}" >

                                                    <Label HorizontalOptions="Center" VerticalOptions="Center" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" TextColor="White" Text="{Binding deviceTitle}" />
                                                </Grid>
                                            </Frame>
                                        </DataTemplate>
                                        </BindableLayout.ItemTemplate>
                                    </StackLayout >

                            </StackLayout>

                        </DataTemplate>
                    </BindableLayout.ItemTemplate>
                </StackLayout >




        </Grid>
        </ScrollView>

处理扩展的命令

        public Command ShowHideCommand => new Command(async (sender) =>
        {
            var sideMenu = sender as SideMenuObject;

            if (changeTriggered == false)
            {

                changeTriggered = true;
                if (sideMenu.rowHeight > 0)
                {
                    foreach (SideMenuDevice dev in sideMenu.device)
                    {
                        dev.visibility = false;

                        while (sideMenu.rowHeight >(sideMenu.device.Count - (sideMenu.device.IndexOf(dev) + 1))*40)
                        {
                            sideMenu.rowHeight = sideMenu.rowHeight - 5;
                            await Task.Delay(5);
                        }

                    }

                }
                else
                {
                    foreach (SideMenuDevice dev in sideMenu.device)
                    {
                        while (sideMenu.rowHeight <= (sideMenu.device.IndexOf(dev) +1 ) *40)
                        {
                        sideMenu.rowHeight = sideMenu.rowHeight + 5;
                        await Task.Delay(5);
                        }
                        dev.visibility = true;
                    }
                }
            }

            changeTriggered = false;
        });

如果可以,请提供反馈!

【讨论】:

    【解决方案3】:
    1. 确保 HasUnevenRows="true" 到您的 listview.HasUnevenRows 属性将用于根据单元格中存在的内容扩展单元格高度。

    2. 对网格应用填充。 例如:&lt;Grid Padding="5"&gt;

    【讨论】:

    • @Priyanka 谢谢。之前测试过,还是不行。设置为“false”只是因为我没有想法想测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-06
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    相关资源
    最近更新 更多