summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.Android/Renderers/ButtonRenderer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Xamarin.Forms.Platform.Android/Renderers/ButtonRenderer.cs')
-rw-r--r--Xamarin.Forms.Platform.Android/Renderers/ButtonRenderer.cs252
1 files changed, 252 insertions, 0 deletions
diff --git a/Xamarin.Forms.Platform.Android/Renderers/ButtonRenderer.cs b/Xamarin.Forms.Platform.Android/Renderers/ButtonRenderer.cs
new file mode 100644
index 00000000..eb9b884f
--- /dev/null
+++ b/Xamarin.Forms.Platform.Android/Renderers/ButtonRenderer.cs
@@ -0,0 +1,252 @@
+using System;
+using System.ComponentModel;
+using Android.Content.Res;
+using Android.Graphics;
+using Android.Graphics.Drawables;
+using Android.Util;
+using AButton = Android.Widget.Button;
+using AView = Android.Views.View;
+using Object = Java.Lang.Object;
+
+namespace Xamarin.Forms.Platform.Android
+{
+ public class ButtonRenderer : ViewRenderer<Button, AButton>, AView.IOnAttachStateChangeListener
+ {
+ ButtonDrawable _backgroundDrawable;
+ ColorStateList _buttonDefaulTextColors;
+ Drawable _defaultDrawable;
+ float _defaultFontSize;
+ Typeface _defaultTypeface;
+ bool _drawableEnabled;
+
+ bool _isDisposed;
+
+ public ButtonRenderer()
+ {
+ AutoPackage = false;
+ }
+
+ AButton NativeButton
+ {
+ get { return Control; }
+ }
+
+ public void OnViewAttachedToWindow(AView attachedView)
+ {
+ UpdateText();
+ }
+
+ public void OnViewDetachedFromWindow(AView detachedView)
+ {
+ }
+
+ public override SizeRequest GetDesiredSize(int widthConstraint, int heightConstraint)
+ {
+ UpdateText();
+ return base.GetDesiredSize(widthConstraint, heightConstraint);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ if (_isDisposed)
+ return;
+
+ _isDisposed = true;
+
+ if (disposing)
+ {
+ if (_backgroundDrawable != null)
+ {
+ _backgroundDrawable.Dispose();
+ _backgroundDrawable = null;
+ }
+ }
+
+ base.Dispose(disposing);
+ }
+
+ protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
+ {
+ base.OnElementChanged(e);
+
+ if (e.OldElement == null)
+ {
+ AButton button = Control;
+ if (button == null)
+ {
+ button = new AButton(Context);
+ button.SetOnClickListener(ButtonClickListener.Instance.Value);
+ button.Tag = this;
+ SetNativeControl(button);
+
+ button.AddOnAttachStateChangeListener(this);
+ }
+ }
+ else
+ {
+ if (_drawableEnabled)
+ {
+ _drawableEnabled = false;
+ _backgroundDrawable.Reset();
+ _backgroundDrawable = null;
+ }
+ }
+
+ UpdateAll();
+ }
+
+ protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == Button.TextProperty.PropertyName)
+ UpdateText();
+ else if (e.PropertyName == Button.TextColorProperty.PropertyName)
+ UpdateTextColor();
+ else if (e.PropertyName == VisualElement.IsEnabledProperty.PropertyName)
+ UpdateEnabled();
+ else if (e.PropertyName == Button.FontProperty.PropertyName)
+ UpdateFont();
+ else if (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName)
+ UpdateDrawable();
+ else if (e.PropertyName == Button.ImageProperty.PropertyName)
+ UpdateBitmap();
+ else if (e.PropertyName == VisualElement.IsVisibleProperty.PropertyName)
+ UpdateText();
+
+ if (_drawableEnabled &&
+ (e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName || e.PropertyName == Button.BorderColorProperty.PropertyName || e.PropertyName == Button.BorderRadiusProperty.PropertyName ||
+ e.PropertyName == Button.BorderWidthProperty.PropertyName))
+ {
+ _backgroundDrawable.Reset();
+ Control.Invalidate();
+ }
+
+ base.OnElementPropertyChanged(sender, e);
+ }
+
+ protected override void UpdateBackgroundColor()
+ {
+ // Do nothing, the drawable handles this now
+ }
+
+ void UpdateAll()
+ {
+ UpdateFont();
+ UpdateText();
+ UpdateBitmap();
+ UpdateTextColor();
+ UpdateEnabled();
+ UpdateDrawable();
+ }
+
+ async void UpdateBitmap()
+ {
+ if (Element.Image != null && !string.IsNullOrEmpty(Element.Image.File))
+ {
+ Drawable image = Context.Resources.GetDrawable(Element.Image.File);
+ Control.SetCompoundDrawablesWithIntrinsicBounds(image, null, null, null);
+ if (image != null)
+ image.Dispose();
+ }
+ else
+ Control.SetCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
+ }
+
+ void UpdateDrawable()
+ {
+ if (Element.BackgroundColor == Color.Default)
+ {
+ if (!_drawableEnabled)
+ return;
+
+ if (_defaultDrawable != null)
+ Control.SetBackgroundDrawable(_defaultDrawable);
+
+ _drawableEnabled = false;
+ }
+ else
+ {
+ if (_backgroundDrawable == null)
+ _backgroundDrawable = new ButtonDrawable();
+
+ _backgroundDrawable.Button = Element;
+
+ if (_drawableEnabled)
+ return;
+
+ if (_defaultDrawable == null)
+ _defaultDrawable = Control.Background;
+
+ Control.SetBackgroundDrawable(_backgroundDrawable);
+ _drawableEnabled = true;
+ }
+
+ Control.Invalidate();
+ }
+
+ void UpdateEnabled()
+ {
+ Control.Enabled = Element.IsEnabled;
+ }
+
+ void UpdateFont()
+ {
+ Button button = Element;
+ if (button.Font == Font.Default && _defaultFontSize == 0f)
+ return;
+
+ if (_defaultFontSize == 0f)
+ {
+ _defaultTypeface = NativeButton.Typeface;
+ _defaultFontSize = NativeButton.TextSize;
+ }
+
+ if (button.Font == Font.Default)
+ {
+ NativeButton.Typeface = _defaultTypeface;
+ NativeButton.SetTextSize(ComplexUnitType.Px, _defaultFontSize);
+ }
+ else
+ {
+ NativeButton.Typeface = button.Font.ToTypeface();
+ NativeButton.SetTextSize(ComplexUnitType.Sp, button.Font.ToScaledPixel());
+ }
+ }
+
+ void UpdateText()
+ {
+ NativeButton.Text = Element.Text;
+ }
+
+ void UpdateTextColor()
+ {
+ Color color = Element.TextColor;
+
+ if (color.IsDefault)
+ {
+ if (_buttonDefaulTextColors == null)
+ return;
+
+ NativeButton.SetTextColor(_buttonDefaulTextColors);
+ }
+ else
+ {
+ _buttonDefaulTextColors = _buttonDefaulTextColors ?? Control.TextColors;
+
+ // Set the new enabled state color, preserving the default disabled state color
+ NativeButton.SetTextColor(color.ToAndroidPreserveDisabled(_buttonDefaulTextColors));
+ }
+ }
+
+ class ButtonClickListener : Object, IOnClickListener
+ {
+ public static readonly Lazy<ButtonClickListener> Instance = new Lazy<ButtonClickListener>(() => new ButtonClickListener());
+
+ public void OnClick(AView v)
+ {
+ var renderer = v.Tag as ButtonRenderer;
+ if (renderer != null)
+ ((IButtonController)renderer.Element).SendClicked();
+ }
+ }
+ }
+} \ No newline at end of file