我想在我的应用中将图像放置在半帧中,我正在使用xamarin表单来执行此操作,我该怎么做
我的Xaml
<StackLayout HorizontalOptions = "FillAndExpand" VerticalOptions="StartAndExpand" >
<ListView x:Name="lv_search" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" RowHeight="175" SeparatorColor="White">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<AbsoluteLayout HorizontalOptions = "FillAndExpand" VerticalOptions="StartAndExpand" >
<Frame BackgroundColor = "White" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand" Margin="20,10,0,0"
HeightRequest="75" AbsoluteLayout.LayoutBounds="0.01,0.9,1,1" AbsoluteLayout.LayoutFlags="All">
<Image Source = "img_frm" BackgroundColor="#14559a" AbsoluteLayout.LayoutBounds="0.009,0.9,0.3,0.6" AbsoluteLayout.LayoutFlags="All" />
<StackLayout Orientation = "Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand">
<AbsoluteLayout HorizontalOptions = "StartAndExpand" >
<Image Source="ellipse_1" VerticalOptions="CenterAndExpand" HorizontalOptions="Start" AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0.01,0.4,1,1" HeightRequest="100" WidthRequest="100" BackgroundColor="White"/>
<Image Source = "{Binding Image}" AbsoluteLayout.LayoutBounds="0.02,0.4,1,1" AbsoluteLayout.LayoutFlags="All"
HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand" ></Image>
</AbsoluteLayout>
<Label x:Name="lbl_categories" HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand" Margin="10,0,0,0"
TextColor="Black" Text="{Binding Title}" LineBreakMode="WordWrap" HorizontalTextAlignment="Start"
FontSize="Medium" FontAttributes="Bold" AbsoluteLayout.LayoutBounds="0.3,0.3,1,1" AbsoluteLayout.LayoutFlags="All"/>
<Image HorizontalOptions = "EndAndExpand" VerticalOptions="Center" Source="arrow" AbsoluteLayout.LayoutBounds="0.9,0.3,0.3,0.3"
AbsoluteLayout.LayoutFlags="All" />
</StackLayout>
</Frame>
</AbsoluteLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
但是它并没有开发出我想要的设计。
实际上我想要这样的设计
但是我得到这样的设计,如何将设计修改成上面的图像
答案 0 :(得分:3)
我不想这么说,但是对于您想要实现的结果,您的xaml是一场噩梦。不仅因为视觉树中元素过多,而且还因为在ListView中使用AbsoluteLayout。
即使从技术上讲这是可行的,但它仍会导致您的应用程序性能下降,尤其是在ListView中填充了很多项目的情况下。
第二,为该蓝色正方形创建图像也会浪费内存,并且会导致更多性能下降,并且如果ListView包含许多条目,最终可能会导致Android出现OutOfMemoryExceptions。
您可以将其替换为从框视图继承的自定义视图,并使用自定义渲染器渲染圆角。
还避免在ListView中使用StackLayout,因为这也会导致性能问题,因为StackLayout在进行布局时会进行大量计算。
正如丹尼斯已经提到的,您要走的路是牢记使用Grid进行布局,所有添加到网格中的元素都将按照它们在xaml定义中的添加顺序相互重叠。
尤其是在使用ListViews时,请尝试使用尽可能少的元素,并避免需要大量布局传递的元素。
即使我没有在示例中使用它,我也想添加信息,您也可以使用负边距值进行高级元素定位。
这是一个简短的示例,我一起砍死了:
<ListView VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" RowHeight="80">
<ListView.ItemsSource>
<x:Array Type="{x:Type x:String}">
<!-- quick hack to make the list view populate items without having to write model classes -->
<x:String>Entry 1</x:String>
<x:String>Entry 2</x:String>
<x:String>Entry 3</x:String>
<x:String>Entry 4</x:String>
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
<BoxView BackgroundColor="LightGray" Margin="19,9,9,9" />
<Grid Margin="20,10,10,10" BackgroundColor="White">
<Label Text="{Binding .}" VerticalOptions="Center" FontSize="18" Margin="25,0,0,0"/>
<!-- insert icons, labels, etc here -->
</Grid>
<customs:RoundedBoxView BackgroundColor="DarkBlue" CornerRadius="6" WidthRequest="15" VerticalOptions="FillAndExpand" HorizontalOptions="Start" Margin="10,20,0,20" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
RoundedBoxView类如下:
public class RoundedBoxView : BoxView
{
readonly BindableProperty CornerRadiusProperty = BindableProperty.Create("CornerRadius", typeof(double), typeof(double), 0.0);
public double CornerRadius
{
get { return (double)GetValue(CornerRadiusProperty); }
set { SetValue(CornerRadiusProperty, value); }
}
}
这将是android的自定义渲染器:
[assembly: ExportRenderer(typeof(RoundedBoxView), typeof(RoundedBoxViewRenderer))]
namespace TestApp.Droid
{
public class RoundedBoxViewRenderer : BoxRenderer
{
public RoundedBoxViewRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
{
base.OnElementChanged(e);
SetWillNotDraw(false);
Invalidate();
}
public override void Draw(Canvas canvas)
{
var box = Element as RoundedBoxView;
var rect = new Rect();
var paint = new Paint()
{
Color = box.BackgroundColor.ToAndroid(),
AntiAlias = true,
};
GetDrawingRect(rect);
var radius = (float)(box.CornerRadius);
canvas.DrawRoundRect(new RectF(rect), radius, radius, paint);
}
}
对于iOS:
[assembly: ExportRenderer(typeof(RoundedBoxView), typeof(RoundedBoxViewRenderer))]
namespace TestApp.iOS
{
public class RoundedBoxViewRenderer: BoxRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<BoxView> e)
{
base.OnElementChanged(e);
if (Element != null)
{
Layer.MasksToBounds = true;
UpdateCornerRadius(e.NewElement as RoundedBoxView);
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == CircleView.WidthProperty.PropertyName || e.PropertyName == CircleView.HeightProperty.PropertyName)
{
UpdateCornerRadius(Element as RoundedBoxView);
}
}
void UpdateCornerRadius(RoundedBoxView box)
{
Layer.CornerRadius = (nfloat)(box.CornerRadius);
CGRect bounds = new CGRect(0, 0, box.Width, box.Width);
Layer.Bounds = bounds;
Layer.Frame = bounds;
}
}
哪个会这样渲染:
答案 1 :(得分:1)
您可以使用Grid
代替AbsoluteLayout
。
我没有对此进行测试,但是尝试如下操作:
<Grid
HorizontalOptions="FillAndExpand"
VerticalOptions="StartAndExpand">
<Frame
Grid.Row="0"
Grid.Column="0"
BackgroundColor="White"
HorizontalOptions="FillAndExpand"
VerticalOptions="StartAndExpand"
Margin="20,10,0,0"
HeightRequest="75">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image
Grid.Row="0"
Grid.Column="0"
Source="ellipse_1"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Start"
HeightRequest="100"
WidthRequest="100"
BackgroundColor="White">
</Image>
<Image
Grid.Row="0"
Grid.Column="1"
Source="{Binding Image}"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand">
</Image>
<Label
Grid.Row="0"
Grid.Column="2"
x:Name="lbl_categories"
HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand"
Margin="10,0,0,0"
TextColor="Black"
Text="{Binding Title}"
LineBreakMode="WordWrap"
HorizontalTextAlignment="Start"
FontSize="Medium"
FontAttributes="Bold">
</Label>
<Image
Grid.Row="0"
Grid.Column="3"
HorizontalOptions="EndAndExpand"
VerticalOptions="Center"
Source="arrow">
</Image>
</Grid>
</Frame>
<Image
Margin="10,10,0,0"
Grid.Row="0"
Grid.Column="0"
Source="img_frm"
BackgroundColor="#14559a">
</Image>
</Grid>
由于Image
是在您的XML中的Frame
之后创建的,因此它与Frame
重叠。您可能需要根据需要更改Frame
和蓝色方形Image
的边距。