ListView 项目在 Xamarin 表单中不展开折叠高度
Posted
技术标签:
【中文标题】ListView 项目在 Xamarin 表单中不展开折叠高度【英文标题】:ListView Item doesn't expand-collapse height in Xamarin Forms 【发布时间】:2018-12-07 18:19:42 【问题描述】:我有一个列表视图。在 ListView 我有 ListViewCell。 ListViewCell 具有展开折叠功能。展开折叠行为的问题很少。
1- 如果我展开第一项,它工作正常。但是,如果我先展开第二项并展开第一项,则第一项落后。请参阅屏幕截图中的案例 1。
2- 如果我单击列表视图项,它会以灰色显示一秒钟。我想阻止这一切。当用户单击任何单元格时,它不应更改和着色。案例2
3- 如果我展开第一个项目并再次折叠它。它会折叠,但会在第二项和第一项之间保留空白。
我注意到了这种行为。如果我向下和向上滚动,上述问题将解决。好吧,在理想情况下,用户不会在每次操作后上下滚动:D
注意:我在 ListViewCell 中有条目、日期选择器和按钮。用户必须能够输入。
这是我的代码。我还附上了屏幕截图。请推荐
主页列表视图
<ListView x:Name="WorkHistoryListView"
ItemsSource="Binding WorkHistoryList"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
SeparatorVisibility="None"
ItemTapped="OnListViewItemTapped"
Margin="10"
HasUnevenRows = "true"
IsPullToRefreshEnabled="False">
<ListView.ItemTemplate>
<DataTemplate>
<localview:WorkHistoryViewCell />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
WorkHistoryViewCell.xaml
<StackLayout Margin="0" Padding="0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<!-- Blue heading-->
<StackLayout Margin="0" Padding="0" Grid.Row="0" BackgroundColor="#367fa9">
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
Padding="15" RowSpacing="10" Margin="0" BackgroundColor="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Label Text="Binding Name" HorizontalOptions="Center" Grid.Column="0" Grid.Row="0"/>
<Label Text="Binding Date" HorizontalOptions="Center" Grid.Column="1" Grid.Row="1"/>
<Label Text="+" HorizontalOptions="End" VerticalOptions="Center" Grid.Column="2" x:Name="LabelCollapse" Grid.Row="0" Grid.RowSpan="2" FontFamily="Roboto">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="LabelOpenCommand"/>
</Label.GestureRecognizers>
</Label>
</Grid>
</StackLayout>
<StackLayout Margin="0" Padding="0" Grid.Row="1" x:Name="FrameVisible">
<Frame Margin="0" Padding="0" HorizontalOptions="FillAndExpand" BackgroundColor="White" OutlineColor="Gray">
<StackLayout Margin="0" VerticalOptions="Fill" Padding="20" IsVisible="Binding IsWeekly">
<Grid>
<Grid.Resources>
<ResourceDictionary>
<local:InvertBooleanConverter x:Key="invertBooleanConverter" />
<Style x:Key="LabelStyle" TargetType="Label">
<Setter Property="FontSize" Value="15"/>
<Setter Property="FontFamily" Value="Roboto"/>
<Setter Property="TextColor" Value="White"/>
</Style>
</ResourceDictionary>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="125"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Image Source="EditLog.png" Grid.Column="1" Grid.Row="0" HorizontalOptions="End" VerticalOptions="Center"
HeightRequest="24">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="OnImageViewItemTapped"/>
</Image.GestureRecognizers>
</Image>
<Label Text="Date" Grid.Column="0" Grid.Row="0" Style="StaticResource LabelStyle"
TextColor="Black" FontFamily="Roboto" Margin="0" />
<local:ExtendedDatePicker TextColor="LightGray" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1"
IsEnabled="False" Date="Binding Date" BackgroundColor="White">
<DatePicker.Format>dd/MM/yyyy</DatePicker.Format>
</local:ExtendedDatePicker>
<Label Text="Pay" Grid.Column="0" Grid.Row="2" Style="StaticResource LabelStyle"
TextColor="Black" FontFamily="Roboto" Margin="0,10,0,0" />
<local:CustomEntry Grid.Column="0" Grid.Row="3" Margin="0,10,0,0" WidthRequest="150" Text="Binding Pay"
Style="StaticResource LabelStyle" TextColor="Black" HorizontalOptions="EndAndExpand" VerticalOptions="FillAndExpand"/>
<Button Text="Submit" BorderRadius="18" TextColor="White" Command="Binding SubmitWeeklyCommand" Grid.Column="0" Grid.Row="4" FontFamily="Roboto"/>
</Grid>
</StackLayout>
</Frame>
</StackLayout>
</Grid>
</StackLayout>
WorkHistoryViewCell.xaml.cs //命令展开折叠
private void LabelOpenCommand(object sender,TappedEventArgs e)
if (LabelCollapse.Text == "+")
FrameVisible.IsVisible = false;
LabelCollapse.Text = "-";
FrameVisible.IsVisible = true;
else
FrameVisible.IsVisible = true;
LabelCollapse.Text = "+";
FrameVisible.IsVisible = false;
截图
【问题讨论】:
【参考方案1】:发生这种情况是因为 单元格的高度 仅在第一次渲染时计算。之后,更改只影响内部布局视图。
尝试在当前TappedCommand
的逻辑结束时调用ForceUpdateSize();
。它将强制整个单元格重新计算其边界。
代码应如下所示:
private void LabelOpenCommand(object sender,TappedEventArgs e)
if (LabelCollapse.Text == "+")
FrameVisible.IsVisible = false;
LabelCollapse.Text = "-";
FrameVisible.IsVisible = true;
else
FrameVisible.IsVisible = true;
LabelCollapse.Text = "+";
FrameVisible.IsVisible = false;
ForceUpdateSize
希望对你有帮助。
【讨论】:
谢谢。ForceUpdateSize
需要 2-3 秒才能获得更新的大小。通常,Accordian 不应该占用这样的时间,因为存在操作而不是隐藏显示。所以,如果有人问我为什么要花时间,很难解释。请提出您的想法!
确实不需要太多时间。整个ViewCell
看起来很沉重,但即使如此,2-3 秒也是不可接受的。您是否尝试过异步执行此操作?你是在为@Developer说话吗?
@DiegoRafaelSouza 我也对此进行了审查。第一次,它需要 1-2 秒,我想这很好。如果用户尝试展开折叠 2-3 次,它会变得非常慢,需要 3-4 秒才能展开折叠。此延迟问题仅适用于 ios。它在 UWP 和 android 中运行良好。我认为它在 iOS 中应该可以正常工作,因为它是我们的主要目标。你提到了异步。我怎样才能做到这一点?我已经按照您在回答中给出的确切代码。你能用异步代码更新你的答案吗?谢谢。
@Developer 很抱歉迟到了。只是将方法的签名更改为private async void LabelOpenCommand(...) ...
。 iOS上没试过,安卓上就试过了,反应也够快的。
@DiegoRafaelSouza,这没有任何改变。是的,你是对的,它在 Android 中运行得非常快。在 iOS 中仍然需要时间。我试图将这一行 CachingStrategy="RecycleElement
放在我的 Listview 中,它开始正常工作。但是它引发了另一个问题:当我展开第一个项目(viewcell)时,它还会展开下一个屏幕上的其他单元格。有什么建议吗?以上是关于ListView 项目在 Xamarin 表单中不展开折叠高度的主要内容,如果未能解决你的问题,请参考以下文章
如何选择项目 MVVM listview - Xamarin 表单
更新 ObservableCollection 无法正确更新 Xamarin 表单中的 ListView