Flutter如何通过DropdownButton切换Text组件展示的书籍章节文本
实现方案
你只需要补全DropdownButton的onChanged回调逻辑,配合setState更新状态即可触发UI重绘,切换展示的章节内容。为了方便后续扩展更多章节,建议先把下拉选项和章节资源做映射,避免单独定义大量texto变量。
具体改动点:
- 新增章节资源映射表,关联下拉选项和对应的
Vincenco资源 - 新增两个状态变量存储当前展示的章节标题、内容
- 补全下拉选择的回调逻辑,选中新选项时调用
setState更新状态 - 将下方文本组件的数据源替换为当前展示的状态变量
修改后的代码:
class _BookMainWidgetState extends State<BookMainWidget> { // 下拉选项列表 final _locations = [ 'Глава 1', 'Глава 2', 'Глава 3', 'Глава 4', 'Глава 5', ]; // 当前选中的下拉项 var _currentItemSelected = 'Глава 1'; // 下拉选项与章节资源的映射表 late final Map<String, Map<String, String>> _chapterMap; // 当前展示的章节标题、内容 late String currentChapterTitle; late String currentChapterContent; @override void initState() { super.initState(); // 初始化章节映射表,后续新增章节只需要在这里加对应配置即可 _chapterMap = { 'Глава 1': { 'title': Vincenco.v1a, 'content': Vincenco.v1 }, 'Глава 2': { 'title': Vincenco.v2a, 'content': Vincenco.v2 }, 'Глава 3': { 'title': Vincenco.v3a, 'content': Vincenco.v3 }, 'Глава 4': { 'title': Vincenco.v4a, 'content': Vincenco.v4 }, 'Глава 5': { 'title': Vincenco.v5a, 'content': Vincenco.v5 }, }; // 初始化默认展示的章节内容 currentChapterTitle = _chapterMap[_currentItemSelected]!['title']!; currentChapterContent = _chapterMap[_currentItemSelected]!['content']!; } @override Widget build(BuildContext context) { return Stack( children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Stack( children: [ Container( decoration: BoxDecoration( color: Colors.white, border: Border.all(color: Colors.black.withOpacity(0.2)), borderRadius: BorderRadius.all(Radius.circular(10)), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.2), blurRadius: 8, offset: Offset(0, 3), ), ],), clipBehavior: Clip.hardEdge, child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ DropdownButton( hint: Text(' Выберите главу...'), isExpanded: true, // 补全选择回调逻辑 onChanged: (newValue) { setState(() { _currentItemSelected = newValue as String; currentChapterTitle = _chapterMap[newValue]!['title']!; currentChapterContent = _chapterMap[newValue]!['content']!; }); }, value: _currentItemSelected, items: _locations.map(( String dropDownStringItem) { return DropdownMenuItem<String>( value: dropDownStringItem, child: Text(dropDownStringItem), ); }).toList() ), SizedBox(height: 10), Column( children: [ Padding( padding: const EdgeInsets.all(8.0), child: Text( currentChapterTitle, style: TextStyle( color: Colors.brown, fontSize: 16, fontWeight: FontWeight.bold ), ), ), Padding( padding: const EdgeInsets.all(8.0), child: Text( currentChapterContent, style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold ), ), ), ] ), // 其余原有代码保持不变
如果不想做映射表,只需要切换texto1和texto2的话,直接修改onChanged逻辑即可:
onChanged: (newValue) { setState(() { _currentItemSelected = newValue as String; if(newValue == 'Глава 1') { texto1a = Vincenco.v1a; texto1 = Vincenco.v1; } else if(newValue == 'Глава 2') { texto1a = Vincenco.v2a; texto1 = Vincenco.v2; } // 其余章节按同样逻辑添加即可 }); },
内容的提问来源于stack exchange,提问作者Радим Одосий
相关产品推荐
相关产品推荐

