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

如何用GetX管理页面并自定义API请求触发时机?

用GetX改造Flutter页面API请求逻辑,解决重复请求问题

原来在initState中初始化API请求和定时任务,每次进入页面都会重复创建定时器、发送请求。现在通过GetX实现以下需求:

  • 应用首次启动时按需触发请求
  • 自定义kriptoGetir和haberGetir的调用间隔
  • 避免页面重复进入时重复创建定时任务

1. 创建GetX控制器类

新建控制器类,把状态管理、API请求、定时逻辑统一移到这里,利用GetX的生命周期和可观察状态替代原有的setState:

import 'package:get/get.dart';
import 'package:http/http.dart' as http;
import 'package:xml2json/xml2json.dart';
import 'dart:convert';
import 'dart:async';

class KriptoHaberController extends GetxController {
  // 可观察列表,状态变化自动通知UI更新
  final RxList<KriptoModel> kriptoList = <KriptoModel>[].obs;
  final RxList<Haber> haberList = <Haber>[].obs;
  final RxList<List<double>> sparklineList = <List<double>>[].obs;

  // 定时器实例,用于页面销毁时取消
  Timer? _kriptoTimer;
  Timer? _haberTimer;

  // 替换为你的实际API地址
  final String url = "你的加密货币API地址";
  final String haberUrl = "你的新闻API地址";

  @override
  void onInit() {
    super.onInit();
    // 首次启动触发初始请求
    _loadInitialData();
    // 设置定时任务
    _setupTimers();
  }

  @override
  void onClose() {
    // 页面销毁时取消定时器,防止内存泄漏
    _kriptoTimer?.cancel();
    _haberTimer?.cancel();
    super.onClose();
  }

  // 加载初始数据
  void _loadInitialData() async {
    await kriptoGetir();
    await haberGetir();
  }

  // 配置定时任务,自定义调用间隔
  void _setupTimers() {
    // 加密货币每45秒请求一次
    _kriptoTimer = Timer.periodic(const Duration(seconds: 45), (_) => kriptoGetir());
    // 新闻每260秒请求一次
    _haberTimer = Timer.periodic(const Duration(seconds: 260), (_) => haberGetir());
  }

  // 重构后的加密货币API请求
  Future<List<KriptoModel>> kriptoGetir() async {
    kriptoList.clear();
    sparklineList.clear();
    final response = await http.get(Uri.parse(url));
    if (response.statusCode == 200) {
      final List<dynamic> jsonRes = json.decode(response.body);
      for (var item in jsonRes) {
        if (item != null) {
          final kripto = KriptoModel.fromJson(item);
          kriptoList.add(kripto);
          sparklineList.add(item['sparkline_in_7d']['price'].cast<double>());
        }
      }
      print('加密货币请求发送成功');
      return kriptoList.toList();
    } else {
      throw Exception('加密货币请求失败');
    }
  }

  // 重构后的新闻API请求
  Future<List<Haber>> haberGetir() async {
    haberList.clear();
    final Xml2Json xml2json = Xml2Json();
    final res = await http.get(Uri.parse(haberUrl));
    if (res.statusCode == 200) {
      xml2json.parse(res.body);
      final jsonString = xml2json.toParker();
      final jsonRes = jsonDecode(jsonString);
      final List jsonLs = jsonRes['haberler']['haber'] as List;
      haberList.assignAll(jsonLs.map((e) => Haber.fromJson(e)).toList());
      print('新闻请求发送成功');
      return haberList.toList();
    } else {
      throw Exception('新闻请求失败');
    }
  }
}

2. 修改页面代码,接入GetX控制器

将原StatefulWidget改为StatelessWidget(GetX推荐无状态组件),通过Obx监听状态变化:

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'your_controller_path.dart'; // 替换为你的控制器文件路径

class KriptoHaberPage extends StatelessWidget {
  // 初始化控制器,GetX自动管理其生命周期
  final KriptoHaberController controller = Get.put(KriptoHaberController());

  KriptoHaberPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('加密货币与新闻')),
      body: Column(
        children: [
          // 加密货币列表区域
          Expanded(
            child: Obx(() {
              if (controller.kriptoList.isEmpty) {
                return const Center(child: CircularProgressIndicator());
              }
              return ListView.builder(
                itemCount: controller.kriptoList.length,
                itemBuilder: (context, index) {
                  final kripto = controller.kriptoList[index];
                  return ListTile(title: Text(kripto.name)); // 替换为你的自定义UI
                },
              );
            }),
          ),
          // 新闻列表区域
          Expanded(
            child: Obx(() {
              if (controller.haberList.isEmpty) {
                return const Center(child: CircularProgressIndicator());
              }
              return ListView.builder(
                itemCount: controller.haberList.length,
                itemBuilder: (context, index) {
                  final haber = controller.haberList[index];
                  return ListTile(title: Text(haber.title)); // 替换为你的自定义UI
                },
              );
            }),
          ),
        ],
      ),
    );
  }
}

关键改造说明

  • 状态响应:用RxList替代普通列表,状态变化自动触发UI更新,彻底抛弃setState
  • 定时任务唯一性:定时器在控制器onInit中创建,仅初始化一次,避免页面重复进入时重复创建
  • 内存泄漏防护:在控制器onClose中取消定时器,确保页面销毁时释放资源
  • 按需触发:若需手动触发请求(如下拉刷新),直接调用controller.kriptoGetir()即可

内容的提问来源于stack exchange,提问作者Yusuf Barulay

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 20:00:58