☰
【Jetpack Compose基础语法学与练】第10课 点击事件进阶、Dropdown下拉菜单,状态联动综合练习
2026/10/9 10:09:52 网站建设 项目流程

前言

上一课学习了副作用API: SideEffect 与 LaunchedEffect ,掌握协程异步任务,理解组件生命周期内的代码执行控制。
前面我们只用了简单Button点击,本课学习状态联动,以Dropdown下拉菜单作为案例。下拉菜单是典型的“点击切换显隐 + 选中项保存”场景,能完整练习布尔状态、点击事件、条件渲染的组合使用。

前置:完成1~9课,掌握状态、重组、条件渲染、基础布局

一、完整可运行示例源码

packagecom.example.composefirstimportandroid.os.Bundleimportandroidx.activity.ComponentActivityimportandroidx.activity.compose.setContentimportandroidx.compose.foundation.layout.Columnimportandroidx.compose.foundation.layout.Spacerimportandroidx.compose.foundation.layout.heightimportandroidx.compose.foundation.layout.paddingimportandroidx.compose.material3.Buttonimportandroidx.compose.material3.DropdownMenuItemimportandroidx.compose.material3.ExperimentalMaterial3Apiimportandroidx.compose.material3.ExposedDropdownMenuBoximportandroidx.compose.material3.ExposedDropdownMenuDefaultsimportandroidx.compose.material3.Textimportandroidx.compose.material3.TextFieldimportandroidx.compose.runtime.Composableimportandroidx.compose.runtime.getValueimportandroidx.compose.runtime.mutableStateOfimportandroidx.compose.runtime.rememberimportandroidx.compose.runtime.setValueimportandroidx.compose.ui.Modifierimportandroidx.compose.ui.tooling.preview.Previewimportandroidx.compose.ui.unit.dpclassMainActivity:ComponentActivity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContent{DropdownDemoPage()}}}@OptIn(ExperimentalMaterial3Api::class)@ComposablefunDropdownDemoPage(){// 控制下拉框展开/收起varexpandedbyremember{mutableStateOf(false)}// 保存选中的文本varselectedTextbyremember{mutableStateOf("请选择城市")}// 下拉选项列表valoptions=listOf("北京","上海","青岛","杭州")Column(modifier=Modifier.padding(20.dp)){ExposedDropdownMenuBox(expanded=expanded,onExpandedChange={expanded=!expanded}){TextField(value=selectedText,onValueChange={},readOnly=true,label={Text("城市选择")},trailingIcon={ExposedDropdownMenuDefaults.TrailingIcon(expanded=expanded)},modifier=Modifier.menuAnchor())ExposedDropdownMenu(expanded=expanded,onDismissRequest={expanded=false}){options.forEach{item->DropdownMenuItem(text={Text(item)},onClick={selectedText=item expanded=false})}}}Spacer(modifier=Modifier.height(20.dp))Text(text="你选中的城市:$selectedText")}}@Preview@ComposablefunDropdownPreview(){DropdownDemoPage()}

二、逐行代码解读

  1. 两个核心状态
varexpandedbyremember{mutableStateOf(false)}varselectedTextbyremember{mutableStateOf("请选择城市")}
  • expanded :布尔类型,控制下拉菜单是否展开。 true 展开, false 收起。点击输入框时取反切换。
  • selectedText :字符串,保存用户最终选中的选项。
  1. ExposedDropdownMenuBox
    下拉菜单的外层容器,Material3推荐的下拉组件。
  • expanded :绑定展开状态;
  • onExpandedChange :点击输入框区域触发,用来切换展开布尔值。
    .menuAnchor() 修饰器标记锚点,告诉菜单弹出时相对于这个输入框定位。
  1. 只读TextField
    readOnly = true ,不能手动输入文字,只用来展示选中结果,作为下拉的触发器。
    trailingIcon 自动根据expanded状态渲染上下箭头图标。
  2. ExposedDropdownMenu
    下拉弹出面板。
  • expanded :和外层状态绑定;
  • onDismissRequest :点击空白区域,自动回调,我们在这里把 expanded 设为false,关闭下拉。
  1. DropdownMenuItem 下拉条目
    遍历选项列表生成每一行选项。
    点击条目时做两件事:
  2. 将选中内容赋值给 selectedText ;
  3. 把 expanded 置为false,关闭下拉菜单。
    状态改变触发重组,页面下方的Text同步刷新选中结果。
  4. @OptIn(ExperimentalMaterial3Api::class)
    Material3的下拉组件目前属于实验性API,需要加上这个注解,消除编译警告。

三、核心知识点:状态联动逻辑

整个下拉菜单是典型的多状态联动:
点击输入框 → 修改 expanded → 菜单展开。
点击菜单项 → 修改 selectedText ,同时把 expanded 关闭 → 面板收起,展示选中内容。
点击空白处 → onDismissRequest 触发, expanded 置false,面板收起。

重点:所有UI变化,全部由状态驱动,不是直接操作控件,符合Compose声明式思想。

四、综合练习题

填空题

  1. 控制下拉菜单展开/收起的状态一般使用______类型。
  2. Material3下拉菜单外层容器组件是________。
  3. 点击空白区域关闭下拉菜单,由________回调处理。

答案与解析

  1. Boolean;解析:展开只有true/false两种状态,布尔类型最合适。
  2. ExposedDropdownMenuBox ;解析:Material3下拉组件外层容器。
  3. onDismissRequest ;解析:点击空白、返回键时触发,用来关闭弹出菜单。

判断题

  1. ExposedDropdownMenuBox的menuAnchor修饰器用于标记弹出菜单的锚点位置。()

答案:正确。理由:menuAnchor标记锚点,下拉面板会相对于这个组件弹出。

  1. DropdownMenuItem点击后,会自动关闭下拉菜单,不需要手动修改expanded。()

答案:错误。理由:点击条目不会自动关闭,代码里必须手动设置expanded=false收起面板。

  1. readOnly为true的TextField,用户无法手动输入文字,仅用于展示。()

答案:正确。理由:只读输入框禁止键盘输入,只用来展示选择结果。

简答题

  1. 简述下拉菜单的完整状态联动流程。

参考答案:
点击输入框,触发onExpandedChange,expanded状态取反为true,下拉面板展开;
点击某一个选项,更新选中文本selectedText,同时将expanded设为false,面板关闭;
点击页面空白区域,触发onDismissRequest,expanded置false,面板关闭;
状态变更触发重组,界面自动刷新。

代码实操题

改造示例:增加一个重置按钮,点击后恢复默认提示文字「请选择城市」,并且关闭下拉菜单。写出按钮代码。参考答案

Button(onClick={selectedText="请选择城市"expanded=false}){Text("重置选择")}

解析:点击重置按钮,重置选中文本,同时把expanded设置为false,确保下拉菜单关闭。

五、本课小结

  1. ExposedDropdownMenu是Material3推荐下拉组件,属于实验API,需要@OptIn注解。
  2. 布尔状态expanded控制面板显隐,选中内容单独保存到另一个状态变量。
  3. 弹出组件需要处理onDismissRequest,支持点击空白关闭。
  4. 核心思想:界面所有变化由状态驱动,属于状态联动的综合练习。

下一课:Card卡片、Checkbox复选框,多表单元素组合实战。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询