HarmonyOS 7 Select 按钮材质关了,菜单怎么还透光?两个接口分开排查

把 Select 的按钮背景换成实色后,点开下拉菜单,菜单仍然像一层半透明玻璃。这时继续调按钮背景颜色通常没用:在 API 26 的沉浸光感里,按钮和菜单是两处不同的材质入口。

这篇只解决这一件事:希望保留 Select 的选择功能,但按需关掉按钮、菜单或两者的沉浸式系统材质。它不是把控件设为 disabled,也不是关闭页面交互。

版本范围:HarmonyOS 7.0 / ArkUI API 26.0.0 起。请先确认工程的 targetSDKVersion 不低于 26.0.0。本文代码按华为 2026-09-06 更新的沉浸光感文档和 Select 接口编写;当前本机只有 API 24 SDK,未在 API 26 设备上编译或截图,下面的“预期结果”是文档推导,不能当作实测结论。

Select 按钮与菜单材质的两处控制点

为什么关了一处,另一处还在

官方把 Select 的两个区域分开控制:systemMaterial 对应下拉按钮本身,menuSystemMaterial 对应展开后的下拉菜单。两处彼此独立。只改前者,不能推断后者也被关掉。

另一个容易混淆的地方是 undefined:官方明确说它会恢复组件默认材质行为,不是“关闭材质”。在默认效果开启的条件下,把参数清成 undefined,反而可能让透光效果回来。明确关闭指定区域应使用 uiMaterial.Material.empty。

你改了什么按钮材质菜单材质能否据此断言 Select 整体已关闭材质
只设置 .systemMaterial(uiMaterial.Material.empty)请求关闭仍按菜单自己的配置/默认规则不能
只设置 .menuSystemMaterial(uiMaterial.Material.empty)仍按按钮自己的配置/默认规则请求关闭不能
两处都设置 Material.empty请求关闭请求关闭可以逐项验收,但仍应看实际设备
把其中一处设为 undefined该处恢复默认规则另一处不受这个赋值影响不能

这里说的是材质效果,不是控件是否可点击、选项是否可选。不要把“菜单看起来变灰”和“菜单交互被禁用”混为一谈。

案例一:只关按钮,复现菜单仍透光

把下面两个 Select 放在同一页,对着有明暗变化的背景观察。第一组留给系统默认行为;第二组只设置按钮材质。展开菜单后,单独记录按钮区域与菜单区域的视觉变化,而不是只拍一张关着菜单的截图。

import { uiMaterial } from '@kit.ArkUI';

@Entry
@Component
struct SelectMaterialCheck {
  build() {
    Column({ space: 24 }) {
      Text('A:默认规则').fontSize(18)
      Select([{ value: '选项一' }, { value: '选项二' }])
        .value('默认 Select')

      Text('B:只关按钮材质').fontSize(18)
      Select([{ value: '选项一' }, { value: '选项二' }])
        .value('只关按钮')
        .systemMaterial(uiMaterial.Material.empty)
    }
    .padding(24)
    .width('100%')
  }
}

复现步骤:在 API 26 设备上运行,分别打开 A 和 B 的菜单;对比 B 的按钮和弹出菜单。若 B 的按钮不再使用沉浸材质、菜单仍有材质表现,说明两个入口确实需要分开处理。不同设备算力、深浅色模式和用户系统设置会改变具体效果,不能要求每台机器的模糊半径一模一样。

案例二:按钮和菜单都要保留普通样式

如果产品确实要求两个区域都不使用沉浸材质,在 Select 上分别设置两个接口,不用删除菜单、更不要禁用控件:

import { uiMaterial } from '@kit.ArkUI';

@Entry
@Component
struct SelectWithoutMaterial {
  build() {
    Column({ space: 16 }) {
      Select([{ value: '标准' }, { value: '紧凑' }])
        .value('选择显示密度')
        .systemMaterial(uiMaterial.Material.empty)
        .menuSystemMaterial(uiMaterial.Material.empty)
    }
    .padding(24)
    .width('100%')
  }
}

验收步骤:先拍菜单关闭状态,再拍展开状态;分别检查按钮与菜单材质是否消失,最后实际选择“紧凑”并确认选中值更新。只看视觉、不测交互,容易把样式问题和功能问题混在一起。

如果仍有透光,不要立刻再叠一层不透明背景。按下面顺序定位:

  1. 看 targetSDKVersion 和设备 API 版本是否真的达到 26.0.0。
  2. 查 entry 模块 module.json5 的 ohos.arkui.UIMaterial.state;这个配置只在 entry 模块生效。
  3. 查代码是否只给 systemMaterial 赋值,却漏了 menuSystemMaterial。
  4. 查是否把 Material.empty 改成了 undefined,导致恢复默认规则。
  5. 查正在观察的到底是 Select 菜单,还是页面上另一个 Popup/Toast;不同浮层有各自接口。
  6. 在深色、浅色和不同算力设备上分别复核;官方说明材质表现会自适应。

全局 disable 适合定位,不适合不加判断地永久套用

如果整页多个浮层都异常,可以临时在 entry 模块 的 module.json5 把应用级状态改为 disable,作为隔离实验:

{
  "module": {
    "name": "entry",
    "type": "entry",
    "metadata": [{
      "name": "ohos.arkui.UIMaterial.state",
      "value": "disable"
    }]
  }
}

重新构建后观察异常是否消失。若消失,说明应该继续检查材质接入和组件样式冲突;若没消失,不该继续把所有问题都归因于沉浸光感。全局开关影响范围大,不能为了修一个 Select 菜单就随手把整个应用的新视觉能力关掉。

default、enable、disable 是应用级状态;Material.empty 是明确关闭具体组件区域材质的方式;undefined 是让该区域回到默认行为。三者作用层级不同。官方文档同时提醒:应用级 disable 下,组件级开启也不会生效;组件级接口只有在该组件实际支持材质接口时才有意义。遇到不支持的组件,不要照搬 Select 的写法。

上线前怎么验收

我会把检查拆成两张截图和一个操作结果:菜单关闭时的按钮、展开后的菜单、选择后显示的值。再把 module.json5 配置值与设备 API 版本记在同一条测试记录里。这样即使后来升级 SDK 或设计调整,也知道“材质没关掉”究竟发生在哪一层。

目前只能确认文档边界和代码接口名称;本机缺 API 26 SDK,尚不能声称上述页面在本机编译或真机运行通过。准备照着做时,请先用 API 26 工程编译,再按两组案例做设备对照。若接口在实际 SDK 中发生变化,以你工程当前对应版本的官方 API 参考为准。

官方资料

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐