android - 通过 bool 值设置 LinearLayout 背景色

标签 android xamarin converter mvvmcross

我正在尝试使用 MvxValueConverter 来根据 bool 值设置 LinearLayout 的背景颜色。转换器看起来像这样:

public class BackgroundColorValueConverter : MvxValueConverter<bool, MvxColor>
{
    private static readonly MvxColor TrueBGColor = new MvxColor(0xDB, 0xFF, 0xCE);
    private static readonly MvxColor FalseBGColor = new MvxColor(0xD6, 0xF6, 0xFF);

    protected override MvxColor Convert(bool value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value ? TrueBGColor : FalseBGColor;
    }
}

在我的 AXML 布局中,我有以下代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    local:MvxBind="BackgroundColor MyBooleanValue, Converter=BackgroundColor">
  <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:gravity="center"
      android:textSize="18dp"
      local:MvxBind="Text MyText" />
</LinearLayout>

我收到以下错误:

Failed to create target binding for binding BackgroundColor for MyBooleanValue

完整的错误轨迹如下:

MvxBind:Error:  8.58 Problem seen during binding execution for binding BackgroundColor for MyBooleanValue - problem InvalidCastException: Cannot cast from source type to destination type.
03-05 14:18:46.434 I/mono-stdout(16474): MvxBind:Error:  8.58 Problem seen during binding execution for binding BackgroundColor for MyBooleanValue - problem InvalidCastException: Cannot cast from source type to destination type.
03-05 14:18:46.434 I/mono-stdout(16474):      at Cirrious.MvvmCross.Plugins.Color.Droid.BindingTargets.MvxViewBackgroundColorBinding.SetValueImpl (System.Object target, System.Object value) [0x00000] in <filename unknown>:0 
      at Cirrious.MvvmCross.Plugins.Color.Droid.BindingTargets.MvxViewBackgroundColorBinding.SetValueImpl (System.Object target, System.Object value) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Bindings.Target.MvxConvertingTargetBinding.SetValue (System.Object value) [0x00000] in <filename unknown>:0 
03-05 14:18:46.434 I/mono-stdout(16474):   at Cirrious.MvvmCross.Binding.Bindings.Target.MvxConvertingTargetBinding.SetValue (System.Object value) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Bindings.MvxFullBinding.UpdateTargetFromSource (System.Object value) [0x00000] in <filename unknown>:0 

所以,老实说,我不确定从这里到哪里去。我正在尝试的是可能的吗?我使用的是正确的 MvvmCross 转换器吗?任何指针将不胜感激。


更新:

将转换器更改为:

public class BackgroundColorValueConverter : MvxColorValueConverter
{
    private static readonly MvxColor TrueBGColor = new MvxColor(0xDB, 0xFF, 0xCE);
    private static readonly MvxColor FalseBGColor = new MvxColor(0xD6, 0xF6, 0xFF);

    protected override MvxColor Convert(object value, object parameter, System.Globalization.CultureInfo culture)
    {
        return (bool)value ? TrueBGColor : FalseBGColor;
    }
}

...解决了我的问题。我的 LinearLayout 上也有 TextColor MyBooleanValue, Converter=TextColor,它的功能与 BackgroundColorValueConverter 类似,但我遇到了同样的错误创建目标绑定(bind)。

一旦我将 AXML 更改为:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    local:MvxBind="BackgroundColor MyBooleanValue, Converter=BackgroundColor">
  <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:gravity="center"
      android:textSize="18dp"
      local:MvxBind="Text MyText; TextColor MyBooleanValue, Converter=TextColor" />
</LinearLayout>

...一切都按预期进行。对于将来碰巧遇到此问题的任何人:不要尝试将 TextColor 绑定(bind)到 LinearLayout 上,因为它不会那样工作!

最佳答案

https://github.com/MvvmCross/MvvmCross-Tutorials/blob/master/ValueConversion/ValueConversion.UI.Droid/Resources/Layout/View_Colors.axml 中有一个 BackgroundColor 绑定(bind)的工作示例

这使用来自 https://github.com/MvvmCross/MvvmCross/blob/v3.1/Plugins/Cirrious/Color/Cirrious.MvvmCross.Plugins.Color.Droid/BindingTargets/MvxViewBackgroundColorBinding.cs 的 BackgroundColor 绑定(bind)

这个示例适合您吗?

如果是,您能看出该样本与您正在使用的样本之间的区别吗?颜色插件有问题吗? (它加载到您的 UI 项目中了吗?)这是 LinearLayout 与 TextView 的问题吗?您可以提供更多错误跟踪吗?您提供的一行跟踪是在 https://github.com/MvvmCross/MvvmCross/blob/1ec7bc5f0307595c7ae11f56727dd0e9d2a2262f/Cirrious/Cirrious.MvvmCross.Binding/Bindings/MvxFullBinding.cs#L139 上创建的- 但通常在那条线之前还有其他痕迹。

如果不是,那就令人担忧了,因为这意味着这是一个普遍的错误...


更新:(在提供更多信息后)

我认为问题出在您的 ValueConverter - 要与 Android 一起使用,您的 ValueConverter 必须以 Native 类型结束 - 而不是平台无关的 MvxColor。您看到的错误是无效的转换异常 - 因为绑定(bind)试图将您的 MvxColor 转换为 https://github.com/MvvmCross/MvvmCross/blob/v3.1/Plugins/Cirrious/Color/Cirrious.MvvmCross.Plugins.Color.Droid/BindingTargets/MvxViewBackgroundColorBinding.cs#L25 中的 Android.Graphics.Color

要转换为 Native,您可以使用 MvxColorValueConverter 基类 - 参见 https://github.com/MvvmCross/MvvmCross/blob/v3.1/Plugins/Cirrious/Color/Cirrious.MvvmCross.Plugins.Color/MvxColorValueConverter.cs

其中一个例子是 https://github.com/MvvmCross/MvvmCross-Tutorials/blob/master/ValueConversion/ValueConversion.Core/Converters/Converters.cs#L35

public class ContrastColorConverter : MvxColorValueConverter
{
    protected override MvxColor Convert(object value, object parameter, CultureInfo culture)
    {
        var input = (MvxColor) value;
        var brightnessToUse = SimpleContrast(input.R, input.G, input.B);
        return new MvxColor(brightnessToUse, brightnessToUse, brightnessToUse);
    }

    private static int SimpleContrast(params int[] value)
    {
        // this is only a very simple contrast method
        // for more advanced methods you need to look at HSV-type approaches

        int max = 0;
        foreach (var v in value)
        {
            if (v > max)
                max = v;
        }

        return 255 - max;
    }
}

https://github.com/MvvmCross/MvvmCross/wiki/Value-Converters#wiki-the-mvx-color-valueconverters 中有一些关于颜色转换器的文档

关于android - 通过 bool 值设置 LinearLayout 背景色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22206659/

相关文章:

java - 在 DefaultTest.class 文件中使用 swagger 自动生成请求参数

jsf - 为 ManagedBean (JSF 1.2) 中的类获取 JSF 转换器

string - 快速将字符串转换为 CLLocationCoordinate2D

android - 从另一个类调用 bool 方法

android - Android上的HttpClient : NoHttpResponseException root cause In my project,是吧?

Android NDK C++ JNI(没有找到原生的实现......)

xamarin.ios - 在 iOS8 的 UITextField 中检测退格

android - 如何知道 Oxyplot 中的缩放级别 - PlotView With DateTimeAxes

c# - 在 Android Xamarin.forms 上的整个应用程序中保持沉浸式模式

Java:如何将 String[] 转换为 List 或 Set