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

Flutter中如何实现多Widget切换?点击按钮展示对应组件

Flutter实现点击按钮切换对应Widget展示

需求:有一行包含4个OutlinedButton,分别对应4个Widget(ListView、ListWheelScrollView、PNG图片、SVG图片),点击某个按钮时仅展示对应的Widget。

实现思路

通过状态管理记录当前选中的按钮索引,根据索引动态切换下方展示的Widget:

  1. 使用StatefulWidget维护当前选中状态;
  2. 定义变量_currentIndex存储当前选中的按钮序号;
  3. 每个按钮的onPressed回调更新_currentIndex;
  4. 根据_currentIndex返回对应Widget。

完整示例代码

import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; // 需要在pubspec.yaml添加依赖: flutter_svg: ^2.0.9

class WidgetSwitcherPage extends StatefulWidget {
  const WidgetSwitcherPage({super.key});

  @override
  State<WidgetSwitcherPage> createState() => _WidgetSwitcherPageState();
}

class _WidgetSwitcherPageState extends State<WidgetSwitcherPage> {
  // 记录当前选中的按钮索引,初始默认展示第一个Widget
  int _currentIndex = 0;

  // 定义四个对应展示的Widget
  final List<Widget> _displayWidgets = [
    // 1. ListView
    ListView.builder(
      itemCount: 20,
      itemBuilder: (context, index) => ListTile(
        title: Text('列表项 ${index + 1}'),
      ),
    ),
    // 2. ListWheelScrollView
    ListWheelScrollView.useDelegate(
      itemExtent: 100,
      childDelegate: ListWheelChildBuilderDelegate(
        childCount: 15,
        builder: (context, index) => Container(
          alignment: Alignment.center,
          color: Colors.blue[100 * ((index % 5) + 1)],
          child: Text('滚轮项 ${index + 1}'),
        ),
      ),
    ),
    // 3. PNG图片(替换为你的本地图片路径或网络地址)
    Center(
      child: Image.asset(
        'assets/images/sample.png',
        width: 200,
        height: 200,
        fit: BoxFit.contain,
      ),
    ),
    // 4. SVG图片(替换为你的本地SVG路径或网络地址)
    Center(
      child: SvgPicture.asset(
        'assets/icons/sample.svg',
        width: 200,
        height: 200,
        colorFilter: const ColorFilter.mode(Colors.green, BlendMode.srcIn),
      ),
    ),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Widget切换示例')),
      body: Column(
        children: [
          // 顶部按钮行
          Container(
            padding: const EdgeInsets.all(8.0),
            height: 100,
            child: Row(
              children: [
                Expanded(
                  child: OutlinedButton(
                    style: OutlinedButton.styleFrom(
                      // 选中按钮高亮样式
                      backgroundColor: _currentIndex == 0 ? Colors.blue[100] : null,
                    ),
                    onPressed: () => setState(() => _currentIndex = 0),
                    child: const Text('ListView'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: OutlinedButton(
                    style: OutlinedButton.styleFrom(
                      backgroundColor: _currentIndex == 1 ? Colors.blue[100] : null,
                    ),
                    onPressed: () => setState(() => _currentIndex = 1),
                    child: const Text('ListWheel'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: OutlinedButton(
                    style: OutlinedButton.styleFrom(
                      backgroundColor: _currentIndex == 2 ? Colors.blue[100] : null,
                    ),
                    onPressed: () => setState(() => _currentIndex = 2),
                    child: const Text('PNG图片'),
                  ),
                ),
                const SizedBox(width: 8),
                Expanded(
                  child: OutlinedButton(
                    style: OutlinedButton.styleFrom(
                      backgroundColor: _currentIndex == 3 ? Colors.blue[100] : null,
                    ),
                    onPressed: () => setState(() => _currentIndex = 3),
                    child: const Text('SVG图片'),
                  ),
                ),
              ],
            ),
          ),
          // 下方展示区域
          Expanded(
            child: _displayWidgets[_currentIndex],
          ),
        ],
      ),
    );
  }
}

注意事项

  • 若使用本地图片/SVG,需在pubspec.yaml中配置资源路径:
    assets:
      - assets/images/
      - assets/icons/
    
  • 使用SVG需先在pubspec.yaml添加依赖:flutter_svg: ^2.0.9(版本号可按需更新)

内容的提问来源于stack exchange,提问作者Nour Mira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 01:40:27