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

Flutter中_WelcomeScreenState类使用context报错的解决方法

问题分析

你遇到的错误核心原因是:State类的实例成员(比如context)不能在类的成员初始化阶段被访问。你的代码里slides列表是作为类的成员变量直接初始化的,在其中的ElevatedButton的onPressed回调里调用了context,但此时_WelcomeScreenState对象还未完成初始化,context还未绑定,因此触发了这个错误。

最优解决方案

推荐采用在PageView.builder的itemBuilder中直接构建页面内容的方式,既解决了context的访问问题,又符合PageView.builder的懒加载设计,提升性能。具体修改如下:

修改后的完整代码

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!;
      });
    });
  }

  // 直接构建单个slide内容
  Widget _buildSlide(Map item) {
    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 (item.containsKey('button') && item['button'] == 'true')
                    ElevatedButton(
                      child: const Text('Open route'),
                      onPressed: () {
                        Navigator.push(
                          context,
                          MaterialPageRoute(builder: (context) => const SecondRoute()),
                        );
                      },
                    ),
                ],
              ),
            ),
          )
        ],
      ),
    );
  }

  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>[
            PageView.builder(
              controller: _pageViewController,
              itemCount: items.length,
              itemBuilder: (BuildContext context, int index) {
                return _buildSlide(items[index]);
              },
            ),
            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(),
                ),
              ),
            )
          ],
        ),
      ),
    );
  }
}

方案说明

  1. 移除提前初始化的slides列表,改为通过_buildSlide方法按需构建每个页面,此时context已在build方法执行时完成绑定,可正常访问。
  2. 调整indicator的数据源,直接使用items.length,避免依赖提前生成的列表。
  3. 保留原有UI和逻辑,仅修改页面内容的构建时机,既解决错误,又利用PageView.builder的懒加载特性减少内存占用。
其他可选方案

若坚持提前生成列表,可使用延迟初始化方式:

late List<Widget> slides;

@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((_) {
    setState(() {
      slides = items.map((item) => /* 原slide构建代码 */).toList();
    });
  });
}

但该方案性能不如懒加载方案,因此优先推荐第一种方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 14:27:54