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

Flutter中不使用FutureBuilder/ListBuilder从JSON取数据用于用户账户头部

Flutter 不使用FutureBuilder/ListBuilder 实现接口数据展示在UserAccountsDrawerHeader

实现思路

手动管理异步请求生命周期:在页面初始化时调用接口,通过setState更新数据与状态,根据状态渲染对应UI(加载中、错误、成功)。

1. 确认Model层JSON解析正确性

确保你的User Model类包含完整的fromJson方法,能正确映射接口返回的JSON字段:

class User {
  final String userName;
  final String userEmail;
  final String? avatarUrl;

  User({required this.userName, required this.userEmail, this.avatarUrl});

  factory User.fromJson(Map<String, dynamic> json) {
    return User(
      userName: json['name'] ?? '未知用户',
      userEmail: json['email'] ?? '',
      avatarUrl: json['avatar'],
    );
  }
}

2. 复用现有Service层接口

假设你的Service层已经封装好请求方法,返回Future<User>类型:

class UserApiService {
  Future<User> getUserProfile() async {
    final response = await http.get(Uri.parse("https://your-api-endpoint.com/user/profile"));
    if (response.statusCode == 200) {
      return User.fromJson(jsonDecode(response.body));
    } else {
      throw Exception("接口请求失败");
    }
  }
}

3. 页面State层实现状态管理

使用StatefulWidget维护用户数据、加载状态和错误信息,在initState中触发接口请求:

class MainPage extends StatefulWidget {
  const MainPage({super.key});

  @override
  State<MainPage> createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  late User _userData;
  bool _isLoading = true;
  String? _loadError;
  final UserApiService _apiService = UserApiService();

  @override
  void initState() {
    super.initState();
    _fetchUserProfile();
  }

  Future<void> _fetchUserProfile() async {
    try {
      final user = await _apiService.getUserProfile();
      // 页面未销毁时再更新状态,避免报错
      if (mounted) {
        setState(() {
          _userData = user;
          _isLoading = false;
        });
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          _loadError = e.toString();
          _isLoading = false;
        });
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("首页")),
      drawer: Drawer(
        child: ListView(
          padding: EdgeInsets.zero,
          children: [
            // 根据状态渲染不同的DrawerHeader
            _buildDrawerHeader(),
            // 其他Drawer选项
            const ListTile(title: Text("我的收藏"), leading: Icon(Icons.star)),
            const ListTile(title: Text("设置"), leading: Icon(Icons.settings)),
          ],
        ),
      ),
      body: const Center(child: Text("主页内容")),
    );
  }

  Widget _buildDrawerHeader() {
    if (_isLoading) {
      return const DrawerHeader(
        child: Center(child: CircularProgressIndicator()),
      );
    } else if (_loadError != null) {
      return DrawerHeader(
        child: Center(
          child: Text(
            "加载失败:$_loadError",
            textAlign: TextAlign.center,
          ),
        ),
      );
    } else {
      return UserAccountsDrawerHeader(
        accountName: Text(_userData.userName),
        accountEmail: Text(_userData.userEmail),
        currentAccountPicture: _userData.avatarUrl != null
            ? CircleAvatar(
                backgroundImage: NetworkImage(_userData.avatarUrl!),
              )
            : const CircleAvatar(child: Icon(Icons.person)),
        decoration: const BoxDecoration(
          color: Colors.blue,
        ),
      );
    }
  }
}

关键注意事项

  • 必须使用StatefulWidget:只有State类才能通过setState触发UI更新
  • 增加mounted判断:异步请求完成后,先检查页面是否还在树中,避免调用setState导致报错
  • 完善状态覆盖:处理加载中、加载失败、加载成功三种场景,提升用户体验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:25:17