如何独立于操作系统设置更改Picker负按钮文本

时间:2017-11-15 07:50:32

标签: c# xamarin.forms localization xamarin.android

我的应用程序只有英语,但我的手机的操作系统是西班牙语。我在页面中添加了Picker,如果我点击它来更改它的值,我会看到取消按钮文本是西班牙语。我想用英文显示这个按钮。我正在使用Xamarin.Forms,因为我用它来开发更容易,但我只需要知道如何在Android 中进行此更改。我尝试在OnCreate()中的MainActivity方法中更改文化,但它不起作用(在调试和发布时运行)。

Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en");
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

然后我尝试使用Android特定代码(再次使用OnCreate()中的MainActivity方法):

Java.Util.Locale.Default = new Java.Util.Locale("en");

但它不起作用。按钮的文本仍为西班牙语。在这种情况下,我想更改一个特定的文本,但没有公共属性,让我可以更改它(即picker.CancelButtonText)。我想显示“取消”而不是“取消”。你知道怎么改变这个文字吗?

Picker displaying Spanish text

我检查了PickerRender.cs文件,发现了这段代码:

var builder = new AlertDialog.Builder(Context);
builder.SetView(layout);
builder.SetTitle(model.Title ?? "");
builder.SetNegativeButton(global::Android.Resource.String.Cancel, (s, a) =>
{
    ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
    // It is possible for the Content of the Page to be changed when Focus is changed.
    // In this case, we'll lose our Control.
    Control?.ClearFocus();
    _dialog = null;
});

global::Android.Resource.String.Cancelint常量,因此我无法更改它。如果能够访问否定按钮文本,您知道吗?

谢谢你, 乔恩。

2 个答案:

答案 0 :(得分:1)

  

global :: Android.Resource.String.Cancel是一个int常量,所以我无法改变它。如果能够访问否定按钮文本,您知道吗?

您的方向正确,但遗憾的是,目前用户无法访问AlertDialog的{​​{1}},因此无法自定义或自定义本地化Picker按钮文字。

我现在唯一能看到的选项是使用自定义渲染器创建自己的Cancel控件并自己构建Picker,然后您可以通过AlertDialog获取按钮。

答案 1 :(得分:0)

我已设法在否定按钮上设置文字。我创建了CustomPickerCustomPickerRenderer

CustomPicker.cs (没什么特别的):

public class CustomPicker : Picker {}

CustomPickerRenderer.cs (继承自Xamarin.Forms.Platform.Android.AppCompat.PickerRenderer并通过一些更改从中复制一些方法):

using Android.App;
using Android.Content;
using Android.Content.Res;
using Android.Text;
using Android.Widget;
using RendererTest.Droid.Renderers;
using System;
using System.Collections.Specialized;
using System.Linq;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(RendererTest.Controls.CustomPicker), typeof(CustomPickerRenderer))]
namespace RendererTest.Droid.Renderers
{
    public class CustomPickerRenderer : Xamarin.Forms.Platform.Android.AppCompat.PickerRenderer
    {
        AlertDialog _dialog;
        TextColorSwitcher _textColorSwitcher;

        public CustomPickerRenderer(Context context) : base(context) { }

        // This method is necessary to set the OnClickListener, copied removing base.OnElementChanged(e); line
        protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
        {
            if (e.OldElement != null)
                ((INotifyCollectionChanged)e.OldElement.Items).CollectionChanged -= RowsCollectionChanged;

            if (e.NewElement != null)
            {
                ((INotifyCollectionChanged)e.NewElement.Items).CollectionChanged += RowsCollectionChanged;
                if (Control == null)
                {
                    EditText textField = CreateNativeControl();
                    textField.Focusable = false;
                    textField.Clickable = true;
                    textField.Tag = this;
                    textField.InputType = InputTypes.Null;
                    textField.SetOnClickListener(PickerListener.Instance);
                    _textColorSwitcher = new TextColorSwitcher(textField.TextColors);
                    SetNativeControl(textField);
                }
                UpdatePicker();
                UpdateTextColor();
            }
        }

        // This method is necessary to change negative button text.
        void OnClick()
        {
            Picker model = Element;
            if (_dialog == null)
            {
                using (var builder = new AlertDialog.Builder(Context))
                {
                    builder.SetTitle(model.Title ?? "");
                    string[] items = model.Items.ToArray();
                    builder.SetItems(items, (s, e) => ((IElementController)model).SetValueFromRenderer(Picker.SelectedIndexProperty, e.Which));

                    builder.SetNegativeButton("Cancel", (o, args) => { }); // Changing negative button text

                    ((IElementController)Element).SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, true);

                    _dialog = builder.Create();
                }
                _dialog.SetCanceledOnTouchOutside(true);
                _dialog.DismissEvent += (sender, args) =>
                {
                    (Element as IElementController)?.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
                    _dialog.Dispose();
                    _dialog = null;
                };

                _dialog.Show();
            }
        }

        void RowsCollectionChanged(object sender, EventArgs e)
        {
            UpdatePicker();
        }

        void UpdatePicker()
        {
            Control.Hint = Element.Title;

            if (Element.SelectedIndex == -1 || Element.Items == null)
                Control.Text = null;
            else
                Control.Text = Element.Items[Element.SelectedIndex];
        }

        void UpdateTextColor()
        {
            _textColorSwitcher?.UpdateTextColor(Control, Element.TextColor);
        }

        // The listener is changed to work with CustomPickerRenderer
        class PickerListener : Java.Lang.Object, IOnClickListener
        {
            #region Statics

            public static readonly PickerListener Instance = new PickerListener();

            #endregion

            public void OnClick(global::Android.Views.View v)
            {
                var renderer = v.Tag as CustomPickerRenderer; // Work with my renderer
                renderer?.OnClick();
            }
        }
    }
}

还需要将TextColorSwitcher类添加到源代码中。