bool ImageSourceLoaded(ButtonHandler buttonHandler) { var image = buttonHandler.PlatformView.Icon ?? TextViewCompat.GetCompoundDrawablesRelative(buttonHandler.PlatformView)[3]; return(image != null); }
public static void UpdateContentLayout(this MaterialButton materialButton, Button button) { var context = materialButton.Context; if (context == null) { return; } var icon = materialButton.Icon ?? TextViewCompat.GetCompoundDrawablesRelative(materialButton)[3]; if (icon != null && !String.IsNullOrEmpty(button.Text)) { var contentLayout = button.ContentLayout; // IconPadding calls materialButton.CompoundDrawablePadding // Which is why we don't have to worry about calling setCompoundDrawablePadding // ourselves for our custom implemented IconGravityBottom materialButton.IconPadding = (int)context.ToPixels(contentLayout.Spacing); switch (contentLayout.Position) { case ButtonContentLayout.ImagePosition.Top: materialButton.Icon = icon; materialButton.IconGravity = MaterialButton.IconGravityTop; break; case ButtonContentLayout.ImagePosition.Bottom: materialButton.Icon = null; TextViewCompat.SetCompoundDrawablesRelative(materialButton, null, null, null, icon); materialButton.IconGravity = MauiMaterialButton.IconGravityBottom; break; case ButtonContentLayout.ImagePosition.Left: materialButton.Icon = icon; materialButton.IconGravity = MaterialButton.IconGravityStart; break; case ButtonContentLayout.ImagePosition.Right: materialButton.Icon = icon; materialButton.IconGravity = MaterialButton.IconGravityEnd; break; } } else { // Don't remove this otherwise the button occasionally measures wrong // on first load materialButton.Icon = icon; materialButton.IconPadding = 0; materialButton.IconGravity = MaterialButton.IconGravityTextStart; } }
protected override void OnLayout(bool changed, int left, int top, int right, int bottom) { // These are hacks that seem to force the button to measure correctly // when using top or bottom positioning. if (IconGravity == IconGravityBottom) { var drawable = TextViewCompat.GetCompoundDrawablesRelative(this)[3]; drawable?.SetBounds(0, 0, drawable.IntrinsicWidth, drawable.IntrinsicHeight); } else if (IconGravity == MaterialButton.IconGravityTop) { var drawable = TextViewCompat.GetCompoundDrawablesRelative(this)[1]; drawable?.SetBounds(0, 0, drawable.IntrinsicWidth, drawable.IntrinsicHeight); } base.OnLayout(changed, left, top, right, bottom); }
void UpdateImage() { if (_disposed || _renderer == null || _element == null) { return; } AButton view = View; if (view == null) { return; } ImageSource elementImage = _element.ImageSource; if (elementImage == null || elementImage.IsEmpty) { view.SetCompoundDrawablesWithIntrinsicBounds(null, null, null, null); return; } // No text, so no need for relative position; just center the image // There's no option for just plain-old centering, so we'll use Top // (which handles the horizontal centering) and some tricksy padding (in OnLayout) // to handle the vertical centering var layout = string.IsNullOrEmpty(_element.Text) ? _imageOnlyLayout : _element.ContentLayout; if (_maintainLegacyMeasurements) { view.CompoundDrawablePadding = (int)layout.Spacing; } else { view.CompoundDrawablePadding = (int)Context.ToPixels(layout.Spacing); } Drawable existingImage = null; var images = TextViewCompat.GetCompoundDrawablesRelative(view); for (int i = 0; i < images.Length; i++) { if (images[i] != null) { existingImage = images[i]; break; } } if (_renderer is IVisualElementRenderer visualElementRenderer) { visualElementRenderer.ApplyDrawableAsync(Button.ImageSourceProperty, Context, image => { if (image == existingImage) { return; } switch (layout.Position) { case Button.ButtonContentLayout.ImagePosition.Top: TextViewCompat.SetCompoundDrawablesRelativeWithIntrinsicBounds(view, null, image, null, null); break; case Button.ButtonContentLayout.ImagePosition.Right: TextViewCompat.SetCompoundDrawablesRelativeWithIntrinsicBounds(view, null, null, image, null); break; case Button.ButtonContentLayout.ImagePosition.Bottom: TextViewCompat.SetCompoundDrawablesRelativeWithIntrinsicBounds(view, null, null, null, image); break; default: // Defaults to image on the left TextViewCompat.SetCompoundDrawablesRelativeWithIntrinsicBounds(view, image, null, null, null); break; } if (_hasLayoutOccurred) { _element?.InvalidateMeasureNonVirtual(InvalidationTrigger.MeasureChanged); } }); } }
public void OnLayout(bool changed, int left, int top, int right, int bottom) { if (_disposed || _renderer == null || _element == null) { return; } AButton view = View; if (view == null) { return; } Drawable drawable = null; Drawable[] drawables = TextViewCompat.GetCompoundDrawablesRelative(view); if (drawables != null) { foreach (var compoundDrawable in drawables) { if (compoundDrawable != null) { drawable = compoundDrawable; break; } } } if (drawable != null) { int iconWidth = drawable.IntrinsicWidth; drawable.CopyBounds(_drawableBounds); // Center the drawable in the button if there is no text. // We do not need to undo this as when we get some text, the drawable recreated if (string.IsNullOrEmpty(_element.Text)) { var newLeft = (right - left - iconWidth) / 2 - view.PaddingLeft; _drawableBounds.Set(newLeft, _drawableBounds.Top, newLeft + iconWidth, _drawableBounds.Bottom); drawable.Bounds = _drawableBounds; } else { if (_alignIconWithText && _element.ContentLayout.IsHorizontal()) { var buttonText = view.TextFormatted; // if text is transformed, add that transformation to to ensure correct calculation of icon padding if (view.TransformationMethod != null) { buttonText = view.TransformationMethod.GetTransformationFormatted(buttonText, view); } var measuredTextWidth = view.Paint.MeasureText(buttonText, 0, buttonText.Length()); var textWidth = Math.Min((int)measuredTextWidth, view.Layout.Width); var contentsWidth = ViewCompat.GetPaddingStart(view) + iconWidth + view.CompoundDrawablePadding + textWidth + ViewCompat.GetPaddingEnd(view); var newLeft = (view.MeasuredWidth - contentsWidth) / 2; if (_element.ContentLayout.Position == Button.ButtonContentLayout.ImagePosition.Right) { newLeft = -newLeft; } if (ViewCompat.GetLayoutDirection(view) == ViewCompat.LayoutDirectionRtl) { newLeft = -newLeft; } _drawableBounds.Set(newLeft, _drawableBounds.Top, newLeft + iconWidth, _drawableBounds.Bottom); drawable.Bounds = _drawableBounds; } } } _hasLayoutOccurred = true; }