Flutter中如何实现多Widget切换?点击按钮展示对应组件
Flutter实现点击按钮切换对应Widget展示
需求:有一行包含4个OutlinedButton,分别对应4个Widget(ListView、ListWheelScrollView、PNG图片、SVG图片),点击某个按钮时仅展示对应的Widget。
实现思路
通过状态管理记录当前选中的按钮索引,根据索引动态切换下方展示的Widget:
- 使用
StatefulWidget维护当前选中状态; - 定义变量
_currentIndex存储当前选中的按钮序号; - 每个按钮的
onPressed回调更新_currentIndex; - 根据
_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
相关产品推荐
相关产品推荐

