在iOS端的Xamarin Forms中,有一个listview。单元格由图像和文本组成。图像具有不同的大小和比例f.e. 300x200和300x350。我想使单元格自动调整内容大小,以便图像将适合整个单元格的宽度,然后根据图像的高度自动调整单元格的高度。
一种方法是计算行的高度取决于图像的高度-这是可行的解决方案,但是从服务器加载图像时速度很慢。更快的方法是将ItemsSource设置为图像url,我想采用这种方式。
我正在尝试图像处理,ffimageloading,hasUnevenRows,Aspect,将ffimageloading放入网格,缓存策略,但是图像两侧留有白带,或者图像被裁切,图像很小,滚动后将它们调整为更大的尺寸。
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:ffimageloadingsvg="clr-namespace:FFImageLoading.Svg.Forms;assembly=FFImageLoading.Svg.Forms"
x:Class="Layout.xxx.Views.iOS.CategoryPage"
x:Name="CategoryPageName">
<StackLayout>
<ListView x:Name="CategoryArticles" SeparatorVisibility="None" ItemsSource="{Binding Articles}" HasUnevenRows="True" CachingStrategy="RetainElement">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame CornerRadius="5" Margin="5,10,5,10" Padding="0">
<Grid Margin="0" Padding="0">
<StackLayout Margin="0" Orientation="Vertical" HorizontalOptions="FillAndExpand" Grid.Row="0">
<Grid HorizontalOptions="FillAndExpand" Margin="0,0,0,0">
<Grid Grid.Row="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
<ffimageloading:CachedImage Margin="0" Source="{Binding PictureUrl}" Aspect="AspectFit" ErrorPlaceholder="default_image.jpg" DownsampleToViewSize="True" />
</Grid>
<BoxView BackgroundColor="Black" HorizontalOptions="FillAndExpand" Grid.Row="0" />
<Grid HorizontalOptions="FillAndExpand" Margin="5,10,5,10" VerticalOptions="Center" Grid.Row="0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".3*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width=".3*"/>
</Grid.ColumnDefinitions>
<ffimageloadingsvg:SvgCachedImage HeightRequest="50" WidthRequest="50" Aspect="AspectFit" Source="minus_article.svg" Grid.Column="0"/>
<Label Text="{Binding Quantity}" TextColor="White" HorizontalOptions="Center" FontSize="50" Margin="10,0,10,0" Grid.Column="1"/>
<ffimageloadingsvg:SvgCachedImage x:Name="AddImage" HeightRequest="50" WidthRequest="50" Aspect="AspectFit" Source="plus.svg" Grid.Column="2"/>
</Grid>
</Grid>
<StackLayout Padding="10" Orientation="Vertical" HorizontalOptions="FillAndExpand">
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="Start">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}" Margin="0,0,10,0" HorizontalOptions="StartAndExpand" Grid.Column="0"/>
<Label Text="{Binding PriceLabel}" HorizontalOptions="End" Margin="0,0,5,0" Grid.Column="1"/>
</Grid>
</StackLayout>
</StackLayout>
</Grid>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
您还有其他想法吗?也许可以为ffimageloading定制渲染器?
答案 0 :(得分:0)
您可以在加载远程图像后在运行时更新单元格的高度。您需要调用cell.ForceUpdateSize();
来更新单元格的大小。
因此,我们使用TriggerAction
来更改此值,并告诉ViewCell更新其大小。
public class ForceUpdateSizeTriggerAction : TriggerAction<VisualElement>
{
public static readonly BindableProperty HeighRequestProperty = BindableProperty.Create(
nameof(HeighRequest),
typeof(double),
typeof(ForceUpdateSizeTriggerAction ),
60);
public double HeighRequest{
get { return (double)GetValue (HeighRequestProperty ); }
set { SetValue (HeighRequestProperty , value); }
}
public ForceUpdateSizeTriggerAction() : base()
{
}
protected override void Invoke(VisualElement sender)
{
var parent = sender.Parent;
while (parent != null && !(parent is ViewCell))
{
parent = parent.Parent;
}
if (parent is ViewCell cell)
{
Device.BeginInvokeOnMainThread(() =>
{
sender.HeightRequest = HeighRequest;
cell.ForceUpdateSize();
});
}
}
}
<Grid.Style>
<Style TargetType="Grid">
<Setter Property="HeightRequest" Value="60"/>
<Style.Triggers>
<DataTrigger TargetType="Grid" Binding="{Binding IsLoadFinished}" Value="True">
<DataTrigger.EnterActions>
<local:ForceUpdateSizeTriggerAction HeighRequest="{Binding NewHeight}" />
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<local:ForceUpdateSizeTriggerAction HeighRequest="60" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
您可以在模型中添加 IsLoadFinished 和 NewHeight 。完成从url加载图像后,更改值。