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.datais null- Your code tries to call
snapshot.data.toString()which results in the string"null" json.decode("null")returnsnull, somyDatabecomes null- When
ListView.buildertries to accessmyData.length, it throws theNoSuchMethodErrorbecause you're calling.lengthon 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.waitingto show a loading spinner instead of trying to process null data - Added error handling with
snapshot.hasErrorto display any fetch errors gracefully - Added validation to ensure
snapshot.dataexists and isn't empty before decoding the JSON - Added
constto 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




