ios - Xamarin Forms iOS listview 的单元格自动调整其内容大小(图片来自 url)

标签 ios forms listview xamarin autosize

在 iOS 端的 Xamarin Forms 中,有一个 ListView 。单元格由图像和文本组成。这些图像的尺寸和比例不同。 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 的自定义渲染器?

最佳答案

加载远程图像后,您可以在运行时更新单元格的高度。您需要调用 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>

您可以将 IsLoadFinishedNewHeight 添加到您的模型中。并在完成从 url 加载图像后更改值。

关于ios - Xamarin Forms iOS listview 的单元格自动调整其内容大小(图片来自 url),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58282316/

相关文章:

ios - 未知异常: signal SIGPIPE with crash when device is unlocked after locked screen

forms - 如何在 ember.js 中使用 ajax 发送 Post 请求?

javascript - form.on ('submit' ) 不会在 form.submit() 之前触发

ruby-on-rails - 复选框未以 Rails 形式保持选中状态

android - 带有 4 个 TextView 的 ListView

ios - 在不登录开发者帐户的情况下在 Xcode 6 中进行临时构建

ios - 如何检测 UIWebView 何时完全完成加载?

Flutter:ListView.builder 中的自动垂直高度

ios - 启用抗锯齿后,使用不同颜色在 drawRect 中绘制重叠形状会导致边缘出血

Android:如何根据所选列表项更改可绘制对象