首页 文章

如何在Xamarin表单按钮中的图像上叠加文本?

提问于
浏览
0

我无法找到一种简单的方法来创建一个Xamarin表单按钮作为顶部带有叠加文本的图像 . 奇怪的是,Button的Image属性只允许图像旁边的文本 .

所以我将在这里分享我的代码实现 . 它包括一个在点击按钮时隐藏键盘的工具,它支持文本属性,图像大小调整和启用 . 感谢@F . Badili,@ Sharada Gururaj和其他人寻求帮助 .

2 回答

  • 0

    我的实施:

    public class ImageButton : Grid
    // A clickable visual element overlaying a label on an image, serving as a button
    {
        public event EventHandler Clicked;
    
        public Image TheImage { get; set; }
        public Label TheLabel { get; set; }
        public bool HideKeyboard { get; set; }
        public string Text
        { 
            get
            {
                if ( TheLabel == null )
                    return null;
                return TheLabel.Text;
            }
    
            set
            {
                if ( TheLabel == null )
                    return;
                TheLabel.Text = value;
            }
        }
    
        public Color TextColor 
        {
            set
            {
                if ( TheLabel != null )
                    TheLabel.TextColor = value;
            }
        }
        public string FontFamily 
        {
            set 
            {
                if ( TheLabel != null )
                    TheLabel.FontFamily = value;
            }
        }
    
        public FontAttributes FontAttributes 
        {
            set 
            {
                if ( TheLabel != null )
                    TheLabel.FontAttributes = value;
            }
        }
    
        public double FontSize 
        {
            set 
            {
                if ( TheLabel != null )
                    TheLabel.FontSize = value;
            }
        }
    
        public double ImageHeightRequest
        {
            set
            {
                if ( TheImage != null )
                    TheImage.HeightRequest = value;
            }
        }
    
        public double ImageWidthRequest
        {
            set
            {
                if ( TheImage != null )
                    TheImage.WidthRequest = value;    
            }
        }
    
        public ImageButton ( Image image, Label label, bool hideKeyboard = true )
        {
            TheImage = image;
            TheLabel = label;
            HideKeyboard = hideKeyboard;
            Text = label.Text;
    
            // Construct the control
            ConstructControl ();
        }
    
        // Invoke the Clicked event; called when ImageButton is tapped
        protected virtual void OnClicked ( EventArgs e )
        {
            if ( Clicked != null )
                Clicked ( this, e );
        }
    
        private void ConstructControl ()
        // Construct the control using a grid with a single cell
        {
            // Add action performed upon tap
            this.AddTap ( () => 
            {
                // Hide keyboard
                if ( HideKeyboard )
                    DependencyService.Get<IKeyboard> ().HideKeyboard ();
    
                // Fire the event 
                OnClicked ( EventArgs.Empty );
            });
    
            // Bind opacity of image and label to IsEnabled via a converter
            TheLabel.SetBinding ( OpacityProperty, new Binding ( "IsEnabled", converter: new BooleanToOpacityConverter (), source: this ) );
            TheImage.SetBinding ( OpacityProperty, new Binding ( "IsEnabled", converter: new BooleanToOpacityConverter (), source: this ) );
    
            // Stack image and label on top of each other in a grid with a single cell
            this.RowDefinitions.Add ( new RowDefinition { Height = new GridLength ( 1, GridUnitType.Auto ) } );
            this.ColumnDefinitions.Add ( new ColumnDefinition { Width = new GridLength ( 1, GridUnitType.Auto ) } );
            this.Children.Add ( TheImage, 0, 0 );   // Add image first, so overlaid label will be visible
            this.Children.Add ( TheLabel, 0, 0 );
        }
    
        public class BooleanToOpacityConverter : IValueConverter
        {
            public object Convert ( object value, Type targetType, object parameter, CultureInfo culture )
            {
                var isEnabled = ( value != null ) && (bool)value;
                return isEnabled ? 1 : 0.5;
            }
    
            public object ConvertBack ( object value, Type targetType, object parameter, CultureInfo culture )
            {
                throw new NotImplementedException ();
            }
        }
    }
    
    public static class GridExtensions
    {
        // Grid extension methods
    
        private static void AddTap ( this Grid grid, Action action )
        // Allows Grid to be tappable
        // action = method to call when Grid is tapped
        // Example:
        //          Grid grid = new Grid ();
        //          grid.AddTap ( () => MyMethod () );
        {
            grid.GestureRecognizers.Add ( new TapGestureRecognizer 
            {
                Command = new Command (action)
            });
        }
    }
    
    public interface IKeyboard
    {
        void HideKeyboard ();       // Hide the keyboard
    }
    
    iOS:
    
    [assembly: Xamarin.Forms.Dependency (typeof(Keyboard))]
    namespace MyApp.iOS
    {
        public class Keyboard : MyApp.IKeyboard
        {
            public Keyboard () {}
    
            public void HideKeyboard ()
            // Hides the keyboard
            {
                UIApplication.SharedApplication.KeyWindow.EndEditing ( true );
            }
        }
    }
    
    Android (not tested yet):
    
    [assembly: Xamarin.Forms.Dependency (typeof (Keyboard))]
    namespace MyApp.Droid
    {
        public class Keyboard : MyApp.IKeyboard
        {
            public Keyboard () {}
    
            public void HideKeyboard ()
            // Hides the keyboard
            {
                var context = Forms.Context;
                var inputMethodManager = context.GetSystemService ( Context.InputMethodService ) as InputMethodManager;
                if ( inputMethodManager != null && context is Activity ) 
                {
                    var activity = context as Activity;
                    var token = activity.CurrentFocus?.WindowToken;
                    inputMethodManager.HideSoftInputFromWindow ( token, HideSoftInputFlags.None );
    
                    activity.Window.DecorView.ClearFocus ();
                }
            }
        }
    }
    

    用法示例:

    public static ImageButton StandardImageButton ( string buttonText, EventHandler onClickedEventHandler = null, string imageResourceID = "MyApp.standardbutton.png", string imageSource = null, 
                                                  Color textColour = default(Color), string fontFamily = null, double fontSize = 15D, FontAttributes fontAttributes = FontAttributes.Bold, 
                                                  double heightRequest = 44D, double widthRequest = 200D, bool hideKeyboard = true )
        // Returns tappable image serving as a button
        // buttonText = text overlaid onbutton
        // Image is sourced from embedded PCL file (Build Action = Embedded Resource) OR, if imageSourceID is non-null, from local platform file in platform-specific location
        {
            // Background image
            Image image = new Image 
            { 
                Aspect = Aspect.Fill,           // Stretch to fill
                HeightRequest = heightRequest,
                WidthRequest = widthRequest,
                HorizontalOptions = LayoutOptions.CenterAndExpand,
                VerticalOptions = LayoutOptions.CenterAndExpand
            };
    
            if ( imageResourceID == null )
                image.Source = ImageSource.FromFile ( imageSource );
            else
                image.Source = ImageSource.FromResource ( imageResourceID );
    
            // Foreground label
            Color colour;
            if ( textColour == default(Color) )
                colour = Color.Black;
            else
                colour = textColour;
    
            Label label = new Label 
            {
                Text = buttonText,
                TextColor = colour,
                FontFamily = fontFamily,
                FontSize = fontSize,
                FontAttributes = fontAttributes,
                HorizontalTextAlignment = TextAlignment.Center,
                VerticalTextAlignment = TextAlignment.Center
            };
    
            ImageButton ret = new ImageButton ( image, label, hideKeyboard );
            ret.Clicked += onClickedEventHandler;
            return ret;
        }
    
  • 0

    如果在代码或xaml中分配btn1.Image,则可以执行此操作

    btn1.ContentLayout = new Button.ButtonContentLayout(Button.ButtonContentLayout.ImagePosition.Bottom, 10);
    

    这将为您提供一个按钮,底部有图像,顶部有文字

相关问题