简体   繁体   中英

Xamarin.Forms XAML Rounded Button

I'm trying to place a rounded Button in my Xamarin.Forms application, but I can't do it.

I read something about a custom controller to the button, but I didn't find any docs about rounded buttons in Xamarin.Forms .

Does anyone know how to do it? I'm just building an Android and iOS application.

You can use the BorderRadius property to create rounded corners on a Button

<Button Text="BlueButton"
        BorderColor="Blue"
        BorderRadius="5"
        BorderWidth="2"/>

You need to use CornerRadius instead of BorderRadius because:

'Button.BorderRadius' is obsolete: 'BorderRadius is obsolete as of 2.5.0. Please use CornerRadius instead.'

Example: XButton.CornerRadius = 5;

If you are trying to have a Round button, use the below code. The height and width needs to be same and also proportionate to Border Radius.

<Button HorizontalOptions="Fill" VerticalOptions="Fill" Text="+">              
            <Button.WidthRequest>
              <OnIdiom x:TypeArguments="x:Double" Phone="60" Tablet="80" />
            </Button.WidthRequest>
            <Button.HeightRequest>
              <OnIdiom x:TypeArguments="x:Double" Phone="60" Tablet="80" />
            </Button.HeightRequest>
            <Button.BorderRadius>
              <OnIdiom x:TypeArguments="x:Int32" Phone="30" Tablet="40" />
            </Button.BorderRadius>
 </Button>

You can ignore the different size for tablets if you are fine in having the same size on phone and tablets.

Note : This won't work on Windows. You will get a square button.

In Android, if your mainactivity is inheriting from AppCompact you will have to add this too.

The side of xaml the property is ConerRadius, Example:

<Button 
    CornerRadius="20"
    Text="{i18n:Translate Cancel}"
    Command="{Binding CancelarCommand}" 
    BackgroundColor="{StaticResource ButtonBackgroundColorbuscar}" 
    TextColor="White" /> 

If you want an image button you can use this ButtonCirclePlugin for Xamarin Forms.

Or an ImageCircle such as this ImageCirclePlugin for Xamarin Forms and add a TapGestureRecognizer.

Try this C# code

private const int BUTTON_BORDER_WIDTH = 1;
private const int BUTTON_HEIGHT = 65;
private const int BUTTON_HEIGHT_WP = 40;
private const int BUTTON_HALF_HEIGHT = 33;
private const int BUTTON_HALF_HEIGHT_WP = 20;
private const int BUTTON_WIDTH = 65;
private const int BUTTON_WIDTH_WP = 20;
var chkIm = new Button()
{
    BackgroundColor = Color.Black,
    HorizontalOptions = LayoutOptions.Center,
    TextColor = Color.White,
    BorderRadius = Device.OnPlatform(BUTTON_HALF_HEIGHT, BUTTON_HALF_HEIGHT, BUTTON_HALF_HEIGHT_WP),
    HeightRequest = Device.OnPlatform(BUTTON_HEIGHT, BUTTON_HEIGHT, BUTTON_HEIGHT_WP),
    MinimumHeightRequest = Device.OnPlatform(BUTTON_HEIGHT, BUTTON_HEIGHT, BUTTON_HEIGHT_WP),
    WidthRequest = Device.OnPlatform(BUTTON_WIDTH, BUTTON_WIDTH, BUTTON_WIDTH_WP),
    MinimumWidthRequest = Device.OnPlatform(BUTTON_WIDTH, BUTTON_WIDTH, BUTTON_WIDTH_WP),
};

If you do not wish to drop down to using a renderer, and you don't mind not having a circular button on Windows Phone, you can use this code:

private const int BUTTON_BORDER_WIDTH = 1;

// Normal button height
//private const int BUTTON_HEIGHT = 44;
//private const int BUTTON_HEIGHT_WP = 72;
//private const int BUTTON_HALF_HEIGHT = 22;
//private const int BUTTON_HALF_HEIGHT_WP = 36;
//private const int BUTTON_WIDTH = 44;
//private const int BUTTON_WIDTH_WP = 72;

// Large button Height
private const int BUTTON_HEIGHT = 88;
private const int BUTTON_HEIGHT_WP = 144;
private const int BUTTON_HALF_HEIGHT = 44;
private const int BUTTON_HALF_HEIGHT_WP = 72;
private const int BUTTON_WIDTH = 88;
private const int BUTTON_WIDTH_WP = 144;

public RoundButtonPage()
{
    var button = new Button
    {
        HorizontalOptions = LayoutOptions.Center,
        BackgroundColor = Color.Accent,
        BorderColor = Color.Black,
        TextColor = Color.White,
        BorderWidth = BUTTON_BORDER_WIDTH,
        BorderRadius = Device.OnPlatform(BUTTON_HALF_HEIGHT, BUTTON_HALF_HEIGHT, BUTTON_HALF_HEIGHT_WP),
        HeightRequest = Device.OnPlatform(BUTTON_HEIGHT, BUTTON_HEIGHT, BUTTON_HEIGHT_WP),
        MinimumHeightRequest = Device.OnPlatform(BUTTON_HEIGHT, BUTTON_HEIGHT, BUTTON_HEIGHT_WP),
        WidthRequest = Device.OnPlatform(BUTTON_WIDTH, BUTTON_WIDTH, BUTTON_WIDTH_WP),
        MinimumWidthRequest = Device.OnPlatform(BUTTON_WIDTH, BUTTON_WIDTH, BUTTON_WIDTH_WP),
        Text = "ClickMe"
    };

    var stack = new StackLayout
    {
        VerticalOptions = LayoutOptions.Center,
        Orientation = StackOrientation.Vertical,
        Children = { button },
    };

    Padding = new Thickness(10, Device.OnPlatform(20, 0, 0), 10, 5);
    Content = stack;
}

It will make a button with rounded corners. To make a button totally round you just set the border radius to be half of the height.

The only thing to remember is that your button has to be large enough to contain the contents. You can see what I mean by commenting/uncommenting out the two constant sections at the top. The first set is good for a number or letter, and the second one is good for a phrase, like "ClickMe."

Again, this uses the native buttons of the platform and since WP doesn't support a border radius all buttons on WP will be rectangular so you'll need to use the technique that James shows in the CircularImage control.

To create rounded (circular) button try this...

  <Button WidthRequest = 100,
            HeightRequest = 100,
            BorderRadius = 50 />

In general, WidthRequest=x, HeightRequest=x, BorderRadius=x/2

There is no BorderRadius Property in the current version of Xamarin Forms. An alternative is the CornerRadius Property.

example:

<Button Text="Submit"
 FontSize="Large"
 TextColor="White"
 BackgroundColor="Green" 
 CornerRadius="100"

Yo can use this style and converter to get General Circular Button.

Style in App.xaml

<Style x:Key="CircleButton" TargetType="{x:Type Button}">
    <Setter Property="CornerRadius" Value="{Binding Source={RelativeSource Self}, Path=WidthRequest, Converter={StaticResource NumberDivideConverter}, ConverterParameter=2}" />
    <Setter Property="HeightRequest" Value="{Binding Source={RelativeSource Self}, Path=WidthRequest}" />
</Style>

Don't forget to add below line to your head of App.xaml :

xmlns:converters="clr-namespace:AlarteInclinometer.Converters"

and

<converters:NumberDivideConverter x:Key="NumberDivideConverter" />

to in App.xaml

Your converter class which divides corner radius to WidthRequest / 2 is:

NumberDivideConverter.cs:

public class NumberDivideConverter : IValueConverter
{
    /// <summary>
    /// Converts binding property to calculated new property
    /// </summary>
    /// <param name="value">Source value</param>
    /// <param name="targetType">Target type of to be calculated (return) value.</param>
    /// <param name="parameter">Converter parameter.</param>
    /// <param name="culture">Converter culture.</param>
    /// <returns>New calculated value.</returns>
    /// <exception cref="ArgumentNullException">If value is null, throws ArgumentNullException</exception>
    /// <exception cref="ArgumentException">If value cannot be converted to a integer, throws ArgumentException</exception>
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Check is value not null
        if (value == null)
            throw new ArgumentNullException($"Value is null");

        // Check is value integer
        if (int.TryParse(value.ToString(), out int intValue))
        {
            // If there is no parameter value, return same value 
            if (parameter == null)
                return intValue;

            // If there is converter parameter, divide number with it and return new result
            if (int.TryParse(parameter.ToString(), out int param))
                return intValue / param;
        }
        // Throw an error if value is not an integer
        else
        {
            throw new ArgumentException($"The value must be a integer but it is a/an {value}");
        }

        return 0;
    }

    /// <summary>
    /// Converts calculated property to binding property
    /// </summary>
    /// <param name="value">Source value</param>
    /// <param name="targetType">Target type of to be calculated (return) value.</param>
    /// <param name="parameter">Converter parameter.</param>
    /// <param name="culture">Converter culture.</param>
    /// <returns>New calculated value.</returns>
    /// <exception cref="ArgumentNullException">If value is null, throws ArgumentNullException</exception>
    /// <exception cref="ArgumentException">If value cannot be converted to a integer, throws ArgumentException</exception>
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Check is value not null
        if (value == null)
            throw new ArgumentNullException($"Value is null");

        // Check is value integer
        if (int.TryParse(value.ToString(), out int intValue))
        {
            // If there is no parameter value, return same value 
            if (parameter == null)
                return intValue;

            // If there is converter parameter, divide number with it and return new result
            if (int.TryParse(parameter.ToString(), out int param))
                return intValue * param;
        }
        // Throw an error if value is not an integer
        else
        {
            throw new ArgumentException($"The target must be a integer but it is a/an {value}");
        }

        return 0;
    }
}

After that, you can use this style in buttons where you want like:

<Button Text="Circular" WidthRequest="120" Style="{StaticResource CircleButton}" />

This is the best solution I think:)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM