身份验证加载时如何显示颤动的本机飞溅屏幕?

发布于 2025-02-11 19:17:10 字数 3339 浏览 1 评论 0原文

我想检查身份验证登录状态,如下所示,

  1. 身份验证加载=>显示Splash屏幕
  2. 身份验证=>主屏幕
  3. 未经身份验证=>

当前在屏幕上登录,我正在使用GetX State Management 我希望,在身份验证加载状态下,然后显示Flutter_Native_splash_screen,而不是由于渲染而导致的自定义飞溅屏幕,它在我自定义的Splash完成渲染之前显示了一个黑屏。

这是我的代码

void main() async {
  var widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
  FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
  internalInitialized();
  runApp(const MyApp());
  FlutterNativeSplash.remove();
}

void internalInitialized() {
  Get.lazyPut(() => AuthController(Get.put(AuthService())));
}


class MyApp extends GetWidget<AuthController> {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      debugShowCheckedModeBanner: false,
      home: Obx(() {
        if (controller.state is Authenticated) {
          return HomeScreen((controller.state as Authenticated).user!);
        } else if (controller.state is UnAuthenticated) {
          return SignInScreen();
        } else {
          return const SplashScreen();
        }
      }),
      theme: lightTheme(),
      darkTheme: darkTheme(),
      getPages: AppPages.list,
    );
  }
}

Splash屏幕


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

  @override
  Widget build(BuildContext context) {
    SizeConfig.init(context);
    return Container(
        color: AppTheme.primaryColor,
        width: SizeConfig.screenWidth,
        height: SizeConfig.screenHeight,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            SizedBox(
              width: getHeight(150),
              height: getHeight(150),
              child: Image.asset("assets/images/logo.png"),
            ),
            const CircularProgressIndicator(color: Colors.white)
          ],
        ));
  }
}

自定义启动屏幕仅显示徽标和处理栏。 auth Controller

class AuthController extends ConnectivityController {
  final AuthService authService;
  final authStateStream = const AuthenticationState().obs;

  AuthController(this.authService);

  AuthenticationState get state => authStateStream.value;

 
  @override
  void onInit() {
    getAuthenticatedUser();
    super.onInit();
  }

  Future<void> signIn(String username, String password) async {
    authStateStream.value = AuthenticationLoading();
    final customer = await authService.sign(username, password);
    if (customer == null) {
      authStateStream.value = UnAuthenticated();
    } else {
      authStateStream.value = Authenticated(customer: customer);
    }
  }

  void signOut() async {
    await authService.signOut("");
    authStateStream.value = UnAuthenticated();
  }

  void getAuthenticatedUser() async {
    authStateStream.value = AuthenticationLoading();
    Future.delayed(const Duration(seconds: 10));
    final customer = await authService.reSignIn();
    if (customer == null) {
      authStateStream.value = UnAuthenticated();
    } else {
      authStateStream.value = Authenticated(customer: customer);
    }
  }
}

请指导我,如何解决此问题。 谢谢你!

I would like to check the authentication login state as below

  1. authentication loading => show splash screen
  2. authenticated=> home screen
  3. unauthenticated=>sign in screen

Currently, I am using GetX state management
I wish, on authentication loading state then show flutter_native_splash_screen rather than my customize splash screen due to rendering, it shows a black screen before my customized splash finished render.

Here is my code

void main() async {
  var widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
  FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
  internalInitialized();
  runApp(const MyApp());
  FlutterNativeSplash.remove();
}

void internalInitialized() {
  Get.lazyPut(() => AuthController(Get.put(AuthService())));
}


class MyApp extends GetWidget<AuthController> {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      debugShowCheckedModeBanner: false,
      home: Obx(() {
        if (controller.state is Authenticated) {
          return HomeScreen((controller.state as Authenticated).user!);
        } else if (controller.state is UnAuthenticated) {
          return SignInScreen();
        } else {
          return const SplashScreen();
        }
      }),
      theme: lightTheme(),
      darkTheme: darkTheme(),
      getPages: AppPages.list,
    );
  }
}

Splash Screen


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

  @override
  Widget build(BuildContext context) {
    SizeConfig.init(context);
    return Container(
        color: AppTheme.primaryColor,
        width: SizeConfig.screenWidth,
        height: SizeConfig.screenHeight,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            SizedBox(
              width: getHeight(150),
              height: getHeight(150),
              child: Image.asset("assets/images/logo.png"),
            ),
            const CircularProgressIndicator(color: Colors.white)
          ],
        ));
  }
}

The customize splash screen just show Logo and processing bar.
Auth Controller

class AuthController extends ConnectivityController {
  final AuthService authService;
  final authStateStream = const AuthenticationState().obs;

  AuthController(this.authService);

  AuthenticationState get state => authStateStream.value;

 
  @override
  void onInit() {
    getAuthenticatedUser();
    super.onInit();
  }

  Future<void> signIn(String username, String password) async {
    authStateStream.value = AuthenticationLoading();
    final customer = await authService.sign(username, password);
    if (customer == null) {
      authStateStream.value = UnAuthenticated();
    } else {
      authStateStream.value = Authenticated(customer: customer);
    }
  }

  void signOut() async {
    await authService.signOut("");
    authStateStream.value = UnAuthenticated();
  }

  void getAuthenticatedUser() async {
    authStateStream.value = AuthenticationLoading();
    Future.delayed(const Duration(seconds: 10));
    final customer = await authService.reSignIn();
    if (customer == null) {
      authStateStream.value = UnAuthenticated();
    } else {
      authStateStream.value = Authenticated(customer: customer);
    }
  }
}

Please guide me, on how can I solve this issue.
Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦与时光遇 2025-02-18 19:17:10

飞溅屏幕旨在显示捆绑的扑动引擎初始化。
完成此操作并控制您的应用程序后,您可以手动创建一个看起来像Splash屏幕的页面。因此,材料应用程序的孩子可以是飞溅屏幕的外观。也许您甚至可以使其与Splash屏幕资产相同。

The splash screen is meant to be displayed whilst the bundled Flutter engine initialises.
Once that is done and your app is in control, you can manually create a page that looks like the splash screen. So the child of the material app can be a splash screen look alike. Maybe you could even make it identical to your splash screen asset.

謌踐踏愛綪 2025-02-18 19:17:10

尝试一下,

第一个初始化您的状态并使用有条件的操作员在身份验证的情况下, to splashscreen else else authenticate


void initState() {
    super.initState();   
    var _isAuth = user != null && user.isVerified;
    Navigator.push(
      context,
      MaterialPageRoute(
          builder: (context) => _isAuth ? SplashScreen() : Authenticate()),
    );
  }

Try this,

first initialize your state and use conditional operator if it is authenticated than go to splashScreen else authenticate .


void initState() {
    super.initState();   
    var _isAuth = user != null && user.isVerified;
    Navigator.push(
      context,
      MaterialPageRoute(
          builder: (context) => _isAuth ? SplashScreen() : Authenticate()),
    );
  }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文