如何在Flutter中用FutureBuilder+AsyncSnapshot加载非列表单条数据?
使用FutureBuilder加载渲染单条用户数据
已实现的列表加载效果
我已经成功用Flutter的FutureBuilder结合AsyncSnapshot实现了列表形式用户数据的加载与渲染,相关示例数据及代码如下:
列表示例数据
[ { "name": "kamchatka11111", "email": "kamchatka@mail.com", "index": 1, "picture": "https://static.themoscowtimes.com/image/1360/73/TASS40183186.jpg", "imageFetchType": "networkImage" }, { "name": "Valjakutse", "email": "valjakutse@mail.com", "index": 2, "picture": "https://images.unsplash.com/photo-1561406636-b80293969660?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxzZWFyY2h8M3x8YmxhY2slMjBsYWR5fGVufDB8fDB8fA%3D%3D&w=1000&q=80", "imageFetchType": "imageNetwork" }, { "name": "einstein", "email": "einstein@mail.com", "index": 12, "picture": "https://static.dw.com/image/45897958_303.jpg", "imageFetchType": "fadeInImage" } ]
列表渲染代码
import 'package:flutter/material.dart'; import 'package:master_learn/classes/async_futures.dart'; import 'package:master_learn/widgets/marquee_widget.dart'; class FutureBuilderListUsingHashMap extends StatefulWidget { const FutureBuilderListUsingHashMap({Key? key}) : super(key: key); @override _FutureBuilderListUsingHashMapState createState() => _FutureBuilderListUsingHashMapState(); } class _FutureBuilderListUsingHashMapState extends State<FutureBuilderListUsingHashMap> { @override void initState() { super.initState(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: IconButton( onPressed: () => Navigator.of(context).pop(), icon: const Icon( Icons.arrow_back, color: Colors.white, )), title: const SizedBox( child: MarqueeWidget( direction: Axis.horizontal, child: Text("Fetch"), ), ), ), body: SizedBox( child: FutureBuilder( future: AsyncFutures.fetchListsOfStringDynamicHashMap(), builder: (BuildContext context, AsyncSnapshot asyncSnapshot) { if (asyncSnapshot.data == null) { return const Center(child: CircularProgressIndicator()); } else { return ListView.builder( itemCount: asyncSnapshot.data.length, itemBuilder: (BuildContext context, int index) { return ListTile( contentPadding: const EdgeInsets.all(10), leading: CircleAvatar( backgroundImage: NetworkImage( asyncSnapshot.data[index]["picture"] ?? ""), ), title: Text(asyncSnapshot.data[index]["name"] ?? ''), subtitle: Text( "Email: ${asyncSnapshot.data[index]["email"] ?? ''}"), ); }, ); } }), ), ); } }
当前需求:加载单条用户档案数据
现在需要实现加载并渲染单个用户的详细档案,而非批量列表,示例数据如下:
{ "name": "einstein", "email": "einstein@mail.com", "index": 12, "picture": "https://static.dw.com/image/45897958_303.jpg", "imageFetchType": "fadeInImage" }
实现方案
和列表场景核心逻辑一致,只是不需要用ListView.builder,直接渲染单个布局组件即可,同时建议完善AsyncSnapshot的状态判断(比如加载中、错误状态),增强健壮性:
完整实现代码
import 'package:flutter/material.dart'; import 'package:master_learn/classes/async_futures.dart'; import 'package:master_learn/widgets/marquee_widget.dart'; class FutureBuilderSingleUser extends StatefulWidget { const FutureBuilderSingleUser({Key? key}) : super(key: key); @override _FutureBuilderSingleUserState createState() => _FutureBuilderSingleUserState(); } class _FutureBuilderSingleUserState extends State<FutureBuilderSingleUser> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( leading: IconButton( onPressed: () => Navigator.of(context).pop(), icon: const Icon(Icons.arrow_back, color: Colors.white), ), title: const MarqueeWidget( direction: Axis.horizontal, child: Text("单用户详情"), ), ), body: FutureBuilder<Map<String, dynamic>>( // 替换为获取单条用户数据的异步方法 future: AsyncFutures.fetchSingleUser(), builder: (context, snapshot) { // 加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 错误处理 if (snapshot.hasError) { return Center(child: Text("加载失败: ${snapshot.error}")); } // 数据为空处理 if (!snapshot.hasData || snapshot.data!.isEmpty) { return const Center(child: Text("无用户数据")); } // 数据加载完成,渲染单用户详情 final user = snapshot.data!; return Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ // 用户头像 CircleAvatar( radius: 60, backgroundImage: NetworkImage(user["picture"] ?? ""), ), const SizedBox(height: 20), // 用户名称 Text( user["name"] ?? "未知用户", style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold), ), const SizedBox(height: 10), // 用户邮箱 Text( "邮箱: ${user["email"] ?? "未设置"}", style: const TextStyle(fontSize: 16, color: Colors.grey), ), const SizedBox(height: 10), // 用户索引 Text( "用户ID: ${user["index"] ?? "N/A"}", style: const TextStyle(fontSize: 16), ), ], ), ); }, ), ); } }
关键说明
- 异步方法适配:确保
AsyncFutures中存在fetchSingleUser()方法,返回Future<Map<String, dynamic>>类型的单条用户数据。 - 状态判断完善:新增了
connectionState判断加载中、hasError处理错误、hasData判断数据有效性,避免空指针问题。 - 布局调整:用
Column+Padding替代列表组件,直接展示单个用户的各项信息,布局可以根据需求自定义(比如用Card包裹增强样式)。
内容的提问来源于stack exchange,提问作者Emmanuel Njorodongo
相关产品推荐
相关产品推荐

