.net MAUI 中的 CollectionView 不格式图像

问题描述 投票:0回答:1

我们有一个应用程序想要显示大量图像(超过 30 个)。由于每个图像都有一些独特的功能,因此我们使用自定义控件实现了集合视图。

集合视图允许用户将列数从一调整为三。这样可以灵活地关注单个图像或查看所有图片的更广泛概览。

每个图像不会以链接形式存储在设备上;相反,它被保存为 SQLite 数据库中的 byte[]。

<CollectionView
x:Name="CollectionView"
HorizontalScrollBarVisibility="Always"
IsVisible="{Binding ShowAttachments}"
ItemsSource="{Binding Attachments}">
<CollectionView.ItemsLayout>
    <GridItemsLayout Orientation="Vertical" Span="{Binding GirdColumns}" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
    <DataTemplate x:DataType="activity:Attachment">
        <customControls:ImageControl
            Title="{Binding Comment, Mode=TwoWay}"
            ContainerHeightRequest="200"
            FavoriteCommand="{Binding Path=UpdateFavoriteStateCommand, Source={RelativeSource AncestorType={x:Type activityDetail:ActivityDetailViewModel}}}"
            FavoriteCommandParameter="{Binding .}"
            Glyph="chat_bubble"
            ImageDoubleTappedCommand="{Binding Path=GoToEditViewOnAttachmentDoubleTappedCommand, Source={RelativeSource AncestorType={x:Type activityDetail:ActivityDetailViewModel}}}"
            ImageDoubleTappedCommandParameter="{Binding .}"
            ImageSource="{Binding Data, Converter={StaticResource ByteArrayToImageSourceConverter}}"
            ImageTappedCommand="{Binding Path=ShowAttachmentDetailCommand, Source={RelativeSource AncestorType={x:Type activityDetail:ActivityDetailViewModel}}}"
            ImageTappedCommandParameter="{Binding .}"
            ImageWidthRequest="180"
            IsFavorite="{Binding IsFavorite}"
            QuickActionCommand="{Binding Path=ShowChatCommand, Source={RelativeSource AncestorType={x:Type activityDetail:ActivityDetailViewModel}}}"
            QuickActionCommandParameter="{Binding .}" />
    </DataTemplate>
</CollectionView.ItemTemplate>

图像控制:

<Border
x:Class="SomeAwesomeNamespace.Controls.ImageControl"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Name="ImageControlItem"
Padding="5"
HeightRequest="330"
Stroke="Black"
StrokeShape="RoundRectangle 5">
<Grid BindingContext="{x:Reference ImageControlItem}">
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>

    <Image
        Grid.Row="0"
        Grid.Column="0"
        Grid.ColumnSpan="2"
        Aspect="AspectFit"
        HorizontalOptions="Center"
        MaximumHeightRequest="250"
        Source="{Binding ImageSource}"
        VerticalOptions="Start">
        <Image.GestureRecognizers>
            <TapGestureRecognizer
                Command="{Binding ImageTappedCommand}"
                CommandParameter="{Binding ImageTappedCommandParameter}"
                NumberOfTapsRequired="1" />

        </Image.GestureRecognizers>
    </Image>
    <VerticalStackLayout
        Grid.Row="0"
        Grid.RowSpan="2"
        Grid.Column="1"
        HorizontalOptions="End">

        <Button
            Margin="3"
            Padding="0"
            BackgroundColor="{StaticResource Primary}"
            Command="{Binding ImageDoubleTappedCommand}"
            CommandParameter="{Binding ImageDoubleTappedCommandParameter}"
            HeightRequest="40"
            VerticalOptions="Start"
            WidthRequest="40">
            <Button.ImageSource>
                <FontImageSource
                    FontFamily="IconFont"
                    Glyph="edit"
                    Size="20" />
            </Button.ImageSource>
        </Button>
        <Button
            Margin="3"
            Padding="0"
            BackgroundColor="{StaticResource Primary}"
            Command="{Binding FavoriteCommand}"
            CommandParameter="{Binding FavoriteCommandParameter}"
            HeightRequest="40"
            VerticalOptions="Start"
            WidthRequest="40">
            <Button.ImageSource>
                <FontImageSource
                    FontFamily="IconFont"
                    Glyph="{Binding IsFavorite, Converter={StaticResource VisibleInvisibleIconConverter}}"
                    Size="20" />
            </Button.ImageSource>
        </Button>
    </VerticalStackLayout>

    <Editor
        Grid.Row="1"
        Grid.Column="0"
        BackgroundColor="White"
        HeightRequest="80"
        HorizontalTextAlignment="Start"
        Opacity="0.7"
        Placeholder="Notiz"
        Text="{Binding Title, Mode=TwoWay}"
        VerticalOptions="End" />
    <Button
        Grid.Row="1"
        Grid.Column="1"
        Padding="5"
        BackgroundColor="{StaticResource Primary}"
        Command="{Binding QuickActionCommand}"
        CommandParameter="{Binding QuickActionCommandParameter}"
        CornerRadius="15"
        HeightRequest="30"
        HorizontalOptions="End"
        VerticalOptions="Center"
        WidthRequest="30">
        <Button.ImageSource>
            <FontImageSource
                FontFamily="IconFont"
                Glyph="{Binding Glyph}"
                Size="15"
                Color="{StaticResource White}" />
        </Button.ImageSource>
    </Button>

</Grid>

此实现的问题是,如果我们有大量图像(超过 30 个),应用程序就会滞后。此外,当使用“MPowerKit.MediaPlugin”导入图像且数量超过 10 时,应用程序崩溃并出现以下错误:

安卓 例外 - 此事件 错误 02:59:52.000 下午 RuntimeException:画布:尝试使用回收的位图 android.graphics.Bitmap@446f22f 网络事件 信息 02:59:51.623 下午

{ 操作:NETWORK_CAPABILITIES_CHANGED, 下载带宽:28154, 网络类型:蜂窝网络, 上传带宽:20245, VPN_活动:假 } 例外 致命的 02:59:51.513 下午 画布:尝试使用回收的位图 android.graphics.Bitmap@446f22f Microsoft.Maui.Controls.Xaml.Diagnostics.BindingDiagnostics 警告 02:59:50.832 下午 指定的 x:DataType (Someawesome.nampespace.Features.Activities.Attachment) 与当前绑定上下文 (Someawesome.nampespace.UI.Controls.ImageControl) 不匹配。 Microsoft.Maui.Controls.Xaml.Diagnostics.BindingDiagnostics 警告 02:59:50.823 下午 指定的 x:DataType (Someawesome.nampespace.Features.Activities.Attachment) 与当前绑定上下文 (Someawesome.nampespace.UI.Controls.ImageControl) 不匹配。 Microsoft.Maui.Controls.Xaml.Diagnostics.BindingDiagnostics 警告 02:59:50.819 下午 指定的 x:DataType (Someawesome.nampespace.Features.Activities.Attachment) 与当前绑定上下文 (Someawesome.nampespace.UI.Controls.ImageControl) 不匹配。 Microsoft.Maui.Controls.Xaml.Diagnostics.BindingDiagnostics 警告 02:59:50.811 下午 指定的 x:DataType (Someawesome.nampespace.Features.Activities.Attachment) 与当前绑定上下文 (Someawesome.nampespace.UI.Controls.ImageControl) 不匹配。 Microsoft.Maui.Controls.Xaml.Diagnostics.BindingDiagnostics 警告 02:59:50.805 下午 指定的 x:DataType (Someawesome.nampespace.Features.Activities.Attachment) 与当前绑定上下文 (Someawesome.nampespace.UI.Controls.ImageControl) 不匹配。 Microsoft.Maui.Controls.Xaml.Diagnostics.BindingDiagnostics 警告 02:59:50.797 下午 指定的 x:DataType (Someawesome.nampespace.Features.Activities.Attachment) 与当前绑定上下文 (Someawesome.nampespace.UI.Controls.ImageControl) 不匹配。

ios WatchdogTermination:操作系统看门狗终止了您的应用程序,可能是因为它过度使用了 RAM。

我们似乎在显示新添加的数据时遇到问题。有没有一种有效的方法来处理集合视图中的许多图像?

谢谢您的帮助! <3

更新:

我更改了工作流程,以便将存储在数据库中的图像复制到应用程序的目录中。

private async Task LoadImagesToLocalStorage(Guid activityId, Attachment attachment)

{ if (!string.IsNullOrWhiteSpace(attachment.LocalPath) && File.Exists(attachment.LocalPath)) { 返回; }

// Ensure the directory exists
var cacheDir = FileSystem.Current.AppDataDirectory;
var localFilePath = Path.Combine(cacheDir, attachment.Name);

if (File.Exists(localFilePath))
{
    attachment.LocalPath = localFilePath;
}
else
{
    try
    {
        // create stream from byte array    
        using MemoryStream sourceStream = new MemoryStream(attachment.Data);
        await using FileStream localFileStream = File.Open(localFilePath, FileMode.OpenOrCreate);
        await sourceStream.CopyToAsync(localFileStream);
        attachment.LocalPath = localFilePath;
    }
    catch (Exception e)
    {
        _logger.LogError(e, e.Message);
        return;
    }
}

await _attachmentDatabase.SaveAttachment(activityId, attachment, CancellationToken.None)
    .ConfigureAwait(false);

}

性能差异巨大!所以效果很好。问题是,是否有“正确”的方式保存图像,或者是否有更好的方法来创建图像的本地副本

c# android ios maui
1个回答
0
投票

最大的性能改进是将ImageSource更改为路径。 为此,我们实现了一种方法,将本地副本保存到存储中。

© www.soinside.com 2019 - 2024. All rights reserved.