Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 89864

Custom Renderer for button with padding not properly sizing buttons in Android

$
0
0

I'm having a lot of trouble getting something that should be very simple to work. All I want is to have buttons with a little bit of padding around the text or icon in the UI. Following an answer on Stack Overflow, I created a custom renderer for a button with padding.

Xamarin.Forms ButtonWithPadding:

using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms;

namespace Messenger.UI.Controls
{
    public class ButtonWithPadding : Button
    {
        public Thickness Padding
        {
            get { return (Thickness)GetValue(PaddingProperty); }
            set { SetValue(PaddingProperty, value); }
        }

        public static readonly BindableProperty PaddingProperty =
            BindableProperty.Create("Padding", typeof(Thickness), typeof(ButtonWithPadding), new Thickness(-1.0));
    }
}

iOS Custom Renderer:

using Messenger.UI.Controls;
using System;
using System.Collections.Generic;
using System.Text;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(ButtonWithPadding), typeof(Messenger.iOS.Controls.ButtonWithPaddingRenderer))]
namespace Messenger.iOS.Controls
{
    public class ButtonWithPaddingRenderer : ButtonRenderer
    {
        public ButtonWithPaddingRenderer() : base()
        {
        }

        protected ButtonWithPadding buttonWithPadding;

        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);

            if (buttonWithPadding == null)
                buttonWithPadding = e.NewElement as ButtonWithPadding;

            var iosButton = Control as UIButton;

            Thickness padding = buttonWithPadding.Padding;

            if (padding.Left > 0)
            {
                iosButton.ContentEdgeInsets = new UIEdgeInsets(
                    new nfloat(padding.Top),
                    new nfloat(padding.Left),
                    new nfloat(padding.Bottom),
                    new nfloat(padding.Right)
                );
            }

        }
    }
}

Android Custom Renderer:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Messenger.Droid.Controls;
using Messenger.UI.Controls;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using System.ComponentModel;

[assembly: ExportRenderer(typeof(ButtonWithPadding), typeof(ButtonWithPaddingRenderer))]
namespace Messenger.Droid.Controls
{
    public class ButtonWithPaddingRenderer : ButtonRenderer
    {
        public ButtonWithPaddingRenderer(Context c) : base(c) { }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
        {
            base.OnElementChanged(e);
            UpdatePadding();
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if (e.PropertyName == nameof(ButtonWithPadding.Padding))
                UpdatePadding();
        }

        private void UpdatePadding()
        {
            ButtonWithPadding buttonWithPadding = Element as ButtonWithPadding;

            if (buttonWithPadding != null && buttonWithPadding.Padding.Left > 0)
            {
                Control.SetPadding(
                    (int) buttonWithPadding.Padding.Left,
                    (int) buttonWithPadding.Padding.Top,
                    (int) buttonWithPadding.Padding.Right,
                    (int) buttonWithPadding.Padding.Bottom
                );
            }

        }
    }
}

Finally, I have this XAML for displaying the buttons with padding:

<StackLayout BackgroundColor="#024985" Orientation="Horizontal" HorizontalOptions="FillAndExpand">

    <Button
        x:Name="HelpButton"
        Text="?"
        HorizontalOptions="EndAndExpand"
        VerticalOptions="CenterAndExpand"
        WidthRequest="26"
        HeightRequest="26"
        BorderRadius="13"
        TextColor="White"
        BackgroundColor="#327fc0"
        Clicked="OnHelpButtonClicked" />

    <controls:ButtonWithPadding
        x:Name="SettingsButton"
        Image="ic_settings"
        TextColor="White"
        BackgroundColor="#327fc0"
        HeightRequest="26"
        WidthRequest="26"
        BorderRadius="13"
        Padding="2"
        HorizontalOptions="End"
        VerticalOptions="CenterAndExpand"
        Clicked="SettingsButtonClicked" />

</StackLayout>

Sorry for all the code, but I thought I'd share everything I thought was relevant! Anyway, the buttons render correctly in iOS:


But fail to size properly in Android:


How can I fix this? Bonus points if you can tell me how to get rid of the drop shadow on the Android buttons as well! :)


Viewing all articles
Browse latest Browse all 89864

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>