c# - Xamarin.Forms 动态按钮样式

标签 c# android xamarin android-styles

我想实现我自己的自定义按钮样式。每当按钮更改其状态(即从启用到禁用)时,样式都必须更改。

我当前的解决方案是在 Android 中定义样式,并且我的自定义 ButtonRenderer 将此样式应用于按钮。

Button_Style.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_pressed="true" >
    <shape>
      <solid
          android:color="#d7d7d7" />
      <stroke
          android:width="1dp"
          android:color="#d7d7d7" />
      <corners
          android:radius="6dp" />
      <padding
          android:left="10dp"
          android:top="10dp"
          android:right="10dp"
          android:bottom="10dp" />
    </shape>
  </item>
  <item android:state_enabled="false">
    <shape>
      <solid
          android:color="#efefef" />
      <stroke
          android:width="1dp"
          android:color="#efefef" />
      <corners
          android:radius="6dp" />
      <padding
          android:left="10dp"
          android:top="10dp"
          android:right="10dp"
          android:bottom="10dp" />
    </shape>
  </item>
  <item>
    <shape>
      <gradient
          android:startColor="#d7d7d7"
          android:endColor="#d7d7d7"
          android:angle="270" />
      <stroke
          android:width="1dp"
          android:color="#d7d7d7" />
      <corners
          android:radius="6dp" />
      <padding
          android:left="10dp"
          android:top="10dp"
          android:right="10dp"
          android:bottom="10dp" />
    </shape>
  </item>
</selector>

自定义渲染器:

using FrameworkForms.UserControl;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Color = Android.Graphics.Color;

[assembly: ExportRenderer(typeof(CustomButton), typeof(FrameworkForms.Droid.Renderer.CustomizedButtonRenderer))]
namespace FrameworkForms.Droid.Renderer
{
    public class CustomizedButtonRenderer : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            base.OnElementChanged(e);
            if (Control != null)
            {
                Control.SetBackgroundResource(Resource.Drawable.button_style);
                Control.SetAllCaps(false);
                if (!Control.Enabled)
                {
                    Control.SetTextColor(Color.ParseColor("#858585"));
                }
            }
        }
    }
}

我的按钮启用属性上有一个绑定(bind)。问题非常明显,一旦属性发生变化,按钮就不会再次渲染并保持之前状态的文本颜色。

我对 Xamarin.Forms 中的样式做了一些研究。似乎动态样式应该为我做这件事,但我想为我的所有按钮都使用它(就像全局样式)。我可以以某种方式将它们结合起来吗?或者这是一个更好的解决方案?值得一提的是,我不介意再次在 iOS 上实现整个事情。无论如何都会有所不同。所以 Android xml-Styles 也可以做到这一点。

谢谢。

最佳答案

如果您想在 IsEnabled 属性更改时更改某些内容,则需要重写 OnElementPropertyChanged:

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);
        if(e.PropertyName == "IsEnabled")
        {
            if(Element.IsEnabled)
            {
                Control.SetTextColor(Color.ParseColor("#858585"));
                Control.SetBackgroundResource(Resource.Drawable.YourEnabledResource);
            }
            else
            {
                Control.SetTextColor(Element.TextColor.ToAndroid());
                Control.SetBackgroundResource(Resource.Drawable.YourDisabledResource);
            }
        }
    }

然后您可以创建两个可绘制的 xml 文件来定义启用和禁用的不同资源。我相应地将它们命名为 YourEnabledResourceYourDisabledResource

关于c# - Xamarin.Forms 动态按钮样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43068924/

相关文章:

c# - 使用 Windows 上配置的 DSN 连接 ODBC(没有用户名和密码)

c# - LINQ IEnumerable 的序列化结果

android - 位图解码资源 - 三星 S5 上的内存不足崩溃

c# - "could not be loaded"是通过重启修复的错误吗?

xaml - 为什么在这种情况下看不到嵌套的 FlexLayout?

c# - 在 C# 中存储设置的设计模式

c# - ASP C# |使用 SQL 和存储过程更新数据库

java - 如何查询基于数组的行列表?

android - 在Android中连接蓝牙耳机后,如何在内置麦克风和耳机麦克风之间切换音频输入?

android - Xamarin.Forms 在 Android 和 IOS 中的设计分离