Flutter欢迎页仅在最后一页显示跳转按钮的实现问题求助
问题解决:Flutter欢迎页多屏跳转按钮实现
问题分析
- context无法识别:原代码在State初始化阶段预创建slides列表,此时State的context未挂载到Widget树,无法用于Navigator导航操作。
- 按钮显示条件:需要实现仅在指定页面(最后一页或标记了button字段的页面)显示跳转按钮。
修改后的完整代码
WelcomeScreen.dart
import 'package:flutter/material.dart'; import '/items.dart'; import '/SecondRoute.dart'; class WelcomeScreen extends StatefulWidget { @override _WelcomeScreenState createState() => _WelcomeScreenState(); } class _WelcomeScreenState extends State<WelcomeScreen> { double currentPage = 0.0; final _pageViewController = PageController(); @override void initState() { super.initState(); _pageViewController.addListener(() { setState(() { currentPage = _pageViewController.page!; }); }); } // 生成页面指示器 List<Widget> indicator() => List<Widget>.generate( items.length, (index) => Container( margin: const EdgeInsets.symmetric(horizontal: 3.0), height: 10.0, width: 10.0, decoration: BoxDecoration( color: currentPage.round() == index ? const Color(0XFF256075) : const Color(0XFF256075).withOpacity(0.2), borderRadius: BorderRadius.circular(10.0), ), ), ); @override Widget build(BuildContext context) { return Scaffold( body: Container( child: Stack( children: <Widget>[ // 动态构建每一页内容,解决context问题 PageView.builder( controller: _pageViewController, itemCount: items.length, itemBuilder: (BuildContext context, int index) { final item = items[index]; return Container( padding: const EdgeInsets.symmetric(horizontal: 18.0), child: Column( children: <Widget>[ Flexible( flex: 1, fit: FlexFit.tight, child: Image.asset( item['image'], fit: BoxFit.fitWidth, width: 220.0, alignment: Alignment.bottomCenter, ), ), Flexible( flex: 1, fit: FlexFit.tight, child: Container( padding: const EdgeInsets.symmetric(horizontal: 30.0), child: Column( children: <Widget>[ Text( item['header'], style: const TextStyle( fontSize: 50.0, fontWeight: FontWeight.w300, color: Color(0XFF3F3D56), height: 2.0, ), ), Text( item['description'], style: const TextStyle( color: Colors.grey, letterSpacing: 1.2, fontSize: 16.0, height: 1.3, ), textAlign: TextAlign.center, ), // 方式一:仅在最后一页显示按钮 if (index == items.length - 1) ElevatedButton( child: const Text('Open route'), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => const SecondRoute()), ); }, ), // 方式二:根据items中的button字段判断(注释掉方式一,打开这个即可) // if (item['button'] == 'true') // ElevatedButton( // child: const Text('Open route'), // onPressed: () { // Navigator.push( // context, // MaterialPageRoute(builder: (context) => const SecondRoute()), // ); // }, // ), ], ), ), ) ], ), ); }, ), Align( alignment: Alignment.bottomCenter, child: Container( margin: const EdgeInsets.only(top: 70.0), padding: const EdgeInsets.symmetric(vertical: 40.0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: indicator(), ), ), ) ], ), ), ); } }
items.dart(无需修改)
List items = [ { "header": "Learn", "description": "Online chat which provides its users maximum functionality to simplify the search", "image": "assets/images/2.png" }, { "header": "Build", "description": "Online chat which provides its users maximum functionality to simplify the search", "image": "assets/images/3.png" }, { "header": "Launch", "description": "Online chat which provides its users maximum functionality to simplify the search", "image": "assets/images/1.png" }, { "header": "Invest", "description": "Online chat which provides its users maximum functionality to simplify the search", "image": "assets/images/5.png" }, { "header": "Travel", "description": "Online chat which provides its users maximum functionality to simplify the search", "image": "assets/images/4.png", "button": "true", } ];
关键修改说明
解决context问题:
- 移除预创建的
slides列表,改为在PageView.builder的itemBuilder中动态构建每一页内容。 - 此时
itemBuilder提供的context已挂载到Widget树,是有效上下文,可直接用于Navigator.push操作。
- 移除预创建的
按钮显示条件:
- 提供两种实现方式,按需选择:
- 方式一:通过
index == items.length -1判断是否为最后一页,显示按钮。 - 方式二:通过
item['button'] == 'true'判断当前页面是否配置了显示按钮,对应items中最后一项的"button": "true"字段。
- 方式一:通过
- 提供两种实现方式,按需选择:
内容的提问来源于stack exchange,提问作者Test
相关产品推荐
相关产品推荐

