Flutter网络请求教程 从API获取数据并展示

我正在学习Flutter的网络请求功能,尝试从API获取数据并在应用中展示。目前遇到几个问题:

  1. 用http或dio发送请求时,如何处理网络异常和超时?有没有完整的错误处理示例?

  2. 从API获取的JSON数据如何高效解析成Dart对象?试过手动转换但代码很冗余,是否有推荐的工具或最佳实践?

  3. 数据加载过程中想显示加载动画,完成后再展示列表,如何优雅地实现这种状态管理?用setState还是其他方案?

  4. 返回的数据量较大时,列表滚动会卡顿,应该怎么优化性能?

希望有经验的朋友能分享具体代码示例和常见坑点,谢谢!

3 回复

首先添加依赖http,初始化网络请求工具类:

import 'package:http/http.dart' as http;

Future<String> fetchData() async {
  final response = await http.get(Uri.parse('https://api.example.com/data'));
  if (response.statusCode == 200) {
    return response.body;
  } else {
    throw Exception('Failed to load data');
  }
}

创建一个状态管理类来存储和更新数据:

class DataModel with ChangeNotifier {
  String _data = '';
  String get data => _data;

  void updateData(String newData) {
    _data = newData;
    notifyListeners();
  }
}

在UI中使用FutureBuilder获取数据:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<String>(
      future: fetchData(),
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return CircularProgressIndicator();
        } else if (snapshot.hasError) {
          return Text('Error: ${snapshot.error}');
        } else {
          return Text(snapshot.data!);
        }
      },
    );
  }
}

通过ChangeNotifierProvider将数据与UI绑定。这样就完成了从API获取数据并在Flutter界面展示的简单教程。

更多关于Flutter网络请求教程 从API获取数据并展示的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


以下是一个简单的 Flutter 网络请求教程:

  1. 添加依赖
    pubspec.yaml 中添加 http 包:

    dependencies:
      http: ^0.14.0
    
  2. 创建 API 方法
    创建一个方法用于发送 GET 请求并解析数据:

    import 'package:http/http.dart' as http;
    import 'dart:convert';
    
    Future<List<dynamic>> fetchPosts() async {
      final response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/posts'));
      if (response.statusCode == 200) {
        return jsonDecode(response.body);
      } else {
        throw Exception('Failed to load posts');
      }
    }
    
  3. 展示数据
    在 UI 中使用 FutureBuilder 获取并显示数据:

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: PostList(),
        );
      }
    }
    
    class PostList extends StatefulWidget {
      @override
      _PostListState createState() => _PostListState();
    }
    
    class _PostListState extends State<PostList> {
      late Future<List<dynamic>> futurePosts;
    
      @override
      void initState() {
        super.initState();
        futurePosts = fetchPosts();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('Posts')),
          body: FutureBuilder<List<dynamic>>(
            future: futurePosts,
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return ListView.builder(
                  itemCount: snapshot.data!.length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text(snapshot.data![index]['title']),
                    );
                  },
                );
              } else if (snapshot.hasError) {
                return Text('${snapshot.error}');
              }
              return CircularProgressIndicator();
            },
          ),
        );
      }
    }
    
  4. 运行应用
    运行后会显示从 API 获取的帖子标题列表。如果需要更复杂的数据结构或 POST 请求,可以扩展此代码。

Flutter网络请求教程:从API获取数据并展示

在Flutter中,你可以使用http包进行网络请求来获取API数据。以下是完整的实现步骤:

1. 添加依赖

首先在pubspec.yaml中添加http包依赖:

dependencies:
  http: ^0.13.4

然后运行flutter pub get安装依赖。

2. 基本实现代码

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

class ApiExample extends StatefulWidget {
  @override
  _ApiExampleState createState() => _ApiExampleState();
}

class _ApiExampleState extends State<ApiExample> {
  List _posts = [];
  bool _isLoading = true;

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

  Future<void> _fetchData() async {
    try {
      final response = await http.get(
        Uri.parse('https://jsonplaceholder.typicode.com/posts'),
      );

      if (response.statusCode == 200) {
        setState(() {
          _posts = json.decode(response.body);
          _isLoading = false;
        });
      } else {
        throw Exception('Failed to load posts');
      }
    } catch (e) {
      setState(() {
        _isLoading = false;
      });
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('Error: ${e.toString()}')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('API Demo')),
      body: _isLoading
          ? Center(child: CircularProgressIndicator())
          : ListView.builder(
              itemCount: _posts.length,
              itemBuilder: (context, index) {
                final post = _posts[index];
                return ListTile(
                  title: Text(post['title']),
                  subtitle: Text(post['body']),
                );
              },
            ),
    );
  }
}

3. 功能说明

  • 使用http.get()方法发送GET请求
  • json.decode()将JSON响应转换为Dart对象
  • 使用CircularProgressIndicator显示加载状态
  • 错误处理展示SnackBar
  • 数据加载完成后用ListView展示

4. 进阶建议

  1. 将网络请求逻辑分离到单独的Service/Repository层
  2. 使用状态管理解决方案(如Provider、Bloc等)管理数据
  3. 添加缓存机制减少网络请求
  4. 实现分页加载更多数据
  5. 使用dio包替代http包以获得更多高级功能

希望这个教程能帮助你理解Flutter中的网络请求实现!

回到顶部