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

使用Getx重构Flutter单位切换Toggle Button(替代setState)

Flutter Toggle Button 切换Getx状态管理失效解决方案

我正在开发一款用于切换单位系统的Toggle Button,需要采用Getx进行状态管理。目前已有通过setState实现的可用代码,但尝试将状态变量改为RxInt并添加.obs、用Obx包裹需更新组件后,功能无法正常运行。使用的是flutter_toggle_tab包。

原setState实现代码

import 'package:flutter/material.dart';
import 'package:flutter_toggle_tab/flutter_toggle_tab.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({this.title});

  final String? title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  var _tabTextIndexSelected = 0;
  final _listTextTabToggle = ["km / m", "m / ft"];

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: SingleChildScrollView(
          child: Column(
            children:[
              FlutterToggleTab(
                selectedIndex: _tabTextIndexSelected,
                selectedBackgroundColors: const [
                  Colors.blue,
                  Colors.blueAccent
                ],
                selectedTextStyle: const TextStyle(
                    color: Colors.white),
                unSelectedTextStyle: const TextStyle(),
                labels: _listTextTabToggle,
                selectedLabelIndex: (index) {
                  setState(() {
                    _tabTextIndexSelected = index;
                  });
                },
                isScroll: false,
              ),
              Text(
                "Index selected : $_tabTextIndexSelected",
              ),
            ],
          ),
        ),
      ),
    );
  }
}

尝试的Getx修改代码(功能失效)

RxInt _tabTextIndexSelected = 0.obs;
final _listTextTabToggle = ["km / m", "m / ft"];

@override
Widget build(BuildContext context) {
  return SafeArea(
    child: Scaffold(
      body: Column(
        children: [
          Obx(
            ()=> FlutterToggleTab(
              selectedIndex: _tabTextIndexSelected,
              selectedBackgroundColors: const [
                Colors.blue,
                Colors.blueAccent
              ],
              selectedTextStyle: const TextStyle(
                  color: Colors.white),
              unSelectedTextStyle: const TextStyle(),
              labels: _listTextTabToggle,
              selectedLabelIndex: (index) {
                _tabTextIndexSelected = index.obs;
              },
              isScroll: false,
            ),
          ),
          Obx(
            ()=>Text(
              "Index selected : $_tabTextIndexSelected",
            ),
          ),

错误原因分析

  1. 状态更新方式错误:在selectedLabelIndex回调中,直接将_tabTextIndexSelected重新赋值为index.obs,这会替换掉原来的RxInt实例,导致Obx监听的对象发生变化,无法触发UI更新。正确的做法是修改现有RxInt实例的.value属性。
  2. 参数类型不匹配:FlutterToggleTab的selectedIndex参数需要的是int类型,但代码中直接传入了RxInt对象,应该使用_tabTextIndexSelected.value获取其内部的int值。

正确的Getx实现代码

import 'package:flutter/material.dart';
import 'package:flutter_toggle_tab/flutter_toggle_tab.dart';
import 'package:get/get.dart'; // 导入Getx包

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget { // 改为StatelessWidget,用Getx管理状态
  const MyHomePage({this.title, Key? key}) : super(key: key);

  final String? title;
  final RxInt _tabTextIndexSelected = 0.obs;
  final _listTextTabToggle = ["km / m", "m / ft"];

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        body: SingleChildScrollView(
          child: Column(
            children: [
              Obx(
                () => FlutterToggleTab(
                  selectedIndex: _tabTextIndexSelected.value, // 使用.value获取int值
                  selectedBackgroundColors: const [
                    Colors.blue,
                    Colors.blueAccent
                  ],
                  selectedTextStyle: const TextStyle(color: Colors.white),
                  unSelectedTextStyle: const TextStyle(),
                  labels: _listTextTabToggle,
                  selectedLabelIndex: (index) {
                    _tabTextIndexSelected.value = index; // 修改.value更新状态
                  },
                  isScroll: false,
                ),
              ),
              Obx(
                () => Text(
                  "Index selected : ${_tabTextIndexSelected.value}", // 同样使用.value
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

关键修改点

  • 导入Getx包:import 'package:get/get.dart';
  • 状态更新:将_tabTextIndexSelected = index.obs改为_tabTextIndexSelected.value = index,保留原RxInt实例,确保Obx能监听到变化。
  • 参数传递:selectedIndex和Text中都使用.value获取RxInt的实际int值,匹配组件所需的参数类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:39:26