【问题标题】:AutomationId for TabBar items not getting set in Android with Xamarin Forms未使用 Xamarin Forms 在 Android 中设置 TabBar 项的 AutomationId
【发布时间】:2021-10-06 14:05:51
【问题描述】:

所以我有以下代码:

<TabBar Route="Dashboard">
   <Tab Title="Dashboard" AutomationId="DashboardId">
      //more codes here
   </Tab>
   <Tab AutomationId="AddNewId">
      //more codes here
   </Tab>
   <Tab Title="Statistics" AutomationId="StatisticsId">
      //more codes here
   </Tab>
</TabBar>

请注意,在我的MainActivityOnCreate() 中,我设置了以下内容:

Xamarin.Forms.Forms.ViewInitialized += (object sender, Xamarin.Forms.ViewInitializedEventArgs e) => {
    if (!string.IsNullOrWhiteSpace(e.View.AutomationId))
    {
        e.NativeView.ContentDescription = e.View.AutomationId;
    }
};

这与我的其他元素完美配合,TabBar 项目除外。不知何故,TabBar 项目正在获取 Title 属性,并且设置位于 accessibilityId/content-dec

任何人都知道这是为什么,我怎样才能使它正确AutomationId?谢谢

【问题讨论】:

    标签: xamarin xamarin.forms appium appium-android


    【解决方案1】:

    AutomationId 在 Android 上存在多个问题。

    Android - Using AutomationId prevents TalkBack screenreader accessibility 讨论了根本问题:

    Xamarin.Forms“借用”Android 上的 ContentDescription 属性用于自动化 ID。这些 ID 污染了 Android 的 TalkBack 可访问性树,使应用几乎无法导航。

    这意味着您可以支持测试自动化或可访问性,而不是两者。我们的应用需要同时支持两者。

    Tabs 的情况下,大概Xamarin 代码正在执行您所看到的:将Title 复制到content-desc,以便Android 文本阅读器会说出它。

    建议的解决方法是编写自定义渲染器来满足您的需求。在comment by codingL3gend 中描述:

    我能够通过创建 customrenderer 和相应的自定义组件来解决此问题,以允许覆盖触发可访问性事件时触发的本机 android 方法。您需要在自定义组件上创建一些可绑定属性,您可以在自定义渲染器中访问这些属性,以便将内容描述值设置为您想要的值,但这很简单。

    每当触发可访问性事件时,都会在控件/自定义渲染器中触发此方法

    public override bool OnRequestSendAccessibilityEvent(Android.Views.View child, AccessibilityEvent e)
      {
             if (AccessibilityHandler.IsAccessibilityEnabled(_context) && child != null)
             {
                    if (!string.IsNullOrEmpty(_automationId) && _automationId.Equals(child.ContentDescription))
                    {
                        child.ContentDescription = $"{_automationName} {_helpText}";
                    }
             }
    
             return base.OnRequestSendAccessibilityEvent(child, e);
    }
    

    然后您可以将控件/自定义渲染器的 contentDescription 值设置回控件/自定义渲染器与视图分离时的automationId 值。

    protected override void OnDetachedFromWindow()
      {
            base.OnDetachedFromWindow();
    
            if (!string.IsNullOrEmpty(_automationId))
            {
                Control.ContentDescription = _automationId;
            }
      }
    

    帮助类

    public static class AccessibilityHandler
        {
            public static bool IsAccessibilityEnabled(Context context)
            {
                var accessibility = (AccessibilityManager)context.GetSystemService(MainActivity.AccessibilityService);
    
                return accessibility?.GetEnabledAccessibilityServiceList(Android.AccessibilityServices.FeedbackFlags.Spoken)?.Count > 0;
            }
        }
    

    如果您在测试期间只需要 AutomationId,或者您可以忍受它对辅助功能屏幕阅读器的影响(尤其是它不会是多语言的),那么您可以做很多测试时使用的更简单的自定义渲染器。

    将其放入您的自定义渲染器中(如果不是 Tab,则将 &lt;Tab&gt; 更改为适当的 Xamarin 类):

    protected override void OnElementChanged( ElementChangedEventArgs<Tab> e )
    {
        base.OnElementChanged( e );
    
        if (e.OldElement != null)
        {
            // Removing previous element.
            // TBD: Remove obsolete references. (usually not needed)
        }
        if (Element == null)
            // Going away with no replacement.
            return;
    
        UpdateAutomationId();
    }
    
    void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(Element.AutomationId))
        {
            UpdateAutomationId();
        }
    }
    
    void UpdateAutomationId()
    {
        var _automationId = Element.AutomationId;
        if (!string.IsNullOrEmpty(_automationId))
        {
            Control.ContentDescription = _automationId;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-21
      • 2019-11-08
      • 2021-05-16
      • 2019-11-06
      • 2021-04-23
      • 2014-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多