【问题标题】:Xamarin Forms image size mismatchXamarin Forms 图像大小不匹配
【发布时间】:2017-06-30 19:55:53
【问题描述】:

我正在使用 Xamarin Forms 实现跨平台应用程序,但遇到了一个奇怪的错误: 我正在尝试创建一个带有文本的按钮。为了实现它,我使用AbsoluteLayout

我已经为每个 iOS 分辨率类型(.png、@2x.png、@3x.png)向 iOS 项目添加了一个图像。使用标准 <Image /> 标签一切正常。但是,当以绝对布局包装图像时 - 图像会失去其分辨率比例并导致边框。

以上代码:

    <AbsoluteLayout BackgroundColor="Blue">
        <Image Source="home/donation-button.png"
            AbsoluteLayout.LayoutFlags="All" 
                x:Name="Button"
            AbsoluteLayout.LayoutBounds="0, 0, 1, 1" 
            />
        <Label Text="Hello, World!"
                TextColor="White"
                FontAttributes="Bold"
                FontSize="16"
                AbsoluteLayout.LayoutFlags="All"
                AbsoluteLayout.LayoutBounds="0, 1, 1, 0.5" />
    </AbsoluteLayout> 

产生以下内容:

在 iPhone 6+/6s+/7+ 上(模拟器为 iPhone 7 Plus): 这是预期的行为。

在 iPhone 6/6s/7 上(模拟器是 iPhone 7): 注意图片上的蓝色小边框,在AbsoluteLayout上设置为背景

在 5SE/5s 及以下: 注意蓝色的大边框。

为了调试它,我将相同的图像放置了两次 - 首先是在 AbsoluteLayout 中,然后作为 StackLayout 中的标准项。绝对布局的图片有比例bug,没有它的图片没有。

我有点迷路了。有什么办法可以破解我们的方法吗?我试过创造。用于手动分配图像大小的自定义渲染器,但 UIImage 提供的大小单位似乎与 Xamarin 使用的不同,并且无法解决 Android 上的问题。

任何建议将不胜感激!

编辑(2017 年 3 月 5 日): 只是为了让您了解最新情况 - 这似乎是 Xamarin Forms 中的一般错误。我发布的解决方案是一种解决方法,我一遍又一遍地陷入这个问题。

例如,我尝试创建这个 GUI:

我创建了下面的代码:

<StackLayout Orientation="Horizontal" 
            VerticalOptions="End"
            HorizontalOptions="FillAndExpand"
            BackgroundColor="#dd2c00">
            <Label Text="100"
                FontSize="46"
                Margin="10"
                FontFamily="OpenSans-Bold" 
                TextColor="#ffffff"
                VerticalOptions="FillAndExpand"
                VerticalTextAlignment="Center"
                HorizontalTextAlignment="Center" />
            <Label TextColor="#ffffff"
                FontSize="Medium"
                VerticalOptions="FillAndExpand"
                HorizontalOptions="FillAndExpand"
                VerticalTextAlignment="Center">
                <Label.FormattedText>
                    <FormattedString>
                        <Span FontFamily="OpenSans-Regular" Text="{markup:Localize CandlesMap.FacebookFriendsCandles1}" />
                        <Span FontFamily="OpenSans-Light" Text="{markup:Localize CandlesMap.FacebookFriendsCandles2}" />
                    </FormattedString>
                </Label.FormattedText>
            </Label>
            <Image Source="{markup:ResolvePath map.show_friends_candle_button}" />
        </StackLayout>

一切正常,直到我添加图像,这会产生以下输出:

如果有人想出如何破解它,如果他或她能在此处发布解决方案,我将不胜感激! 只要我得到它,它就是 iOS UIImage 渲染器的问题 - UIImage 本机端点在计算图像布局时不可用(因此图像宽度和高度为-1),因此 XF 不知道如何正确渲染图像。

【问题讨论】:

  • 尽量只使用堆栈布局,并将水平(图像和标签)都放在水平堆栈布局上
  • @MikeDarwish 是的,这就是我使用的解决方法,谢谢!
  • @QzB 。我为你发布一个答案.. 谢谢

标签: c# android ios xamarin.forms cross-platform


【解决方案1】:

感谢建议的答案。不幸的是,使用任何建议的答案都无法解决此问题。 我放弃了使用AbsoluteLayout。实际上,在过去的一周里,我在RelativeLayoutStackLayout 也遇到了很多关于iOS 图像的问题。我已将它们报告给 Xamarin。

同时,我将在这里发布我的解决方法,虽然可能更漂亮,但效果很好。

using System;
using Xamarin.Forms;
namespace App.Views.Home
{
    public class DonationButton : RelativeLayout
    {
        #region Properties

        /// <summary>
        /// Gets or sets the button text.
        /// </summary>
        /// <value>The text.</value>
        public string Text
        {
            get { return this._textLabel.Text; }
            set { this._textLabel.Text = value; }
        }

        public event EventHandler Clicked;

        #endregion

        #region iVars

        private Image _backgroundImage;
        private Label _textLabel;

        #endregion

        public DonationButton()
        {
            //--------------------------------------------
            //  Setup the background image
            //--------------------------------------------
            this._backgroundImage = new Image()
            {
                Source = ImageSource.FromFile("home__donation_button.png")
            };

            this.Children.Add(this._backgroundImage, (Constraint)null, (Constraint)null, (Constraint)null, (Constraint)null);

            //--------------------------------------------
            //  Add the label
            //--------------------------------------------

            /* See: http://stackoverflow.com/a/40942692/1497516 */
            Func<RelativeLayout, double> getLabelWidth
                = (p) => this._textLabel.Measure(p.Width, p.Height).Request.Width;
            Func<RelativeLayout, double> getLabelHeight
                = (p) => this._textLabel.Measure(p.Width, p.Height).Request.Height;

            this._textLabel = new Label()
            {
                TextColor = Color.White,
                FontAttributes = FontAttributes.Bold,
                FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label))
            };

            this.Children.Add(this._textLabel,
                              Constraint.RelativeToParent((parent) => parent.Width - (getLabelWidth(parent) + 10)),
                              Constraint.RelativeToView(this._backgroundImage, (parent, view) => (view.Height - getLabelHeight(parent)) / 2)
                              );

            //--------------------------------------------
            //  Allow clicks
            //--------------------------------------------
            this.GestureRecognizers.Add(new TapGestureRecognizer
            {
                Command = new Command(sender =>
                {
                    if (this.Clicked != null)
                    {
                        this.Clicked(this, EventArgs.Empty);
                    }
                }),
                NumberOfTapsRequired = 1
            });
        }
    }
}

【讨论】:

    【解决方案2】:

    尝试使用 Horizo​​ntal StackLayout 如下:

    <StackLayout BackgroundColor="Blue" Orientation="Horizontal">
            <Image Source="home/donation-button.png"               
                x:Name="Button"
                />
            <Label Text="Hello, World!"
                TextColor="White"
                FontAttributes="Bold"
                FontSize="16"
               />
        </StackLayout >
    

    【讨论】:

    • 感谢您的建议。试过了,没有运气......即使在较小的 iPhone 上,Forms 仍然使用@3x 图像。请参阅我的解决方法:stackoverflow.com/a/42456114/1497516
    【解决方案3】:

    只需添加

    Aspect:AspectFill

    Fill

    满足你的需求!!!

    【讨论】:

      【解决方案4】:

      边框和大小调整来自 AbsoluteLayout 而不是来自图像。看看布局的宽度是否可以从父容器动态扩展为 100% 以及是否允许无边框等选项。

      【讨论】:

        【解决方案5】:

        您可以将 Image 标签的 Aspect 属性设置为 AspectFill,这允许您的图像适合其容器而不会丢失其分辨率`

        <AbsoluteLayout BackgroundColor="Blue">
                <Image Source="home/donation-button.png"
                    Aspect="AspectFill"
                    AbsoluteLayout.LayoutFlags="All" 
                    x:Name="Button"
                    AbsoluteLayout.LayoutBounds="0, 0, 1, 1"/>
                <Label Text="Hello, World!"
                    TextColor="White"
                    FontAttributes="Bold"
                    FontSize="16"
                    AbsoluteLayout.LayoutFlags="All"
                    AbsoluteLayout.LayoutBounds="0, 1, 1, 0.5" />
            </AbsoluteLayout>
        

        `

        【讨论】:

          猜你喜欢
          • 2019-03-02
          • 1970-01-01
          • 2015-04-21
          • 2020-08-24
          • 2023-03-22
          • 2021-08-01
          • 2014-10-05
          • 2014-09-28
          • 2020-06-26
          相关资源
          最近更新 更多