简体   繁体   English

Xamarin形成没有边框问题的按钮

[英]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. 我发现StackLayout / ViewCell中的按钮无法呈现边框。

<?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>

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. 我正在使用Xamarin.Forms 2.3,我还试图创建一个按钮,没有边框半径,背景颜色设置为白色,边框颜色和宽度,以上所有答案都不适合我。

Actually I still had to set the BorderRadius to 1 (my width was 2), AND add another workaround that I just cannot understand : 实际上我仍然需要将BorderRadius设置为1(我的宽度为2),并添加另一个我无法理解的解决方法:

In my Android project, I added a Custom renderer, for Button, with nothing in it. 在我的Android项目中,我为Button添加了一个自定义渲染器,其中没有任何内容。 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. 因此,当您使用默认渲染器时,以及使用从默认渲染器继承但尚未包含任何代码行的自定义渲染器时,Xamarin窗体的行为在Android上会有所不同。

My Renderer: 我的渲染器:

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

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

There seems to be a issue in Xamarin.Forms where Button borders don't show on Android when the ButtonRadius is 0 . ButtonRadius为0时,在Android上不显示Button边框的 Xamarin.Forms似乎存在问题。 (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. (从Xamarin.Forms v2.0.0.6482开始,这个问题似乎没有得到解决。)它不太理想,因为它会略微改变按钮的外观,但你可以通过设置BorderRadius = 1来解决它Android或所有平台,给角落略微可感知的四舍五入。

具有各种BorderWidth和BorderRadius值的按钮的示例。

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) 解决方法(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>

Are you using Android? 你在使用Android吗? If yes, then: 如果是,那么:

On Android this property will not have an effect unless VisualElement.BackgroundColor is set to a non-default color. 在Android上,除非将VisualElement.BackgroundColor设置为非默认颜色,否则此属性将不起作用。

In Xamarin.Forms 2.5.0 , the patch has been reverted : 在Xamarin.Forms 2.5.0中 ,补丁已被还原:

"Revert "Fix border on android buttons (#941)" ( #1192 )" “恢复”修复Android按钮上的边框(#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 : 此错误已在最新版本的Xamarin Forms 2.4.0中修复:

> 36031 - "Button border not drawn on Android without a BorderRadius" (PR) > 36031 - “没有BorderRadius的Android上没有绘制按钮边框”(PR)

in Android project go to MainActivity and change it to be inhereted from 在Android项目中转到MainActivity并将其更改为固有的

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" />

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) 我没有为Android按钮设置背景颜色(仅适用于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>

I found this solution, don't know why is working but it works. 我找到了这个解决方案,不知道为什么工作但它有效。

In PCL 在PCL

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

Then you have to make the render in android and DO NOTHING 然后你必须在android中做渲染并且没有任何东西

[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. 如果没有人知道为什么工作,请解释我,我已经尝试了同样但没有渲染只使用类按钮正常,如果我这样做,我没有得到预期的结果。

in Android project create ButtonRenderer and paste code 在Android项目中创建ButtonRenderer并粘贴代码

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);
    }

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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