You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Forms Material Visual:MaterialPicker取消按钮本地化失效问题

问题描述

我为MaterialPickerRenderer编写了如下自定义渲染器:

[assembly: ExportRenderer(typeof(BorderlessPicker), typeof(BorderlessPickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
namespace KitchenAssembly.XF.Droid.CustomRenderer
{
    public class BorderlessPickerRenderer : MaterialPickerRenderer
    {
        public BorderlessPickerRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
        {
            base.OnElementChanged(e);

            if (Control == null || e.NewElement == null)
                return;

            Control.BoxStrokeWidth = 0;
            Control.BoxStrokeWidthFocused = 0;
        }
    }
}

目前需要对其弹出选择框中的“Cancel”按钮进行本地化设置,当前应用默认显示德语版本的“Abbrechen”,但切换应用语言后,该按钮文本并未随之更新,请问该如何解决此问题?


解决方案

核心思路

MaterialPicker的弹窗Cancel按钮默认依赖系统资源加载文本,语言切换后不会自动触发资源重新绑定。需要通过重写弹窗创建逻辑、监听配置变化的方式,手动控制按钮文本的本地化更新。

具体实现

  1. 修改自定义渲染器,重写弹窗创建与配置监听
    更新后的渲染器代码如下,通过自定义上下文获取最新本地化资源,并在语言变化时刷新弹窗:

    [assembly: ExportRenderer(typeof(BorderlessPicker), typeof(BorderlessPickerRenderer), new[] { typeof(VisualMarker.MaterialVisual) })]
    namespace KitchenAssembly.XF.Droid.CustomRenderer
    {
        public class BorderlessPickerRenderer : MaterialPickerRenderer
        {
            private Context _localizedContext;
    
            public BorderlessPickerRenderer(Context context) : base(context)
            {
                _localizedContext = context.CreateConfigurationContext(Resources.Configuration);
            }
    
            protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
            {
                base.OnElementChanged(e);
    
                if (Control == null || e.NewElement == null)
                    return;
    
                Control.BoxStrokeWidth = 0;
                Control.BoxStrokeWidthFocused = 0;
            }
    
            protected override AlertDialog CreateDialog()
            {
                // 从当前语言上下文获取本地化文本
                var cancelText = _localizedContext.Resources.GetString(Resource.String.Cancel);
                var dialog = base.CreateDialog();
    
                // 替换Cancel按钮文本
                var cancelBtn = dialog.GetButton((int)DialogButtonType.Negative);
                cancelBtn?.SetText(cancelText);
    
                return dialog;
            }
    
            // 监听系统语言配置变化
            protected override void OnConfigurationChanged(Configuration newConfig)
            {
                base.OnConfigurationChanged(newConfig);
                _localizedContext = Context.CreateConfigurationContext(newConfig);
    
                // 若弹窗已显示,销毁后重建以更新文本
                if (Dialog != null && Dialog.IsShowing)
                {
                    Dialog.Dismiss();
                    Dialog = CreateDialog();
                    Dialog.Show();
                }
            }
        }
    }
    
  2. 配置多语言资源文件
    在Android项目的对应资源目录下创建strings.xml,添加不同语言的Cancel文本:

    • Resources/values/strings.xml:<string name="Cancel">Cancel</string>
    • Resources/values-de/strings.xml:<string name="Cancel">Abbrechen</string>
  3. 应用内语言切换的额外处理
    如果你的应用支持应用内手动切换语言(非系统语言切换),需要在语言切换后通过消息通知渲染器更新:

    • 在共享项目中用MessagingCenter发送语言变更消息
    • 在渲染器中订阅该消息,收到后更新_localizedContext并刷新弹窗(逻辑同OnConfigurationChanged)

关键说明

  • 必须使用CreateConfigurationContext创建的上下文获取资源,避免默认上下文缓存旧语言资源
  • 系统语言切换时会触发OnConfigurationChanged,此时需重建弹窗同步文本
  • 应用内语言切换需手动触发上下文更新,因为系统不会自动调用配置变更回调

内容的提问来源于stack exchange,提问作者Anna Melashkina

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 10:05:38