概述

车载设置(packages/apps/Car/Settings)是专门为 Android Automotive OS (AAOS) 提供的。车载设置与手机设置(packages/apps/Settings)不同。虽然车载设置包含一些熟悉的手机设置,但车载设置提供了车载视觉用户界面、驾驶员分心优化以及 OEM 的众多自定义入口点。

除了下面提供的车载设置概览外,请参阅以下相关主题以详细了解车载设置

架构和指南

车载设置中的大多数页面都实现为一系列扩展 SettingsFragment 的 Fragment,每个 Fragment 都有其自己在 CarSettingActivities 中定义的 Activity。这些静态 Activity 扩展自 BaseCarSettingsActivity。虽然此规则有一些例外情况,例如,某些特殊 Fragment 扩展 BaseFragment 而不是 SettingsFragment,以及某些 Activity 驻留在 CarSettingActivities 之外,但所有这些都应被视为例外情况(而不是要遵循的模式)。

静态偏好设置

静态偏好设置在 XML 中使用 PreferenceCarUiPreference 标记定义。SettingsFragment 实现使用 getPreferenceScreenResId() 方法来定义哪个 XML 文件包含要显示的静态偏好设置列表。

动态偏好设置

动态偏好设置使用 PreferenceGroup 标记或 PreferenceGroup 的实现。

在 CarSettings 应用中,动态偏好设置代表一组正常的偏好设置,这些偏好设置将用户定向到 CarSettings 内的其他页面,但这些偏好设置是通过 偏好设置控制器 而不是在 XML 中添加的。一个示例是“语言和输入”偏好设置下的“管理键盘”偏好设置,它会根据是否允许这些输入法,动态地将输入法添加到偏好设置页面。

操作栏

每个设置屏幕的顶部都有一个操作栏,其中可以包含“返回”导航、屏幕标题和补充操作微件(例如,按钮和开关)。这些操作栏类似于 Android 提供的 ActionBar,但实际上是自定义视图。在 Android 11 及更高版本中,此工具栏包含在底盘基本布局中,其中包含工具栏的视图和一个用于应用其余内容的 FrameLayout。

补充操作微件是 MenuItem 类,应在相应 SettingsFragmentBaseFragmentonCreate 中创建。诸如可见性、状态等属性应由 SettingsFragment 的业务逻辑中的 setter 控制。

// ExampleSettingsFragment.java
public class ExampleSettingsFragment extends SettingsFragment {

    @Override
    protected List<MenuItem> getToolbarMenuItems() {
        return Collections.singletonList(mClearConfirmButton);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mButton = new MenuItem.Builder(getContext())
                .setTitle(R.string.text)
                .setOnClickListener(mOnClickListener)
                .setUxRestrictions(CarUxRestrictions.UX_RESTRICTIONS_NO_SETUP)
                .build();
    }

    private void updateState() {
        button.setVisible(false);
    }
}

操作栏支持车载设置中的分心优化。在创建时在 MenuItem.Builder 中设置 UXRestrictions。

偏好设置控制器

每个设置页面都可以容纳许多不同的 偏好设置

请参阅下图,了解这些组件是如何关联的

CarSettings Components

图 1. CarSettings 组件

PreferenceController 是一个生命周期感知型组件,有助于封装与特定偏好设置相关的业务逻辑。PreferenceController 只能通过 XML 附加到相关的偏好设置。

// example_settings_fragment.xml
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:settings="http://schemas.android.com/apk/res-auto"
    android:title="@string/example_settings_title">
  <Preference
    android:key="@string/pk_example_preference_key"
    android:title="@string/example_preference_title"
    settings:controller="com.android.car.settings.example.ExamplePreferenceController"/>
</PreferenceScreen>

车载设置明确禁止通过代码创建 PreferenceController,以便更轻松地修改设置层次结构,同时最大限度地减少对 Java 代码的更改。

PreferenceController 可能需要一些动态数据才能正确运行。例如,关闭应用的通知的 PreferenceController 需要知道要对哪个应用执行操作。由于 PreferenceController 始终在 XML 中定义,因此无法提供其他构造函数参数。相反,这些附加值通过 PreferenceController 上的公共 setter 提供,并使用 SettingsFragment 中的 use(...) 方法进行设置。

// ExamplePreferenceController.java
public class ExamplePreferenceContorller extends PreferenceController<Preference> {

  private ExampleArg mExampleArg;

  public ExamplePreferenceController(...) {
    ...
  }

  public void setExampleArg(ExampleArg exampleArg) {
    mExampleArg = exampleArg;
  }
}

// ExampleSettingsFragment.java
public class ExampleSettingsFragment extends SettingsFragment {

  @Override
  @XmlRes
  protected int getPreferenceScreenResId() {
    Return R.xml.example_settings_fragment;
  }

  @Override
  public void onAttach(Context context) {
    ExampleArg arg = (ExampleArg) getArguments().getSerializeable(ARG_KEY);
    ExamplePreferenceController controller =
        use(ExamplePreferenceController.class, R.string.pk_example_preference_key);
    controller.setExampleArg(arg);
  }
}

使用 use(...) 方法的频率越高,就越难实现能够重新排列设置层次结构同时最大限度地减少对 Java 代码的更改这一最初目标,因为需要将现有 Fragment 代码的大部分复制到新创建的 Fragment 中。最大限度地减少执行此操作的难度的一种方法是

  • 尽量减少 use(...) 的使用。
  • 尝试将对 use(...) 的每次调用都放在 Fragment 中的一个位置(例如,在 onAttach() 方法中)。

Intent 处理

Car Settings 应用应处理的所有 Intent 都在 清单文件中定义。Intent 通常像大多数标准 Android 应用一样定义和处理,所有 Activity 和 Intent 过滤器都在清单中定义。

更改根 Fragment

如果需要,可以使用 config_show_settings_root_exit_icon 显示或隐藏“退出”图标。

自定义主题

自定义其他属性和资源

Car Settings 应用主要使用 CarSettingTheme,它是 Theme.CarUi 的扩展。此主题用于标准化系统应用的外观,以确保系统中的一致性。

自定义偏好设置

自定义偏好设置跨越以下其他位置

  • 某些基本偏好设置类的布局在 car_preference叠加中为车载版本定义。基本偏好设置类的任何自定义布局都可以在此处替换。
  • Car Settings 使用主要在 common 软件包中定义的一些自定义偏好设置。这些应在 Car Settings 模块中与基本偏好设置类分开叠加。