Flutter基础(前端教程①⑤-API请求转化为模型列成列表展示实战)

  1. models/post_model.dart

    • 定义 Post 数据模型
    • 包含 fromJson() 方法用于解析 JSON
  2. controllers/post_controller.dart

    • 管理帖子数据的获取和状态
    • 使用 http 包请求 API
    • 通过 RxListRxBool 实现响应式状态管理
  3. views/post_list_view.dart

    • 展示帖子列表的 UI
    • 使用 Obx 监听状态变化
    • 包含加载中、错误和数据展示三种状态
  4. main.dart

    • 应用入口点
    • 使用 GetMaterialApp 作为根组件
    • 设置主题并指定首页

post_controller.dart

Dart 复制代码
// lib/controllers/post_controller.dart
import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import '../models/post_model.dart';

class PostController extends GetxController {
  // 响应式状态
  final RxList<Post> posts = <Post>[].obs;
  final RxBool isLoading = false.obs;
  final RxString? error = RxString?('');

  // 获取帖子列表
  Future<void> fetchPosts() async {
    isLoading.value = true;
    error.value = null;

    try {
      final response = await http.get(
        Uri.parse('https://jsonplaceholder.typicode.com/posts'),
      );

      if (response.statusCode == 200) {
        final List<dynamic> jsonData = json.decode(response.body);
        // 解析JSON并更新状态
        posts.assignAll(jsonData.map((item) => Post.fromJson(item)).toList());
      } else {
        error.value = '请求失败: ${response.statusCode}';
      }
    } catch (e) {
      error.value = '发生错误: $e';
    } finally {
      isLoading.value = false;
    }
  }

  // 初始化
  @override
  void onInit() {
    super.onInit();
    fetchPosts(); // 控制器初始化时加载数据
  }
}    

post_model.dart

Dart 复制代码
// lib/models/post_model.dart
class Post {
  final int id;
  final int userId;
  final String title;
  final String body;

  Post({
    required this.id,
    required this.userId,
    required this.title,
    required this.body,
  });

  // 从JSON解析
  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
      id: json['id'] as int,
      userId: json['userId'] as int,
      title: json['title'] as String,
      body: json['body'] as String,
    );
  }
}    

post_list_view.dart

Dart 复制代码
// lib/views/post_list_view.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controllers/post_controller.dart';

class PostListView extends StatelessWidget {
  const PostListView({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // 获取控制器实例
    final PostController controller = Get.put(PostController());

    return Scaffold(
      appBar: AppBar(
        title: const Text('Posts'),
        centerTitle: true,
      ),
      body: Obx(() {
        // 加载状态
        if (controller.isLoading.value) {
          return const Center(child: CircularProgressIndicator());
        }

        // 错误状态
        if (controller.error.value != null) {
          return Center(child: Text(controller.error.value!));
        }

        // 数据为空
        if (controller.posts.isEmpty) {
          return const Center(child: Text('没有数据'));
        }

        // 数据列表
        return ListView.builder(
          itemCount: controller.posts.length,
          itemBuilder: (context, index) {
            final post = controller.posts[index];
            return Card(
              margin: const EdgeInsets.all(8.0),
              elevation: 2,
              child: ListTile(
                leading: CircleAvatar(child: Text(post.id.toString())),
                title: Text(
                  post.title,
                  style: const TextStyle(fontWeight: FontWeight.bold),
                ),
                subtitle: Text(post.body),
                onTap: () {
                  // 点击显示详情
                  Get.snackbar(
                    'Post #${post.id}',
                    '用户ID: ${post.userId}\n标题: ${post.title}',
                    snackPosition: SnackPosition.BOTTOM,
                  );
                },
              ),
            );
          },
        );
      }),
    );
  }
}    

main.dart

Dart 复制代码
// lib/main.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'views/post_list_view.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter GetX Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const PostListView(),
    );
  }
}    
相关推荐
怀君3 小时前
Flutter——Android原生View是如何通过Flutter进行加载
android·flutter
LinXunFeng10 小时前
Flutter - 聊天面板库动画生硬?这次让你丝滑个够
前端·flutter·github
0wioiw014 小时前
Flutter基础(前端教程①③-单例)
前端·flutter
iFlyCai14 小时前
Flutter状态管理篇之ChangeNotifier基础篇(一)
开发语言·flutter·dart
勤劳打代码19 小时前
配置无忧 —— Flutter × macOS 实战指南
flutter·macos·google
peter676820 小时前
flutter项目调试问题小结
flutter
给钱,谢谢!1 天前
Flutter权限管理终极指南:实现优雅的Android 48小时授权策略
android·flutter
YueYaTech2 天前
【Flutter 必备插件】国际化 Flutter Intl、flutter_localizations
flutter
Cao_Shixin攻城狮2 天前
Flutter运行Android项目时显示java版本不兼容(Unsupported class file major version 65)的处理
android·java·flutter