Giu
Giu

Reputation: 1952

Xamarin forms button with no border issue

I try to render a list of clickable items in a view. I would like to add a button with an image and a white border (the first one). I discovered that the buttons in my StackLayout/ViewCell can't render a border.

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage 
xmlns="http://xamarin.com/schemas/2014/forms" 
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
xmlns:controls="clr-namespace:XLabs.Forms.Controls;assembly=XLabs.Forms"
x:Class="*.PlacesPage"
Title="TEST">
<ContentPage.Padding>
    <OnPlatform x:TypeArguments="Thickness" iOS="0, 20, 0, 0" />
</ContentPage.Padding>
<ContentPage.Content>
    <Grid>
        <ListView x:Name="lvPlaces" ItemsSource="{Binding Places}" SeparatorColor="Gray" SeparatorVisibility="Default" RowHeight="120" >
            <ListView.ItemTemplate>
              <DataTemplate>
                  <ViewCell>
                    <ViewCell.View>
                        <StackLayout Orientation="Horizontal">
                            <Button HorizontalOptions="Center" VerticalOptions="Center" BorderWidth="3" BorderColor="White" Text="IMG"></Button>
                            <Button Text="{Binding Name}" BorderWidth="0" FontSize="20" BackgroundColor="Transparent" Clicked="OnButtonClickedPlace"></Button>
                        </StackLayout>
                    </ViewCell.View>
                  </ViewCell>
              </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</ContentPage.Content>

Upvotes: 6

Views: 20845

Answers (8)

Tzz
Tzz

Reputation: 11

In Xamarin.Forms 2.5.0, the patch has been reverted :

"Revert "Fix border on android buttons (#941)" (#1192)"

You have to use a custom renderer for now...

This bug has been fixed in the last version of Xamarin Forms 2.4.0 :

> 36031 - "Button border not drawn on Android without a BorderRadius" (PR)

Upvotes: 1

user8424728
user8424728

Reputation:

in Android project create ButtonRenderer and paste code

protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {

        if (Control != null)
        {
            var roundableShape = new GradientDrawable();
            roundableShape.SetShape(ShapeType.Rectangle);
            roundableShape.SetStroke((int) Element.BorderWidth,Element.BorderColor.ToAndroid());
            roundableShape.SetColor(Element.BackgroundColor.ToAndroid());
            roundableShape.SetCornerRadius(Element.BorderRadius * Resources.DisplayMetrics.Density);
            Control.Background = roundableShape;
            Control.TransformationMethod = null;
            Control.Elevation = 0;
        }
        base.OnElementPropertyChanged(sender, e);
    }

enter image description here

Upvotes: 0

CarLoOSX
CarLoOSX

Reputation: 525

I found this solution, don't know why is working but it works.

In PCL

namespace xxx.Renderers
{
    public class WhiteButton : Button
    {
        public WhiteButton()
        {
        }
    }
}

Then you have to make the render in android and DO NOTHING

[assembly: ExportRenderer(typeof(WhiteButton), typeof(WhiteButtonRenderer))]
namespace xxxx.Droid.Renderers
{
    public class WhiteButtonRenderer : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {
                var newElement = e.NewElement as WhiteButton;

                if (newElement != null)
                {

                }
            }
        }

    }
}

Then you only have to call instantiate the button and do the border that you want

    var myButton = new WhiteButton()
    {
        BackgroundColor = Color.Transparent,
        TextColor = Color.White,
        Text = "Desconectarse",
        BorderRadius = 45/2,//rounded border Heightbutton/2
        BorderWidth = 2,
        BorderColor = Color.White
    };

If nobody knows why is working please explain me , I have tried the same but with no render only using the class Button normally and if I do this I don't get the expected result.

Upvotes: 0

Marin Shalamanov
Marin Shalamanov

Reputation: 746

Got the some problem. I did two things to solve it:

  1. I don't set background color to the buttons for Android (only for iOS)
<Setter Property="BackgroundColor">
    <OnPlatform x:TypeArguments="x:String">
        <OnPlatform.iOS>Transparent</OnPlatform.iOS>
    </OnPlatform>
</Setter>
  1. Manually setting a background drawable to the buttons
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="rectangle">
  <stroke android:width="2px" android:color="#ffffff" />
</shape>

Upvotes: 0

Abdullah Tahan
Abdullah Tahan

Reputation: 2129

in Android project go to MainActivity and change it to be inhereted from

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity

to

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity

now you won't have issue to use the Border

 <Button Text="test" TextColor="White" 
            BackgroundColor="#FFA733" BorderRadius="15" 
            BorderColor="White" BorderWidth="2" HorizontalOptions="FillAndExpand" />

Upvotes: 0

Miiite
Miiite

Reputation: 1557

I'm using Xamarin.Forms 2.3, and I was also trying to create a button, with no border radius, a background color set to white, and a border color & width, and none of the above answers worked for me.

Actually I still had to set the BorderRadius to 1 (my width was 2), AND add another workaround that I just cannot understand :

In my Android project, I added a Custom renderer, for Button, with nothing in it. Absolutely nothing. So the behavior of Xamarin forms, is different on Android when you use the Default renderer, and when you use a custom renderer that inherits from the default renderer, and yet with no line of code in it.

My Renderer:

[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(GenericButtonRenderer))]

    namespace Express.CustomRenderers
{
    public class GenericButtonRenderer : Xamarin.Forms.Platform.Android.ButtonRenderer
    {
    }
}

Upvotes: 20

patridge
patridge

Reputation: 26565

There seems to be a issue in Xamarin.Forms where Button borders don't show on Android when the ButtonRadius is 0. (It doesn't appear that this issue is fixed as of Xamarin.Forms v2.0.0.6482.) It's not ideal since it will slightly change the look of the button, but you can work around it by setting BorderRadius = 1 for just Android, or all platforms, giving a slightly perceptible rounding to the corners.

Examples of Buttons with various BorderWidth and BorderRadius values.

Workaround (code)

// HACK: fixes a bug where border doesn't work without a radius.
yourButton.BorderRadius = Device.OnPlatform<int>(iOS: 0, Android: 1, WinPhone: 0);

Workaround (XAML)

<Button
    x:Name="YourButton"
    Text="Some Button Text"
    TextColor="Black"
    Clicked="OnClickedDiscover"
    BackgroundColor="Aqua"
    BorderColor="Red"
    BorderWidth="1">
    <Button.BorderRadius>
        <!-- HACK: fixes a bug where border doesn't work without a radius. -->
        <OnPlatform x:TypeArguments="x:Int32">
            <OnPlatform.Android>1</OnPlatform.Android>
        </OnPlatform>
    </Button.BorderRadius>
</Button>

Upvotes: 13

Daniel Luberda
Daniel Luberda

Reputation: 7454

Are you using Android? If yes, then:

On Android this property will not have an effect unless VisualElement.BackgroundColor is set to a non-default color.

Upvotes: 4

Related Questions