You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flutter FutureBuilder启动短暂红屏报错问题求助

Fixing the FutureBuilder Red Screen Error in Your Flutter App

Let's break down why you're seeing that temporary red screen and how to fix it:

The Root Cause

When your app first loads, the FutureBuilder starts building before the future (loading your JSON file) completes. At this point:

  • snapshot.data is null
  • Your code tries to call snapshot.data.toString() which results in the string "null"
  • json.decode("null") returns null, so myData becomes null
  • When ListView.builder tries to access myData.length, it throws the NoSuchMethodError because you're calling .length on a null value.

The Solution

You need to handle the different states of the Future in your FutureBuilder's builder function:

  • Show a loading indicator while the data is being fetched
  • Handle any errors that occur during fetching
  • Only render your list after valid data is available

Here's the corrected code:

import 'dart:convert';
import 'package:flutter/material.dart';

class JsonData extends StatefulWidget {
  @override
  _JsonDataState createState() => _JsonDataState();
}

class _JsonDataState extends State<JsonData> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home Page Data Visualization'),
      ),
      body: Center(
        child: FutureBuilder(
          builder: (context, snapshot) {
            // Handle loading state
            if (snapshot.connectionState == ConnectionState.waiting) {
              return const CircularProgressIndicator();
            }

            // Handle error state
            if (snapshot.hasError) {
              return Text('Error loading data: ${snapshot.error}');
            }

            // Validate data exists before processing
            if (!snapshot.hasData || snapshot.data.toString().isEmpty) {
              return const Text('No data available');
            }

            // Now safely process the data
            var myData = json.decode(snapshot.data.toString());
            return ListView.builder(
              itemBuilder: (BuildContext context, int index) {
                return Card(
                  elevation: 3,
                  child: ListTile(
                    leading: CircleAvatar(
                      child: Text(myData[index]['trade_code'][0]),
                    ),
                    title: Text(myData[index]['trade_code']),
                    subtitle: Column(
                      crossAxisAlignment: CrossAxisAlignment.stretch,
                      children: <Widget>[
                        Text(
                          "\nHigh:" + myData[index]['high'],
                          style: const TextStyle(fontWeight: FontWeight.bold),
                          textAlign: TextAlign.left,
                        ),
                        Text(
                          "Low:" + myData[index]['low'],
                          style: const TextStyle(fontWeight: FontWeight.bold),
                          textAlign: TextAlign.left,
                        ),
                        Text(
                          "Open:" + myData[index]['open'],
                          style: const TextStyle(fontWeight: FontWeight.bold),
                          textAlign: TextAlign.left,
                        ),
                        Text(
                          "Close:" + myData[index]['close'],
                          style: const TextStyle(fontWeight: FontWeight.bold),
                          textAlign: TextAlign.left,
                        ),
                        Text(
                          "Volume:" + myData[index]['volume'],
                          style: const TextStyle(fontWeight: FontWeight.bold),
                          textAlign: TextAlign.left,
                        ),
                        Text(
                          "\nDate:" + myData[index]['date'],
                          style: const TextStyle(fontWeight: FontWeight.bold),
                          textAlign: TextAlign.center,
                        ),
                      ],
                    ),
                    isThreeLine: true,
                  ),
                );
              },
              itemCount: myData.length,
            );
          },
          future: DefaultAssetBundle.of(context)
              .loadString("assets/stock_market_data.json"),
        ),
      ),
    );
  }
}

Key Changes Made

  • Added a check for ConnectionState.waiting to show a loading spinner instead of trying to process null data
  • Added error handling with snapshot.hasError to display any fetch errors gracefully
  • Added validation to ensure snapshot.data exists and isn't empty before decoding the JSON
  • Added const to static widgets where possible for performance improvements

This will eliminate the red screen by ensuring your app never tries to access properties on null data while waiting for the future to complete.

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

火山引擎 最新活动