You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter如何通过DropdownButton切换Text组件展示的书籍章节文本

实现方案

你只需要补全DropdownButton的onChanged回调逻辑,配合setState更新状态即可触发UI重绘,切换展示的章节内容。为了方便后续扩展更多章节,建议先把下拉选项和章节资源做映射,避免单独定义大量texto变量。

具体改动点:

  1. 新增章节资源映射表,关联下拉选项和对应的Vincenco资源
  2. 新增两个状态变量存储当前展示的章节标题、内容
  3. 补全下拉选择的回调逻辑,选中新选项时调用setState更新状态
  4. 将下方文本组件的数据源替换为当前展示的状态变量

修改后的代码:

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,提问作者Радим Одосий

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 16:54:02