Flutter中是使用RxDart代替Stateful

2022-07-28 14:31:26 浏览数 (1)

本文先列举一个最简单的例子,以后遇到比较典型的例子再分享:

先看一个常规的写法,首页上面有两个tab的例子:

代码语言:javascript复制
class MainTabPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return MainTabPageState();
  }
}

class MainTabPageState extends State<MainTabPage> {
  int _currentIndex = 0;
  final pageList = [
    TabInfo(Home(), "首页", Icons.home),
    TabInfo(Text(""), "我的", Icons.person)
  ];

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
        child: Scaffold(
            backgroundColor: Color(0xFFF5F5F5),
            bottomNavigationBar: BottomNavigationBar(
              items: pageList.map((info) => BottomNavigationBarItem(
                  title: Text(info.title), icon: Icon(info.icon))).toList(),
              currentIndex: _currentIndex,
              type: BottomNavigationBarType.fixed,
              onTap: (int index) {
                setState(() {
                  _currentIndex = index;
                });
              },
            ),
            body: pageList[_currentIndex].widget),
        length: pageList.length);
  }
}

其中_currentIndex记录了当前tab的索引,onTap中调用setState来更新视图,没毛病。

现在使用RxDart改写这个页面。

代码语言:javascript复制
class MainTabPage extends StatelessWidget {
  final pageList = [
    TabInfo(Home(), "首页", Icons.home),
    TabInfo(Text(""), "我的", Icons.person)
  ];
  final changeTabStream = PublishSubject<int>();
  @override
  Widget build(BuildContext context) => DefaultTabController(
        child: StreamBuilder<int>(
            initialData: 0,
            stream: changeTabStream,
            builder: (context, snapshot) => Scaffold(
                  backgroundColor: Color(0xFFF5F5F5),
                  bottomNavigationBar: BottomNavigationBar(
                    items: pageList
                        .map((info) => BottomNavigationBarItem(
                            title: Text(info.title), icon: Icon(info.icon)))
                        .toList(),
                    currentIndex: snapshot.data,
                    type: BottomNavigationBarType.fixed,
                    onTap: changeTabStream.add,
                  ),
                  body: pageList[snapshot.data].widget,
                )),
        length: pageList.length,
      );
}

我们看到不需要再定义_currentIndex,然后我们只需要继承StatelessWidget 。取而代之的是我们定义了changeTabStream,这是一个PublishSubject用来发送事件,Flutter官方提供了StreamBuilder来响应这种事件流,很贴心。

这个例子还看不出Rx的明显优势,但是大家可以思考一下,Rx的好处在哪里。

0 人点赞