繁体   English   中英

如何使用Xamarin表单将图像放置在半帧中

[英]How to place a image in the half of a frame using Xamarin forms

我想在我的应用程序中将图像放置在半帧中,我正在使用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>

但是它并不能满足我的需求。

其实我想要这样的设计

在此处输入图片说明

但是我得到这样的设计,如何将设计修改成上面的图像

在此处输入图片说明

我讨厌这样说,但是对于您想要实现的结果,您的xaml是一场噩梦。 不仅因为您的可视树中元素过多,还因为您在ListView中使用AbsoluteLayout。

即使从技术上讲这是可行的,也会导致您的应用程序性能下降,尤其是在ListView中填充了很多项目的情况下。

其次,为该蓝色正方形创建图像也会浪费内存,并且会导致更多性能下降,并且如果ListView包含许多条目,最终可能会导致Android出现OutOfMemoryExceptions。

您可以将其替换为从框视图继承的自定义视图,并使用自定义渲染器渲染圆角。

还要避免在ListView中使用StackLayout,因为这也会导致性能问题,因为StackLayout在进行布局时会进行大量计算。

正如Dennis所提到的,您要走的路是牢记使用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;
    }
}

它将如下所示:

在此处输入图片说明 }

您可以使用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是在xaml中的Frame之后创建的,所以它与Frame重叠。 您可能需要根据需要更改Frame和蓝色方形Image的边距。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM