首页 > 解决方案 > Xamarin Forms 调整图像宽度以填充堆栈布局而无需顶部和底部剪辑

问题描述

这是我拥有的当前代码:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="WPapp.Views.Post">
    <ContentPage.Content>
        <ScrollView>
            <StackLayout Margin="10"
                         HorizontalOptions="Center"
                         VerticalOptions="FillAndExpand"
                         x:Name="PostContainer">
                <Image x:Name="FeaturedImage"
                       HorizontalOptions="Center"/>
                <Label x:Name="Title"
                       FontSize="Title"
                       FontAttributes="Bold"
                       Margin="0, 20, 0, 10"/>
                <Label x:Name="PostMeta"
                       FontSize="Caption"
                       FontAttributes="None"
                       Margin="0, 0, 0, 0"/>
            </StackLayout>
        </ScrollView>
    </ContentPage.Content>
</ContentPage>

Image image = new Image();
image.Source = imageSource;
image.Aspect = Aspect.AspectFill;
PostContainer.Children.Add(image);

这是图像:

图片

这是结果:

结果

图像正在按预期水平填充。

问题是,图像被垂直裁剪。如何防止图像被剪裁以及如何在不拉伸的情况下显示完整图像?


如下面的答案所示,为了调整图像的大小,使宽度与 StackLayout Container 的最大宽度匹配而不进行裁剪,我需要设置图像的 HeightRequest。

我正在从 WordPress 网站检索帖子。为了解析来自 Wordpress REST API 的 JSON 响应,我使用了 WordpressPCL 包。为了解析我从 WordpressPCL 获得的 HTML 输出,通过 ID 方法获取帖子内容,我使用了 HTML Agility Pack。

使用 HTML Agility Pack,我能够获取 Wordpress 媒体 ID,然后使用该 ID 查询 Wordpress API 并使用 WordpressPCL 包获取原始图像的宽度和高度以及标题文本。

根据图像的尺寸,我计算了纵横比。使用纵横比,我可以通过将纵横比乘以屏幕的总宽度减去 20 来计算图像的新高度。20 是 StackLayout 的左边距 + 右边距,它是图像的父级。

所有图像现在都是全宽以适应父容器的宽度,并且没有被剪裁(100% 高度)。

代码如下(不包括负责解析Wordpress帖子其余内容的代码):

Uri imageSource = new Uri(figure.GetAttributeValue("src", "").ToString());
Int32.TryParse(figure.GetAttributeValue("data-attachment-id", "").ToString(), out int mediaID);
string caption = null;
double aspectRatio = 0;
Task.Run(() =>
{
    Constants wpsite = new Constants();
    var client = new WordPressClient(wpsite.resturl);
    var caption_task = client.Media.GetByID(mediaID);
    caption_task.Wait();
    caption = caption_task.Result.Caption.Rendered;
    double height = caption_task.Result.MediaDetails.Height;
    double width = caption_task.Result.MediaDetails.Width;
    aspectRatio = height / width;
    var htmlCaption = new HtmlDocument();
    htmlCaption.LoadHtml(caption);
    caption = WebUtility.HtmlDecode(htmlCaption.DocumentNode.InnerText);
}).Wait();

Image image = new Image();
image.Source = imageSource;
image.Aspect = Aspect.AspectFit;
double maxWidth = Application.Current.MainPage.Width - 20;
double imageHeight = aspectRatio * maxWidth;
image.HeightRequest = imageHeight;

Label imageCaption = new Label();
imageCaption.Text = caption;
imageCaption.HorizontalTextAlignment = TextAlignment.Center;
imageCaption.FontSize = 12;
imageCaption.Margin = new Thickness(0, 0, 0, 10);

PostContainer.Children.Add(image);
PostContainer.Children.Add(imageCaption);

这是输出:

输出

标签: c#imagexamarin.formsimage-resizingaspect-ratio

解决方案


试试这个。它按预期对我有用。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="PGCubes.Main.Posts">
    <ScrollView>
        <StackLayout Margin="10"
                         HorizontalOptions="Center"
                         VerticalOptions="FillAndExpand"
                         x:Name="PostContainer">
            <Image x:Name="FeaturedImage"
                       HorizontalOptions="Center"/>
            <Label x:Name="Title"
                       FontSize="Title"
                       FontAttributes="Bold"
                       Margin="0, 20, 0, 10"/>
            <Label x:Name="PostMeta"
                       FontSize="Caption"
                       FontAttributes="None"
                       Margin="0, 0, 0, 0"/>
        </StackLayout>
    </ScrollView>
</ContentPage>

后面的代码:

public partial class Posts : ContentPage
    {
        public Posts()
        {
            InitializeComponent();


            Title.Text = "Aims of this Mission";
            PostMeta.Text = "Lorem Ipsum is simply dummy text of " +
                "the printing and typesetting industry. Lorem Ipsum has been " +
                "the industry's standard dummy text ever since the 1500s, when " +
                "an unknown printer took a galley of type and scrambled it to " +
                "make a type specimen book. It has survived not only five centuries" +
                ", but also the leap into electronic typesetting, remaining essentially " +
                "unchanged. It was popularised in the 1960s with the release of Letraset " +
                "sheets containing Lorem Ipsum passages, and more recently with desktop " +
                "publishing software like Aldus PageMaker including versions of Lorem Ipsum.";

            Image image = new Image();
            image.HeightRequest = 640;
            image.Source = "https://i.stack.imgur.com/r5pdVl.png";
            image.Aspect = Aspect.AspectFit;
            PostContainer.Children.Add(image);

        }
    }

我的三星 A30S 的输出 在此处输入图像描述


推荐阅读