Несоответствие размера изображения Xamarin
Я использую кросс-платформенное приложение с использованием Xamarin Forms, и я борюсь со странной ошибкой:
Я пытаюсь создать кнопку с текстом на ней. Для этого я использую AbsoluteLayout
.
Я добавил изображение в проект iOS для каждого типа разрешений iOS (.png, @2x.png, @3x.png). Все работает нормально со стандартным тегом <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. Изображение в абсолютном макете имеет ошибку пропорции, и изображение без него не имеет.
Я немного потерялся здесь. Есть ли способ взломать этот путь? Я пытался создать. пользовательский рендерер, чтобы назначить размер изображения вручную, но похоже, что UIImage предоставляет различные единицы размера, которые использует Xamarin, и это не решит проблему на Android.
Любые советы будут действительно оценены!
Изменить (3/5/2017):
Просто чтобы вы обновили - похоже, это общая ошибка в Xamarin Forms. Мое опубликованное решение является обходным решением, и я снова и снова застревает в этой проблеме.
Например, я пытаюсь создать этот графический интерфейс:
![Желаемый образ графического интерфейса пользователя]()
Я создал код ниже:
<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>
Все работает нормально, пока я не добавлю изображение, что приводит к следующему результату:
![Фактический GUI]()
Если кто-то подскажет, как взломать его, я буду очень признателен, если он или она сможет опубликовать решение здесь!
Пока я получаю это, проблема с iOS UIImage
renderer - конечная точка UIImage недоступна при вычислении макета изображения (и, следовательно, ширина и высота изображения -1), и поэтому XF не знает, как визуализируйте изображение правильно.
Ответы
Ответ 1
Спасибо за предложенные ответы. К сожалению, эта проблема не была решена с использованием любого предлагаемого ответа.
Я отказался от использования AbsoluteLayout
. Фактически, на прошлой неделе я столкнулся со многими проблемами относительно изображений в iOS на RelativeLayout
и StackLayout
. Я сообщил им о Ксамарине.
Между тем, я опубликую здесь свое обходное решение, которое, хотя может быть красивее, отлично работает.
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(sender, EventArgs.Empty);
}
}),
NumberOfTapsRequired = 1
});
}
}
}
Ответ 2
Вы можете установить свойство 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>
`
Ответ 3
Граница и изменение размера - от AbsoluteLayout, а не от изображения. Посмотрите, может ли ширина макета динамически расширяться как 100% из родительского контейнера, и если она разрешает такие параметры, как no-border.
Ответ 4
Просто добавьте
Aspect:AspectFill
или
Fill
в зависимости от ваших потребностей!!!
Ответ 5
попробуйте использовать Горизонтальный 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 >