使用逗号作为带有 MvvmCross 的 android EditText 的小数分隔符

Posted

技术标签:

【中文标题】使用逗号作为带有 MvvmCross 的 android EditText 的小数分隔符【英文标题】:Use Comma as decimal separator for android EditText with MvvmCross 【发布时间】:2016-07-09 09:16:56 【问题描述】:

我正在开发一个使用 Xamarin 和 MvvmCross 的 android 应用程序。 我有一个这样定义的EditText

<EditText
            local:MvxBind="Text PorcentagemDesconto"
            android:inputType="number|numberDecimal"
            android:nextFocusDown="@+id/valorDesconto"
            android:layout_
            android:layout_weight="0.3"
            android:layout_
            android:hint="%"
            android:focusableInTouchMode="true" />

当我点击EditText 时,键盘没有让我选择插入逗号,只有一个 用作小数分隔符。这里的问题是,例如当我插入数字 2.22 时,Binding 假定该值为 222,因为我的设备使用的是 pt-BR 语言环境,使用逗号表示小数,点表示千位。

我已经做了以下解决问题:

创建了一个ValueConverter 替换逗号

public class DecimalValueConverter : MvxValueConverter

    public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    
        return value;
    

    public override object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    
        var strValue = value?.ToString();
        if (string.IsNullOrEmpty(strValue))
            return null;

        strValue = strValue.Replace(".", ",");

        return strValue;
    

但是这样,一旦用户输入第一个十进制数字,光标就会移动到EditText的开头,所以,我还使用EditTextTextChanged事件将选择设置为on输入结束来解决这个问题。

var porcentagemDesconto = v.FindViewById<EditText>(Resource.Id.porcentagemDesconto);
porcentagemDesconto.TextChanged += (s, e) =>

    Activity.RunOnUiThread(() =>
    
        if (porcentagemDesconto.Text != null)
        
            porcentagemDesconto.SetSelection(porcentagemDesconto.Text.Length);
        
    );
;

但老实说,我不喜欢这种解决方案。我需要为我所有接受小数的EditTexts 编写事件代码,或者创建一个自定义视图来执行此操作。

我很难相信我需要创建一个 自定义视图 和一个 ValueConverter 只是为了使用逗号作为小数分隔符,所以,我想知道是否有更好的解决我的问题的方法。

编辑:

我也已经尝试过使用android:digits="0123456789,-",但这样逗号不会出现在键盘上,只会出现在点上。唯一的区别是这样,当我单击点时,什么也没有发生。

【问题讨论】:

【参考方案1】:

这是自 2009 年以来未修复的 Android bug。

你必须设置android:digits

<EditText
    local:MvxBind="Text PorcentagemDesconto"
    android:inputType="number|numberDecimal"
    android:layout_
    android:layout_
    android:hint="%"
    android:digits="0123456789,-"
    android:focusableInTouchMode="true" />

如果你想为不同的国家部署你的应用,你必须使用字符串资源android:digits="@string/localized_digits

values-de/strings.xml 例如德语

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="localized_digits">0123456789,-</string>
</resources>

values/strings.xml 默认

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="localized_digits">0123456789.-</string>
</resources>

或者使用更通用的方法并通过代码设置:

// extension method
public static class EditTextExtension

    public static void FixDigits(this EditText text)
    
        var decimalSign = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
        var digits = $"0123456789decimalSign-";
        text.KeyListener = DigitsKeyListener.GetInstance(digits);
    


// usage
FindViewById<EditText>(Resource.Id.txtNumber).FixDigits();

或者您将扩展方法 FixDigits() 的功能添加到您的自定义 EditText 类中。

【讨论】:

嗨,斯文,感谢您的回答。我尝试了 android:digits 解决方案。请检查我的编辑。有什么方法可以在键盘上显示逗号? 嗯,我的键盘显示逗号。你有默认键盘还是自定义键盘?你用的是哪个安卓版本? 我使用的是默认键盘,我的设备是搭载 Android 5.0 的 Galaxy S5。 使用 DigitsKeyListener 有效。使用时,键盘会显示带有 ".,-+" 文本的选项。第一次单击它会显示一个点,第二次单击它会显示逗号,依此类推。我发现很奇怪 android:digits 解决方案虽然不起作用。 @PedroMartinsTimóteodaCosta 代码是否在三星设备上运行?

以上是关于使用逗号作为带有 MvvmCross 的 android EditText 的小数分隔符的主要内容,如果未能解决你的问题,请参考以下文章

MvvmCross Xamarin Android 在初始屏幕上挂起并带有链接

带有 MvvmCross 的 Xamarin.Android 上的 System.InvalidCastException

MvvmCross Android UI 组件

将 Xamarin.UITest 与 MvvmCross 绑定一起使用

MvvmCross 是不是支持故事板

在 mvvmcross 中显示非视图/视图模型的视图