我正在用 flutter 开发一个移动应用程序。我的应用程序应该仅在有互联网连接时运行,因为它使用 Firebase 作为数据库。
我在主函数中初始化 Firebase。但是,当用户在没有互联网连接的情况下启动时,我会显示一个对话框,当用户连接到互联网时,我会启动导航到下一个屏幕的相同过程和过程。
但是,导航在正常流程中顺利进行,但在用户到达启动后连接到互联网的其他流程中。即使所有函数调用都正确执行,导航也没有发生。我已经检查过日志记录。
我当前的启动屏幕及其视图模型的实现如下。我已经尝试了所有记录但无法锻炼。谁能告诉我我做错了什么以及需要修复什么?
启动画面:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../View Models/Splash View Model.dart';
import 'Signup Screen.dart'; // Replace with actual path to signup screen
class SplashScreen extends StatelessWidget {
const SplashScreen({super.key});
@override
Widget build(BuildContext context) {
final viewModel = Provider.of<SplashViewModel>(context, listen: false);
WidgetsBinding.instance.addPostFrameCallback((_) {
_initializeApp(context, viewModel ,false);
});
return Scaffold(
body: Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/drawables_png/splash_bg.png'),
fit: BoxFit.cover,
),
),
child: Column(
children: [
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/drawables_png/splash_ic.png',
width: 150,
height: 150,
),
const SizedBox(height: 20),
const Text(
'EASY FOOD JOURNAL',
style: TextStyle(
fontFamily: 'Viga',
fontSize: 24,
color: Colors.white,
),
),
const SizedBox(height: 10),
const Text(
'Effortless Tracking for Delicious Living!',
style: TextStyle(
fontFamily: 'Outfit',
fontSize: 16,
color: Colors.white,
),
),
const SizedBox(height: 40),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 60.0, vertical: 30),
child: Consumer<SplashViewModel>(
builder: (context, viewModel, child) {
return LinearProgressIndicator(
value: viewModel.progress,
backgroundColor: const Color(0xff29ffffff),
valueColor: const AlwaysStoppedAnimation<Color>(Colors.white),
);
},
),
),
],
),
),
);
}
void _initializeApp(BuildContext context, SplashViewModel viewModel , bool callFirebase) async {
print("finally here011");
bool connected = await viewModel.checkInternetConnection();
if (connected) {
bool firebaseInitialized = await viewModel.initializeFirebase(callFirebase);
if (firebaseInitialized) {
print("finally here211");
await viewModel.startProgress();
print("finally here311");
_navigateBasedOnLoginStatus(context, viewModel);
print("finally here411");
} else {
_showNoConnectionDialog(context, viewModel);
}
} else {
_showNoConnectionDialog(context, viewModel);
}
}
void _showNoConnectionDialog(BuildContext context, SplashViewModel viewModel) {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: const Text("No Internet Connection"),
content: const Text("Please connect to the internet to continue."),
actions: [
TextButton(
child: const Text("Retry"),
onPressed: () {
Navigator.of(context).pop();
_initializeApp(context, viewModel , true); // Retry the initialization
},
),
],
);
},
);
}
void _navigateBasedOnLoginStatus(BuildContext context, SplashViewModel viewModel) async {
bool isLoggedIn = await viewModel.isUserLoggedIn();
// Use addPostFrameCallback to ensure context is valid for navigation
WidgetsBinding.instance.addPostFrameCallback((_) {
if (isLoggedIn) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (_) => const SignupScreen()), // Change to home screen if logged in
);
} else {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (_) => const SignupScreen()), // Change to signup screen if not logged in
);
}
});
}
}
查看模型:
import 'dart:async';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/cupertino.dart';
import '../Utils/SharedPrefs.dart';
class SplashViewModel with ChangeNotifier {
double _progress = 0.0;
Timer? _timer;
double get progress => _progress;
/// Initializes Firebase separately to control when it is called.
Future<bool> initializeFirebase( bool callFirebase) async {
try {
if(callFirebase){
if (Firebase.apps.isEmpty) {
await Firebase.initializeApp();
}
}
return true;
} catch (e) {
print("Firebase initialization failed: $e");
return false;
}
}
/// Starts the progress bar animation.
Future<void> startProgress() async {
_resetProgress();
// Start progress bar animation
_timer = Timer.periodic(const Duration(milliseconds: 50), (timer) {
if (_progress < 1.0) {
_progress += 0.02; // Increment progress by 2%
notifyListeners();
} else {
timer.cancel();
}
});
// Complete progress after 2 seconds for animation consistency
if (Firebase.apps.length != 0) {
await Future.delayed(const Duration(seconds: 2));
_progress = 1.0;
notifyListeners();
_timer?.cancel();
}
}
void _resetProgress() {
_progress = 0.0;
notifyListeners();
_timer?.cancel();
}
Future<bool> checkInternetConnection() async {
var connectivityResult = await Connectivity().checkConnectivity();
return connectivityResult != ConnectivityResult.none;
}
Future<bool> isUserLoggedIn() async {
User? currentUser = FirebaseAuth.instance.currentUser;
if (currentUser == null) return false;
bool onboardingComplete = await SharedPreferencesUtil.getValue<bool>('onboarding_complete', false);
return onboardingComplete;
}
@override
void dispose() {
_timer?.cancel();
super.dispose();
}
}
问题似乎出在 checkInternetConnection 上,它仅被调用一次,因此应用程序不会对连接更改做出反应。