【问题标题】:Android layout resources for Accessibility vision impairment无障碍视觉障碍的 Android 布局资源
【发布时间】:2017-10-01 07:36:01
【问题描述】:

Android 应用目前支持基于方向、屏幕大小、白天和黑夜等不同的布局资源。

但是,我想提供针对视力障碍用户的布局,例如使用带有黄色背景和黑色文本的布局。

我是否错过了 Android 已经支持的功能?

我可以实现自定义 res/layout-WAI 或 res/layout-DDA 文件夹吗?

【问题讨论】:

    标签: android android-layout android-view wai-aria android-accessibility


    【解决方案1】:

    您无法创建自定义配置限定符。 列出了当前支持的限定符here

    我将建议以下解决方法(示例):

    1. 为每个现有布局创建一个特殊的布局,名称相同,但后缀为“_wai”

      example_layout.xml
      example_layout_wai.xml
      
    2. 根据系统需要创建一种方法来解决适当的布局。假设我们有一个方法 isWAI(),resolve 方法看起来像:

      public int resolveLayoutResourceID(int layoutResID) {
          int newLayoutResID = layoutResID;
          if (isWAI()) {
              String layoutResName = getResources().getResourceEntryName(layoutResID);
              String newLayoutResName = layoutResName + "_wai";
              newLayoutResID = getResources().getIdentifier(newLayoutResName, "layout", getPackageName());
          }
          return newLayoutResID;
      }
      
    3. 为所有类创建一个BaseActivity 类(或使用实用程序静态函数),这将覆盖setContentView 方法。在那里,您将添加一个逻辑来选择布局。

      @Override
      public void setContentView(int layoutResID) {
          int newLayoutResID = resolveLayoutResourceID(layoutResID)
          super.setContentView(newLayoutResID);
      }
      

    【讨论】:

      【解决方案2】:

      颜色(黄色背景和黑色文本)、字体和字体大小是Styles and Themes 的主题。

      除非视力受损的人需要自己的布局(排列、gui 元素的排序),否则您可以使用 a style chooser 实现可应用于每个布局的设置

      【讨论】:

      • 这是真的,但是如果我可以提供 WAI 布局并在用户启用任何其他辅助功能(例如例如三次点击放大或回复等。与简单地提供替代布局相比,以编程方式更改样式、主题和字体需要我的开发人员编写更多需要测试和维护的代码行。我要说的总体要点是……如果 Android 提供了昼夜替代布局资源,为什么不能将其从无障碍布局中移除?
      【解决方案3】:

      您可以在一个布局中参数化视图,而不是提供两种不同的布局。因此,您的布局视图会从它们膨胀的上下文主题中获取参数(例如背景颜色、文本颜色)。

      所以,这就是我们想要实现的目标:

      <android.support.constraint.ConstraintLayout
          android:background="?attr/bgColor"
          ... >
      
          <TextView
              android:textColor="?attr/textColor"
              ... />
      
      </android.support.constraint.ConstraintLayout>
      

      ?attr/someAttribute 将取自当前上下文的主题。

      values/ 中的attrs.xml 创建属性:

      <?xml version="1.0" encoding="utf-8"?>
      <resources>
      
          <declare-styleable name="MyAttrs">
              <attr name="bgColor" format="reference|color"/>
              <attr name="textColor" format="color"/>
          </declare-styleable>
      
      </resources>
      

      styles.xml 中声明从一个共同主题扩展而来的两个主题:

      <resources>
      
          <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
              ...
          </style>
      
          <style name="AppTheme.Default">
              <item name="bgColor">@color/red</item>
              <item name="textColor">@color/blue</item>
          </style>
      
          <style name="AppTheme.Accessibility">
              <item name="bgColor">@color/orange</item>
              <item name="textColor">@color/yellow</item>
          </style>
      
      </resources>
      

      然后,在您的活动中执行断言并设置正确的主题:

      @Override
      protected void onCreate(@Nullable Bundle savedInstanceState) {
          setTheme(isAccessibility ? R.style.AppTheme_Accessibility : R.style.AppTheme_Default);
      
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main_activity);
          ...
      }
      

      或者,如果您必须在运行时执行此操作,您可以使用 ContextThemeWrapper 为特定视图添加适当的主题。

      Context wrapper = new ContextThemeWrapper(MyFragment.this.getContext(), R.style.AppTheme_Accessibility);
      // inflating with a `wrapper`, not with the activity's theme
      View themedView = View.inflate(wrapper, R.layout.some_layout, parent);
      

      这比提供两个单独的布局要好得多,因为它可以避免在 UI 发生变化时维护两个布局。

      【讨论】:

      • 我很欣赏你的方法。然而主题和风格总是让我感到悲伤。我觉得布局方法更清晰......并且通过使用包含我可以减少多个布局问题。
      猜你喜欢
      • 1970-01-01
      • 2019-05-06
      • 2021-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-24
      • 1970-01-01
      相关资源
      最近更新 更多