4、车载UI基础:Car UI Library介绍、ConstraintLayout在车载屏上的适配、主题与样式

好,咱们进入车载UI这一块。说实话,车载屏幕和手机屏幕完全是两码事。你想想看,手机竖着拿,车载屏横着摆,而且尺寸五花八门——有10寸的、12.3寸的,甚至还有贯穿整个仪表台的“带鱼屏”。

我刚开始做车载项目时,拿着手机那套布局经验直接往上套,结果一跑起来,界面歪七扭八的。嗯,从那以后我就老老实实研究Car UI Library和ConstraintLayout了。

4.1 Car UI Library 是什么?

Car UI Library是Google专门为车载场景推出的一个UI组件库。说白了,它帮你解决了两大痛点:驾驶安全屏幕适配

我个人习惯把它理解成“车载版的Material Design”。但它比Material Design更克制——按钮更大、文字更粗、间距更宽。为什么?因为驾驶员在开车时,视线离开道路的时间不能超过1.5秒。

核心原则:Car UI Library中的所有组件都遵循“3秒规则”——用户从看到控件到完成操作,最多3秒。

常用的组件有这些:

  • CarButton:大尺寸按钮,最小触摸区域48dp,实际建议做到64dp以上
  • CarTextView:自动适配字体大小,支持夜间模式
  • CarRecyclerView:针对车载场景优化的列表,支持快速滑动和焦点管理
  • CarToolbar:顶部导航栏,左侧通常放返回键,右侧放设置

我在项目中遇到过一个问题:用普通Button做音乐播放器的暂停键,结果用户开车时怎么点都点不准。换成CarButton后,触摸区域大了,误触率直接降了70%。

4.2 ConstraintLayout 在车载屏上的适配

车载屏幕的尺寸差异有多大?我列个表你就明白了:

屏幕类型 常见分辨率 宽高比
标准横屏 1280x720 16:9
宽屏 1920x720 8:3
带鱼屏 3840x720 16:3
方形屏 1024x1024 1:1

看到没?从16:9到16:3,跨度非常大。如果用LinearLayout或者RelativeLayout,你得写一堆判断代码。但ConstraintLayout不一样,它用百分比约束链条就能搞定。

举个例子,我要做一个音乐播放界面,左边是专辑封面,右边是歌曲信息和控制按钮。在手机上可能是竖排,但在车载屏上必须是横排,而且左右比例要固定。

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 专辑封面,占左侧30%宽度 -->
    <ImageView
        android:id="@+id/album_cover"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintWidth_percent="0.3"
        app:layout_constraintHeight_percent="0.8"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:src="@drawable/album_placeholder"/>

    <!-- 歌曲信息,占右侧70%宽度 -->
    <LinearLayout
        android:id="@+id/song_info"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:orientation="vertical"
        app:layout_constraintWidth_percent="0.65"
        app:layout_constraintHeight_percent="0.8"
        app:layout_constraintStart_toEndOf="@id/album_cover"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">

        <CarTextView
            android:id="@+id/song_title"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:text="歌曲名称"
            android:textSize="24sp"/>

        <CarTextView
            android:id="@+id/artist_name"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:text="歌手"
            android:textSize="18sp"/>

        <!-- 控制按钮 -->
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="2"
            android:gravity="center">
            <CarButton
                android:id="@+id/btn_prev"
                android:layout_width="64dp"
                android:layout_height="64dp"
                android:text="上一首"/>
            <CarButton
                android:id="@+id/btn_play"
                android:layout_width="80dp"
                android:layout_height="80dp"
                android:text="播放"/>
            <CarButton
                android:id="@+id/btn_next"
                android:layout_width="64dp"
                android:layout_height="64dp"
                android:text="下一首"/>
        </LinearLayout>
    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

小技巧:layout_constraintWidth_percent代替固定dp值,这样不管屏幕是16:9还是16:3,布局比例都不会变。我曾经在1920x720的屏幕上调试时,发现封面图被拉伸了,后来加了android:scaleType="centerCrop"才解决。

4.3 主题与样式

车载应用的主题和手机不一样。手机可以花里胡哨,但车载必须简洁、高对比度、易读。为什么?因为阳光直射时,屏幕会反光,颜色太浅根本看不清。

我建议你从这几个维度来设计主题:

  • 背景色:深色为主(#1A1A2E或#2D2D44),浅色为辅。深色背景能减少反光,也省电(OLED屏)。
  • 文字色:白色或浅灰色(#FFFFFF或#E0E0E0),字号至少16sp,标题建议24sp以上。
  • 强调色:用高饱和度的颜色(比如#FF6B35橙色或#00D2FF青色),但不要超过两种。
  • 夜间模式:必须支持!因为晚上开车时,太亮的屏幕会晃眼。

在代码里,我习惯这样组织主题:

<!-- res/values/themes.xml -->
<resources>
    <style name="Theme.CarApp" parent="Theme.CarUI">
        <!-- 基础颜色 -->
        <item name="colorPrimary">#1A1A2E</item>
        <item name="colorOnPrimary">#FFFFFF</item>
        <item name="colorSecondary">#FF6B35</item>
        <item name="colorOnSecondary">#FFFFFF</item>
        <item name="android:colorBackground">#0F0F1A</item>

        <!-- 文字样式 -->
        <item name="android:textViewStyle">@style/CarTextViewStyle</item>
        <item name="android:buttonStyle">@style/CarButtonStyle</item>
    </style>

    <style name="CarTextViewStyle">
        <item name="android:textColor">#E0E0E0</item>
        <item name="android:textSize">18sp</item>
        <item name="android:lineSpacingExtra">4dp</item>
    </style>

    <style name="CarButtonStyle">
        <item name="android:backgroundTint">#FF6B35</item>
        <item name="android:textColor">#FFFFFF</item>
        <item name="android:textSize">16sp</item>
        <item name="android:minWidth">64dp</item>
        <item name="android:minHeight">64dp</item>
    </style>
</resources>

注意:千万不要在车载应用里用纯白色背景(#FFFFFF)。阳光下一照,驾驶员根本看不清上面的文字。我曾经吃过这个亏,测试时在室内好好的,一上路就被用户投诉了。

另外,夜间模式怎么实现?很简单,用values-night目录:

<!-- res/values-night/themes.xml -->
<resources>
    <style name="Theme.CarApp" parent="Theme.CarUI">
        <item name="colorPrimary">#0A0A14</item>
        <item name="colorOnPrimary">#C0C0C0</item>
        <item name="colorSecondary">#FF8C42</item>
        <item name="android:colorBackground">#05050A</item>
    </style>
</resources>

这样系统就会根据时间自动切换主题。嗯,这里要注意:夜间模式不只是把背景变暗,文字颜色也要相应调低对比度,不然晚上看还是会刺眼。

4.4 避坑指南

最后分享几个我踩过的坑:

  • 触摸区域不够大:车载按钮最小触摸区域建议64dp,不要低于48dp。我曾经用40dp的按钮,用户开车时根本点不准。
  • 字体太小:正文至少16sp,标题至少20sp。别想着“多显示点内容”,安全第一。
  • 忽略焦点管理:车载应用通常用旋钮或方向盘按键操作,必须处理好焦点移动顺序(android:nextFocusDown等属性)。
  • 动画太花哨:开车时不要搞什么旋转、缩放动画,会分散注意力。淡入淡出就够了。

好了,这一章的内容就这些。Car UI Library帮你搭好架子,ConstraintLayout帮你适配各种奇葩屏幕,主题和样式则决定了用户体验的底线。下一章咱们聊聊车载应用的生命周期管理——嗯,那又是一个大坑。