【问题标题】:In Flutter CupertinoTabBar + StreamBuilder code is running but widgets are not rebuilt在 Flutter CupertinoTabBar + StreamBuilder 代码正在运行但小部件未重建
【发布时间】:2021-08-21 16:47:19
【问题描述】:

我有一个 2 选项卡屏幕,我想根据用户的交互动态重建内容。在第一个选项卡上,我尝试通过使用模型和提供程序设置当前步骤名称来处理多个状态。对于按下按钮后的第二个屏幕,我在控制台中收到打印消息,但 CupertinoTabView 的内容保持不变。

最小可运行代码sn-p:

main.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import 'package:my_app/screens/login.dart';
import 'package:my_app/screens/tab_bar.dart';
import 'package:my_app/models/model.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations(
      [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);

  return runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (context) => Model(),
        ),
      ],
      child: CupertinoApp(
        theme: const CupertinoThemeData(
          brightness: Brightness.light,
          scaffoldBackgroundColor: CupertinoColors.white,
        ),
        initialRoute: '/',
        routes: {
          '/': (context) => LoginScreen(),
          '/tab_bar': (context) => TabBarScreen(),
          //'/add_item': (context) => AddItemScreen(),
        },
      ),
    );
  }
}

登录.dart

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

import 'package:my_app/models/model.dart';

class LoginScreen extends StatelessWidget {
  final model = Model();

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text('app',),
      ),
      child: Container(
        alignment: FractionalOffset.center,
        child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                child: Text('next'),
                onPressed: (){
                  model.setStep('step1');
                  Navigator.pushNamed(context, '/tab_bar');
                },
                style: ElevatedButton.styleFrom(
                    primary: CupertinoColors.white,
                    side: BorderSide(color: Colors.blue, width: 2.0)
                ),
              ),
            ]
        ),
      ),
    );
  }
}

tab_bar.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:my_app/models/model.dart';

class TabBarScreen extends StatefulWidget {
  @override
  State createState() => TabBarScreenState();
}

class TabBarScreenState extends State<TabBarScreen> {
  final model = Model();

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

  @override
  Widget build(BuildContext context) {
    print(model.getStep);
    return Consumer<Model>(
      builder: (context, model, _) => CupertinoTabScaffold(
        tabBar: CupertinoTabBar(
          backgroundColor: CupertinoColors.white,
          inactiveColor: Colors.blue,
          activeColor: Colors.blueAccent,
          border: const Border(
            top: BorderSide(
              color: CupertinoColors.activeBlue,
              width: 2.0,
            ),
          ),
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.favorite_outline_outlined),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.more_vert_sharp),
            ),
          ],
        ),
        tabBuilder: (context, index) {
          late final CupertinoTabView returnValue;
          switch (index) {
            case 0:
              if (model.getStep == 'step1') {
                print('step1');
                returnValue = CupertinoTabView(builder: (context) {
                  return CupertinoPageScaffold(
                    child: SafeArea(
                      child: GestureDetector(
                        onTap: (){  },
                        child: Column(
                          children: <Widget>[
                            Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: <Widget>[
                                Container(
                                  margin: const EdgeInsets.only(bottom: 15.0),
                                  child: FloatingActionButton(
                                    onPressed: () { model.setStep('step2'); setState(() {

                                    }); },
                                    tooltip: 'step2',
                                    child: Icon(Icons.add),
                                    backgroundColor: CupertinoColors.white,
                                    foregroundColor: CupertinoColors.black,
                                  ),
                                ),
                              ],
                            ),
                          ],
                        ),
                      ),
                    ),
                  );
                });
              }
              else if (model.getStep == 'step2') {
                print('step2');
                returnValue = CupertinoTabView(builder: (context) {
                  return CupertinoPageScaffold(
                    child: SafeArea(
                      child: Column(
                        children: <Widget> [
                          Text('step2'),
                        ],
                      ),
                    ),
                  );
                });
              }
              else {
                returnValue = CupertinoTabView(builder: (context) {
                  return Container();
                });
              }
              break;
            case 1:
              returnValue = CupertinoTabView(builder: (context) {
                return CupertinoPageScaffold(
                  child: Text("Tab2"),
                );
              });
              break;
          }
          return returnValue;
        },
      ),
    );
  }
}

model.dart

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

class Model extends ChangeNotifier {
  static String currentStep = 'login';
  // login
  // step1                      - step1
  // step2                      - step2


  String get getStep {
    return currentStep;
  }

  void setStep(String step) {
    currentStep = step;
    notifyListeners();
  }
}

我希望在按下步骤 1 中的按钮以显示步骤 2 内容时重建选项卡。在控制台中,按下时我可以看到“step2”的打印,但实际选项卡保持不变。 感谢您的帮助

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    由于没有人回答,我自己想通了。 解决方法是像这样使用 Navigator:

    onPressed: () {
      Navigator.of(context).push(
        CupertinoPageRoute<void>(
          builder: (BuildContext context) {
            return CupertinoPageScaffold(
              navigationBar: CupertinoNavigationBar(
                middle: Text('Page 2 of tab'),
              ),
              child: Center(
                child: CupertinoButton(
                  child: const Text('Back'),
                  onPressed: () { Navigator.of(context).pop(); },
                ),
              ),
            );
          },
        ),
      );
    },
    

    因此您不需要“else if”条件。

    【讨论】:

      猜你喜欢
      • 2020-11-09
      • 2022-01-05
      • 2021-11-11
      • 1970-01-01
      • 1970-01-01
      • 2021-10-27
      • 2021-06-11
      • 1970-01-01
      • 2019-08-24
      相关资源
      最近更新 更多