0

如果有人无法理解我的问题,请告知

我已经使用 Provider 包来处理身份验证流程。我正在做的是: Main.dart -> Auth 处理程序小部件(其中包含用于检查 onAuthChange 的流生成器​​) -> 页面处理程序(如果用户是新用户,它将带用户从那里进入登录屏幕,它被转移到登录使用推送替换的页面)登录后检查用户是否存在数据 -> 如果存在,则将其带到主屏幕 -> 主屏幕包含 3 个选项卡。在主页选项卡中有注销按钮,但是当我按下它时它不起作用。在这方面帮助我。

主要.dart

Provider<AuthBase>(
      create: (context)=>Auth(),
      child: MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'Rapport',
          theme: ThemeData(
            primaryColor: Color(0xFFE3F2FD),
            visualDensity: VisualDensity.adaptivePlatformDensity,
            pageTransitionsTheme: PageTransitionsTheme(
              builders: {
                TargetPlatform.android: CustomPageTransitionsBuilder(),
                TargetPlatform.iOS: CustomPageTransitionsBuilder(),
              },
            ),
          ),

          /*This is the routes table. Add all the route names used inside the app here
        Add the route name where the route is made as static const String, so as to you don't need to remember anything.
         */
          routes: {
            //the route name / stands for home / first route in the app.
            '/': (ctx) {
              return SplashScreen.navigate(
                name: 'assets/splash.flr',
                next: (context) {
                  print(isLogin.toString());
                  return AuthWidgetBuilder(dataExists: myData.length==0,isLogin: isLogin,builder: (context, userSnapshot,isLogin,dataExist) {
                    return Scaffold(
                      body: AuthWidget(userSnapshot: userSnapshot,dataExists: myData.length==0,isLogin: isLogin,),
                    );
                  });
                },
                startAnimation: 'Untitled',
                until: () => Future.delayed(Duration(seconds: 4)),
                backgroundColor: Colors.white,
              );
            },
            LoginScreen.loginRoute: (ctx) => LoginScreen(),
            CheckUser.checkRoute: (ctx) => CheckUser(),
            OnboardingScreen.onBoardRoute: (ctx) => OnboardingScreen(),
            StudentInfo.studentRoute: (ctx) => StudentInfo(),
            PersonalDetails.routeName:(ctx) => PersonalDetails(),
            ProfessionalDetails.routeName:(ctx) => ProfessionalDetails(),
            AddressDetails.routeName: (ctx) => AddressDetails(),
            TeacherHomeScreen.routeName:(ctx)=>TeacherHomeScreen(),
            TeacherVerification.routeName:(ctx)=>TeacherVerification(),
            StudentHomeScreen.routeName : (ctx)=>StudentHomeScreen(),
          },
        ),
    );

Auth_Widget_Builder

class AuthWidgetBuilder extends StatelessWidget {
  const AuthWidgetBuilder({Key key, @required this.builder,@required this.isLogin,@required this.dataExists}) : super(key: key);
  final Widget Function(BuildContext, AsyncSnapshot<User>,String,bool) builder;
  final String isLogin;
  final bool dataExists;


  @override
  Widget build(BuildContext context) {
    print('AuthWidgetBuilder rebuild');
    print(dataExists);
    final authService =
    Provider.of<AuthBase>(context, listen: false);
    return StreamBuilder<User>(
      stream: authService.onAuthStateChanged,
      builder: (context, snapshot) {
        print('StreamBuilder: ${snapshot.connectionState}');
        final User user = snapshot.data;
        if (user != null) {
          SharedPrefFunction().saveLoginPreference();
          return MultiProvider(
            providers: [
              Provider<User>.value(value: user),
            ],
            child: builder(context, snapshot,'true',dataExists),
          );
        }
        return builder(context, snapshot,isLogin,dataExists);
      },
    );
  }
}

Auth.Widget

class AuthWidget extends StatelessWidget {
  const AuthWidget({Key key, @required this.userSnapshot,this.dataExists,this.isLogin}) : super(key: key);
  final AsyncSnapshot<User> userSnapshot;
  final String isLogin;
  final bool dataExists;

  @override
  Widget build(BuildContext context) {
    if (userSnapshot.connectionState == ConnectionState.active) {
      if(isLogin == null){
        return OnboardingScreen();
      }
      else{
        return userSnapshot.hasData ? CheckUser(dataExist: dataExists,) : LoginScreen();
      }
    }
    return Scaffold(
      body: Center(
        child: CircularProgressIndicator(),
      ),
    );
  }
}

如果数据存在,则在 checkUser.dart 中

homePage(BuildContext context) {
    print('checkUser');
    if (dataExists) {
      return Scaffold(
        body: SafeArea(
          child: Container(
            child: Column(
              children: <Widget>[
                Text(
                  'Welcome',
                  style: kTextStyle,
                ),
                FlatButton.icon(
                  onPressed: () {
                    setState(() {
                      Navigator.of(context).pushReplacementNamed(
                        StudentHomeScreen.routeName,   //This line is changed by me. This code is not correct and needs to be changed.
                      );
                    });
                  },
                  icon: Icon(Icons.home),
                  label: Text('Home'),
                ),
              ],
            ),
          ),
        ),
      );
    } else {
      return getInfoPage();
    }
  }

Student_Home_Screen.dart

class _StudentHomeState extends State<StudentHomeScreen> {
  bool _isProfilePicSet = false;
  int _currentTabIndex = 1;
  var _tabs = [
    Center(
      child: Text('Search Tab'),
    ),
    HomeTab(),
    Center(
      child: Text('Profile Tab'),
    ),
  ];

  @override
  Widget build(BuildContext context) {
    var size = MediaQuery.of(context).size;
    return Scaffold(
      backgroundColor: Colors.white,
      body: _tabs[_currentTabIndex],
      bottomNavigationBar: BottomNavigationBar(
//        type: BottomNavigationBarType.shifting,
        backgroundColor: Colors.white,
//        fixedColor: Colors.black,
        iconSize: 24,
        selectedIconTheme: IconThemeData(
          color: themeColor,
          opacity: 1,
        ),
        unselectedIconTheme: IconThemeData(
          color: themeColor,
          opacity: 0.6,
        ),
        showUnselectedLabels: false,
        showSelectedLabels: true,
        elevation: 10,
        currentIndex: _currentTabIndex,
        onTap: (index) {
          setState(() {
            _currentTabIndex = index;
          });
        },
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.search),
            title: Text(
              'Search',
              style: subhead2.copyWith(color: themeColor),
            ),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            title: Text(
              'Home',
              style: subhead2.copyWith(color: themeColor),
            ),
          ),
          BottomNavigationBarItem(
            icon: CircleAvatar(
              backgroundImage: _isProfilePicSet
                  ? NetworkImage('set link here')
                  : AssetImage('assets/images/default.png'),
              maxRadius: 12,
            ),
            title: Text(
              'Profile',
              style: subhead2.copyWith(color: themeColor),
            ),
          ),
        ],
      ),
    );
  }
}

在 Hometab 中的 signOut 按钮功能

  Future<void> _signOut(BuildContext context) async {
    try {
      final auth = Provider.of<AuthBase>(context, listen: false);
      await auth.signOut();
    } catch (e) {
      print(e);
    }
  }
4

2 回答 2

0

这可能会对您有所帮助。我不确定,但这对我有用

登出功能

Future _signOut() async {
    try {
      return await auth.signOut();
    } catch (e) {
      print(e.toString());
      return null;
    }
  }

函数用法

IconButton(
  onPressed: () async {
    await _auth.signOut();
    MaterialPageRoute(
      builder: (context) => Login(),
    );
  },
  icon: Icon(Icons.exit_to_app),
),
于 2020-07-16T09:41:58.040 回答
-1

您需要将 AuthWidgetBuilder 作为顶级小部件(最好在 MaterialApp 之上),以便在登录/注销事件时重建整个小部件树。

你可以让 SplashScreen 成为一个孩子,并有一些条件逻辑来决定你是否应该展示它。

顺便说一句,如果您的初始屏幕不包含任何动画,则您根本不需要小部件,您可以在 iOS 上使用 Launch Screen 或在 Android 上使用同等功能(网上有关于此的教程)。通过@bizz84

于 2020-07-20T12:51:48.367 回答