Xamarin 自定义渲染器:圆形按钮的自定义渲染器
我正在使用PCL Xamarin表单项目开发一个跨平台应用程序。我的应用程序将在ios、android、windows 10和windows 8.1桌面上运行 我想为xamarin表单中的按钮控件创建一个自定义呈现程序,在这个呈现程序中,我可以从xaml页面和代码隐藏中指定以下属性-Xamarin 自定义渲染器:圆形按钮的自定义渲染器,xamarin,xamarin.forms,portable-class-library,custom-renderer,Xamarin,Xamarin.forms,Portable Class Library,Custom Renderer,我正在使用PCL Xamarin表单项目开发一个跨平台应用程序。我的应用程序将在ios、android、windows 10和windows 8.1桌面上运行 我想为xamarin表单中的按钮控件创建一个自定义呈现程序,在这个呈现程序中,我可以从xaml页面和代码隐藏中指定以下属性- 边框颜色 边框宽度 边界半径 背景色 文本颜色 文本字体大小、颜色、属性(如粗体) 按钮的高度和宽度 我尝试过xamarin窗体的普通按钮控件,但在android和Windows10的悬停按钮颜色更改中,边框半径不
我尝试过xamarin窗体的普通按钮控件,但在android和Windows10的悬停按钮颜色更改中,边框半径不起作用。
那么我如何才能做到这一点呢?在Android中,
radiuproperty
停止仅使用AppCompat
它是一个
AppCompat
如果您想同时使用普通按钮和AppCompat,则需要继承按钮并注册CustomRenderer
[assembly: ExportRenderer(typeof(RoundButton), typeof(RoundButtonRenderer))]
namespace Project.Droid.Renderers
{
public class RoundButtonRenderer : Xamarin.Forms.Platform.Android.AppCompat.ButtonRenderer
{
ButtonDrawable _backgroundDrawable;
Drawable _defaultDrawable;
bool _drawableEnabled;
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (_backgroundDrawable != null)
{
_backgroundDrawable.Dispose();
_backgroundDrawable = null;
}
}
base.Dispose(disposing);
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
base.OnElementChanged(e);
if (e.OldElement != null && _drawableEnabled)
{
_drawableEnabled = false;
_backgroundDrawable.Reset();
_backgroundDrawable = null;
}
UpdateDrawable();
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (_drawableEnabled &&
(e.PropertyName == VisualElement.BackgroundColorProperty.PropertyName || e.PropertyName == Xamarin.Forms.Button.BorderColorProperty.PropertyName || e.PropertyName == Xamarin.Forms.Button.BorderRadiusProperty.PropertyName ||
e.PropertyName == Xamarin.Forms.Button.BorderWidthProperty.PropertyName))
{
_backgroundDrawable.Reset();
Control.Invalidate();
}
base.OnElementPropertyChanged(sender, e);
}
private void UpdateDrawable()
{
if (Element.BackgroundColor == Color.Default)
{
if (!_drawableEnabled)
return;
if (_defaultDrawable != null)
Control.SetBackground(_defaultDrawable);
_drawableEnabled = false;
}
else
{
if (_backgroundDrawable == null)
_backgroundDrawable = new ButtonDrawable();
_backgroundDrawable.Button = Element;
if (_drawableEnabled)
return;
if (_defaultDrawable == null)
_defaultDrawable = Control.Background;
Control.SetBackground(_backgroundDrawable.GetDrawable());
_drawableEnabled = true;
}
Control.Invalidate();
}
}
public class ButtonDrawable : IDisposable
{
object _backgroundDrawable;
PropertyInfo ButtonProperty;
public Xamarin.Forms.Button Button
{
get
{
return (Xamarin.Forms.Button)ButtonProperty.GetMethod.Invoke(_backgroundDrawable, null);
}
set
{
ButtonProperty.SetMethod.Invoke(_backgroundDrawable, new object[] { value });
}
}
public ButtonDrawable()
{
_backgroundDrawable = typeof(Xamarin.Forms.Platform.Android.ButtonRenderer).Assembly.CreateInstance("Xamarin.Forms.Platform.Android.ButtonDrawable");
this.ResetMethod = _backgroundDrawable.GetType().GetMethod("Reset", BindingFlags.Instance | BindingFlags.Public);
this.DisposeMethod = _backgroundDrawable.GetType().GetMethod("Dispose", BindingFlags.Instance | BindingFlags.Public);
this.ButtonProperty = _backgroundDrawable.GetType().GetProperty("Button", BindingFlags.Instance | BindingFlags.Public);
}
MethodInfo ResetMethod;
public void Reset()
{
ResetMethod.Invoke(_backgroundDrawable, null);
}
MethodInfo DisposeMethod;
public void Dispose()
{
DisposeMethod.Invoke(_backgroundDrawable, null);
}
public Android.Graphics.Drawables.Drawable GetDrawable()
{
return _backgroundDrawable as Android.Graphics.Drawables.Drawable;
}
}
}
我在我的应用程序上使用这些属性,对我来说效果很好。 我将这些属性与“样式”一起使用 例如:
<Style x:Key="buttonStyle" TargetType="Button">
<Setter Property="BackgroundColor" Value="{DynamicResource Snow}"/>
<Setter Property="TextColor" Value="{DynamicResource LightBlue}" />
<Setter Property="BorderColor" Value="{DynamicResource LightBlue}"/>
<Setter Property="BorderRadius" Value="15"/>
<Setter Property="BorderWidth" Value="1"/>
<Setter Property="FontAttributes" Value="Bold" />
</Style>
我的按钮:
<Button Text="Login" Command="{Binding LoginCommand}" Style="{DynamicResource buttonStyle}" />
你的问题是什么?@Jason你还不清楚我的问题吗?“我需要…”不是问题。Border radius在IOS上有效吗?我还没有试过。从来没有遇到过问题,但是没有在任何windows平台上试过。我在Windows10和8.1中试过普通的按钮控件,效果很好@Sonali如果你在BorderRadius
上加了一个不正确的量,超过了它的一半高度,那就有点错误了好吧,我会记住这一点,所以为android定制渲染器只能解决我的问题,对吧?我已经尝试过了,但在android上不起作用。按钮没有边框,也没有圆角,可以清除项目并重新编译。也许只是文件上的垃圾。我在我当前的项目中使用这个,我没有遇到任何问题。我尝试了这个,得到了一个错误:没有定义名称空间前缀“x”
<Button Text="Login" Command="{Binding LoginCommand}" Style="{DynamicResource buttonStyle}" />
<ContentPage.Resources>
<ResourceDictionary>
<Style x:Key="myRoundbutton" TargetType="Button">
<Setter Property="BackgroundColor" Value="Green"/>
<Setter Property="TextColor" Value="White" />
<Setter Property="BorderColor" Value="Blue"/>
<Setter Property="CornerRadius" Value="35"/>
<Setter Property="HeightRequest" Value="70" />
<Setter Property="WidthRequest" Value="70"/>
<Setter Property="BorderWidth" Value="2"/>
<Setter Property="FontAttributes" Value="Bold" />
</Style>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout HorizontalOptions="Fill"
VerticalOptions="Fill">
<Button Image="myBtn3.png"
Command="{Binding LoginCommand}"
Style="{DynamicResource myRoundbutton}" />
</StackLayout>
</ContentPage.Content>