2017-08-29 106 views
0

我無法找到一種簡單的方法來創建一個Xamarin Forms按鈕作爲頂部帶有疊加文本的圖像。奇怪的是,Button的Image屬性只允許圖片旁邊的文字。如何在Xamarin表單按鈕中的圖像上添加文本?

所以我會在這裏分享我的代碼實現。它包括一個工具,可以在輕按按鈕時隱藏鍵盤,並支持文本屬性,圖像大小調整和啓用。感謝@F。 Badili,@Sharada Gururaj等人提供協助。

回答

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); 

這會給你一個帶底部圖像和頂部圖像的按鈕

+0

通過圖像的「頂部」我實際上是指疊加在圖像上。對不起@Yuri s,我應該已經更清楚了:) – BillF

相關問題