【问题标题】:Aligning Image with Entry in Xamarin Forms将图像与 Xamarin 表单中的条目对齐
【发布时间】:2018-01-19 07:01:08
【问题描述】:

在以下 Xamarin Forms 代码中,我尝试将 Image 与 Entry 对齐,以创建类似于引导输入组的视觉外观,如 Bootstrap input group addon alignment problems 中所述

但它有以下缺点:

  1. 图片的宽度和高度超过了指定的HeightRequest和WidthRequest
  2. 图像和条目之间有多余的空间

如何解决这个问题?

XAML

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MyHomeScreen2;assembly=MyHomeScreen2"
             x:Class="MyHomeScreen2.InputFormTest"
             NavigationPage.HasNavigationBar="False">
    <ContentPage.Content>
        <Grid x:Name="inputGrid" Grid.Row="1" ColumnSpacing="0" RowSpacing="0" Padding="0" BackgroundColor="#606060">
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>

            <Label x:Name="lblReading" TextColor="White"  Text="READING" Grid.Row="0" Margin="15"></Label>

            <StackLayout Grid.Row="1" Orientation="Horizontal">
                <Image Source="homea.png" Aspect="AspectFit" 
                       HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" 
                       HeightRequest="10" WidthRequest="20"
                       BackgroundColor="Silver" ></Image>
                <Entry x:Name="myEntry" TextColor="Black"  Text="1" Keyboard="Numeric"  BackgroundColor="White"  
                           Opacity="0.9" HeightRequest="20">
                </Entry>
            </StackLayout>
        </Grid>
    </ContentPage.Content>
</ContentPage>

【问题讨论】:

  • 您不能“FillAndExpand”图像的水平和垂直选项。用“CenterAndExpand”覆盖它,并将“FillAndExpand”布局选项放在 Entry 视图上。
  • 我没试过。但我确定问题就在那里。让我看看我能不能让它工作,我会告诉你。 (对不起英语不好)
  • 1 将水平和垂直选项更改为居中、开始或结束,2 在 Stacklayout 上设置 Spacing="0"
  • 您使用的图片的实际尺寸是多少?你能展示所需布局的图片吗?

标签: xamarin xamarin.forms


【解决方案1】:

第一件事:

XAML:

<Grid Grid.Row="1" ColumnSpacing="0" 
      RowSpacing="0" 
      Padding="0"
      BackgroundColor="#606060">
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Label Grid.Row="0"
           x:Name="lblReading" 
           TextColor="White"  
           Text="READING" 
           Margin="15"/>
    <StackLayout Grid.Row="1" 
                 Orientation="Horizontal"
                 Spacing="1"
                 Margin="5,0">
        <Image Source="lan_connect_white_36dp" 
               Aspect="AspectFit" 
               HorizontalOptions="Center" 
               VerticalOptions="CenterAndExpand" 
               HeightRequest="40" 
               WidthRequest="40"
               BackgroundColor="Silver"/>
        <Entry x:Name="myEntry" 
               TextColor="Black"  
               Text="1" 
               Keyboard="Numeric"  
               BackgroundColor="White" 
               HorizontalOptions="FillAndExpand" 
               VerticalOptions="CenterAndExpand"
               Opacity="0.9">
        </Entry>
    </StackLayout>
</Grid>

结果:

说明

  1. 图片的宽度和高度超过了指定的HeightRequest和WidthRequest

当您使用星号设置ColumnDefinitionWidthRowDefinitionHeight 时,您是说它应该占用它的所有可用空间,而其他列/行将使用足够的空间保留内部视图的空间。

  1. 图像和条目之间有多余的空间

某些布局容器在视图之间具有默认间距。 GridLayout 就是这种情况,它的默认 ColumnSpacingRowSpacing6

【讨论】:

  • 谢谢。但是如何去掉Image和Entry之间的空格
  • 只需将Spacing="1" 更改为Spacing="0"
【解决方案2】:

我已经使用这个blog 完成了这项工作。

在 PCL 中:创建一个名为 ImageEntry 的类

using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;

namespace ImageEntry
{
    public class ImageEntry1 : Entry
    {
        public ImageEntry1()
        {
            this.HeightRequest = 50;
        }
        public static readonly BindableProperty ImageProperty =
            BindableProperty.Create(nameof(Image), typeof(string), typeof(ImageEntry1), string.Empty);

        public static readonly BindableProperty LineColorProperty =
            BindableProperty.Create(nameof(LineColor), typeof(Xamarin.Forms.Color), typeof(ImageEntry1), Color.White);

        public static readonly BindableProperty ImageHeightProperty =
            BindableProperty.Create(nameof(ImageHeight), typeof(int), typeof(ImageEntry1), 40);

        public static readonly BindableProperty ImageWidthProperty =
            BindableProperty.Create(nameof(ImageWidth), typeof(int), typeof(ImageEntry1), 40);

        public static readonly BindableProperty ImageAlignmentProperty =
            BindableProperty.Create(nameof(ImageAlignment), typeof(ImageAlignment), typeof(ImageEntry1), ImageAlignment.Left);

        public Color LineColor
        {
            get { return (Color)GetValue(LineColorProperty); }
            set { SetValue(LineColorProperty, value); }
        }

        public int ImageWidth
        {
            get { return (int)GetValue(ImageWidthProperty); }
            set { SetValue(ImageWidthProperty, value); }
        }

        public int ImageHeight
        {
            get { return (int)GetValue(ImageHeightProperty); }
            set { SetValue(ImageHeightProperty, value); }
        }

        public string Image
        {
            get { return (string)GetValue(ImageProperty); }
            set { SetValue(ImageProperty, value); }
        }

        public ImageAlignment ImageAlignment
        {
            get { return (ImageAlignment)GetValue(ImageAlignmentProperty); }
            set { SetValue(ImageAlignmentProperty, value); }
        }
    }

    public enum ImageAlignment
    {
        Left,
        Right
    }
}

在android中创建一个名为ImageEntryRenderer的类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.Graphics;
using Android.Graphics.Drawables;
using Android.OS;
using Android.Runtime;
using Android.Support.V4.Content;
using Android.Views;
using Android.Widget;
using ImageEntry;
using ImageEntry.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(ImageEntry1), typeof(ImageEntryRenderer))]
namespace ImageEntry.Droid
{
    public class ImageEntryRenderer : EntryRenderer
    {
        ImageEntry1 element;
        public ImageEntryRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
            if (e.OldElement != null || e.NewElement == null)
                return;

            element = (ImageEntry1)this.Element;


            var editText = this.Control;
            if (!string.IsNullOrEmpty(element.Image))
            {
                switch (element.ImageAlignment)
                {
                    case ImageAlignment.Left:
                        editText.SetCompoundDrawablesWithIntrinsicBounds(GetDrawable(element.Image), null, null, null);
                        break;
                    case ImageAlignment.Right:
                        editText.SetCompoundDrawablesWithIntrinsicBounds(null, null, GetDrawable(element.Image), null);
                        break;
                }
            }
            editText.CompoundDrawablePadding = 25;
            Control.Background.SetColorFilter(element.LineColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
        }

        private BitmapDrawable GetDrawable(string imageEntryImage)
        {
            int resID = Resources.GetIdentifier(imageEntryImage, "drawable", this.Context.PackageName);
            var drawable = ContextCompat.GetDrawable(this.Context, resID);
            var bitmap = ((BitmapDrawable)drawable).Bitmap;

            return new BitmapDrawable(Resources, Bitmap.CreateScaledBitmap(bitmap, element.ImageWidth * 2, element.ImageHeight * 2, true));
        }
    }
}

在IOS中创建一个名为ImageEntryRenderer的类

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using CoreAnimation;
using CoreGraphics;
using Foundation;
using ImageEntry;
using ImageEntry.iOS;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(ImageEntry1), typeof(ImageEntryRenderer))]
namespace ImageEntry.iOS
{
    public class ImageEntryRenderer : EntryRenderer
    {
        ImageEntry1 element;
        public ImageEntryRenderer()
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);
            if (e.OldElement != null || e.NewElement == null)
                return;

            var element = (ImageEntry1)this.Element;
            var textField = this.Control;
            if (!string.IsNullOrEmpty(element.Image))
            {
                switch (element.ImageAlignment)
                {
                    case ImageAlignment.Left:
                        textField.LeftViewMode = UITextFieldViewMode.Always;
                        textField.LeftView = GetImageView(element.Image, element.ImageHeight, element.ImageWidth);
                        break;
                    case ImageAlignment.Right:
                        textField.RightViewMode = UITextFieldViewMode.Always;
                        textField.RightView = GetImageView(element.Image, element.ImageHeight, element.ImageWidth);
                        break;
                }
            }

            textField.BorderStyle = UITextBorderStyle.None;
            CALayer bottomBorder = new CALayer
            {
                Frame = new CGRect(0.0f, element.HeightRequest - 1, this.Frame.Width, 1.0f),
                BorderWidth = 2.0f,
                BorderColor = element.LineColor.ToCGColor()
            };

            textField.Layer.AddSublayer(bottomBorder);
            textField.Layer.MasksToBounds = true;
        }

        private UIView GetImageView(string imagePath, int height, int width)
        {
            var uiImageView = new UIImageView(UIImage.FromBundle(imagePath))
            {
                Frame = new RectangleF(0, 0, width, height)
            };
            UIView objLeftView = new UIView(new System.Drawing.Rectangle(0, 0, width + 10, height));
            objLeftView.AddSubview(uiImageView);

            return objLeftView;
        }
    }
}

在 XAML 中添加了入口代码:MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ImageEntry"
             BackgroundColor="#2f4259"
             x:Class="ImageEntry.MainPage">
    <ContentPage.Content>
        <ScrollView>
            <StackLayout Padding="40" Spacing="10">
                <local:ImageEntry1 TextColor="White" 
                        Image="user" 
                        Placeholder="Emil" 
                        HorizontalOptions="FillAndExpand"/>
            </StackLayout>
        </ScrollView>
    </ContentPage.Content>
</ContentPage>

附上here上的示例项目,快乐编码:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    • 1970-01-01
    • 2012-12-21
    • 2017-08-13
    • 2015-10-04
    • 2021-10-14
    • 1970-01-01
    相关资源
    最近更新 更多