将图像与Xamarin表单中的条目对齐

时间:2017-08-10 21:27:33

标签: xamarin xamarin.forms

在下面的Xamarin Forms代码中,我尝试将Image与Entry对齐以创建视觉外观,如Bootstrap input group addon alignment problems

中所述的bootstrap输入组

但它有以下缺点:

  1. 图像占用的宽度和高度超过指定的HeightRequest和WidthRequest
  2. 图像和条目之间存在不需要的空间
  3. 如何解决这个问题?

    enter image description here

    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>
    

2 个答案:

答案 0 :(得分: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>

<强>结果:

Sample

答案 1 :(得分:0)

我已经使用此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上附加了示例项目,使用了愉快的编码:)