我在这里提供了3个文件和我的main.dart文件。所以问题是,即使在我重新运行应用程序或重新启动应用程序时,我也希望将数据保存在HomePageScreen.dart上。
这是我的主.dart()文件
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/scheduler.dart';
import 'package:dinesh_s_application42/theme/theme_helper.dart';
import 'package:dinesh_s_application42/routes/app_routes.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:dinesh_s_application42/presentation/homepage_screen/functionality/expense/expense_bloc.dart';
import 'package:dinesh_s_application42/presentation/homepage_screen/functionality/income/income_bloc.dart';
import 'package:dinesh_s_application42/presentation/settings_screen/ProfileBloc.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final prefs = await SharedPreferences.getInstance();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
///Please update theme as per your need if required.
ThemeHelper().changeTheme('primary');
runApp(MyApp(prefs));
}
class MyApp extends StatelessWidget {
final SharedPreferences prefs; // Declare the SharedPreferences instance
MyApp(this.prefs);
@override
Widget build(BuildContext context) {
return MultiBlocProvider( // Use MultiBlocProvider to provide multiple blocs if needed
providers: [
BlocProvider<ExpenseBloc>(create: (context) => ExpenseBloc(prefs)), // Provide your ExpenseBloc
BlocProvider<IncomeBloc>(create: (context) => IncomeBloc()),
BlocProvider<ProfileBloc>(create: (context) => ProfileBloc()),
],
child: MaterialApp(
theme: theme,
title: 'dinesh_s_application42',
debugShowCheckedModeBanner: false,
initialRoute: AppRoutes.startPageScreen,
routes: AppRoutes.routes,)
);
}
}
这是我的expense_bloc.dart文件
import 'package:bloc/bloc.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import 'package:dinesh_s_application42/presentation/homepage_screen/functionality/expense/expense.dart';
class ExpenseBloc extends Bloc<ExpenseEvent, List<Expense>> {
final SharedPreferences _prefs;
ExpenseBloc(this._prefs) : super([]);
@override
Stream<List<Expense>> mapEventToState(ExpenseEvent event) async* {
if (event is AddExpenseEvent) {
final updatedExpenses = List.of(state)..add(event.expense);
await saveExpenses(updatedExpenses);
yield updatedExpenses;
} else if (event is RemoveExpenseEvent) {
final updatedExpenses = List.of(state)..remove(event.expense);
await saveExpenses(updatedExpenses);
yield updatedExpenses;
} else if (event is LoadExpensesEvent) {
yield event.expenses;
}
}
Future<void> saveExpenses(List<Expense> expenses) async {
final jsonData = expenses.map((expense) => expense.toJson()).toList();
await _prefs.setString('expenses', jsonEncode(jsonData));
}
Future<void> loadExpenses() async {
final jsonData = _prefs.getString('expenses');
if (jsonData != null) {
final List<dynamic> jsonList = jsonDecode(jsonData);
final expenses = jsonList.map((jsonExpense) => Expense.fromJson(jsonExpense)).toList();
add(LoadExpensesEvent(expenses));
}
}
}
abstract class ExpenseEvent {}
class AddExpenseEvent extends ExpenseEvent {
final Expense expense;
AddExpenseEvent(this.expense);
}
class RemoveExpenseEvent extends ExpenseEvent {
final Expense expense;
RemoveExpenseEvent(this.expense);
}
class LoadExpensesEvent extends ExpenseEvent {
final List<Expense> expenses;
LoadExpensesEvent(this.expenses);
}
这是expense.dart文件
import 'package:uuid/uuid.dart';
import "package:flutter/material.dart";
import 'package:intl/intl.dart';
final formatter = DateFormat.yMd();
const uuid = Uuid();
enum Category { Essentials, Transportation, Housing, Healthcare, Education, Personal_Care, Entertainment, Communication, Savings, Investments, Dept_payments, Miscellaneous, Travel_Entertainment, Emergency_Fund}
const categoryIcons = {
Category.Essentials: Icons.add_business_rounded,
Category.Transportation: Icons.directions_car_filled,
Category.Housing: Icons.add_home_work_sharp ,
Category.Healthcare: Icons.health_and_safety_rounded,
Category.Education: Icons.school_rounded,
Category.Personal_Care: Icons.attribution_outlined,
Category.Entertainment: Icons.add_home_work_sharp ,
Category.Communication: Icons.face_retouching_natural_sharp,
Category.Savings: Icons.area_chart_sharp,
Category.Investments: Icons.attach_money_outlined,
Category.Dept_payments: Icons.feed_rounded ,
Category.Miscellaneous: Icons.fitness_center_sharp,
Category.Travel_Entertainment: Icons.fire_truck_rounded ,
Category.Emergency_Fund: Icons.fireplace_outlined,
};
class Expense {
Expense({
required this.title,
required this.amount,
required this.date,
required this.category,
}) :
id = uuid.v4();
final String id;
final String title;
final double amount;
final DateTime date;
final Category category;
Map<String, dynamic> toJson() {
return {
'title': title,
'amount': amount,
'date': date.toIso8601String(),
'category': category.index
};
}
factory Expense.fromJson(Map<String, dynamic> json) {
return Expense(
title: json['title'],
amount: json['amount'],
date: DateTime.parse(json['date']),
category: Category.values[json['category']],
);
}
String get formattedDate {
return formatter.format(date);
}
}
class ExpenseBucket {
const ExpenseBucket({
required this.category,
required this.expenses,
});
ExpenseBucket.forCategory(List<Expense> allExpenses, this.category)
: expenses = allExpenses
.where((expense) => expense.category == category)
.toList();
final Category category;
final List<Expense> expenses;
double get totalExpenses {
double sum = 0;
for (final expense in expenses) {
sum = sum + expense.amount;
}
return sum;
}
}
这是我的HomePageScreen.dart文件:
import '../menubar_draweritem/menubar_draweritem.dart';
import 'package:dinesh_s_application42/core/app_export.dart';
import 'package:dinesh_s_application42/widgets/app_bar/appbar_image.dart';
import 'package:dinesh_s_application42/widgets/app_bar/appbar_image_1.dart';
import 'package:dinesh_s_application42/widgets/app_bar/custom_app_bar.dart';
import 'package:dinesh_s_application42/widgets/custom_elevated_button.dart';
import 'package:flutter/material.dart';
import 'package:dinesh_s_application42/presentation/homepage_screen/functionality/expense/expense.dart';
import 'package:dinesh_s_application42/presentation/homepage_screen/functionality/expense/new_expense.dart';
import 'package:dinesh_s_application42/presentation/homepage_screen/functionality/expense/expense_bloc.dart';
import 'package:dinesh_s_application42/presentation/homepage_screen/functionality/income/income_bloc.dart';
import 'package:dinesh_s_application42/presentation/homepage_screen/functionality/income/incomes_list.dart';
import 'package:dinesh_s_application42/presentation/homepage_screen/functionality/expense/expenses_list.dart';
import 'package:dinesh_s_application42/presentation/homepage_screen/functionality/income/income.dart';
import 'package:dinesh_s_application42/presentation/homepage_screen/functionality/income/new_income.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
// ignore_for_file: must_be_immutable
class _ExpensesState extends State<HomepageScreen> {
final List<Expense> _registeredExpenses = [ ];
final List<Income> _registeredIncomes = [ ];
Map<String, double> _categoryExpenses = {
"Essentials": 0.0,
"Category2": 0.0, // Initialize for all 14 categories
// ...
};
double calculateTotalIncome() {
final List<Income> incomes = context.watch<IncomeBloc>().state;
double totalIncome = incomes.fold(0, (sum, income) => sum + income.amount);
return totalIncome;
}
double calculateTotalExpense() {
final List<Expense> expenses = context.watch<ExpenseBloc>().state;
double totalExpense = expenses.fold(0, (sum, expense) => sum + expense.amount);
return totalExpense;
}
double calculateTotalAmount() {
double totalIncome = calculateTotalIncome();
double totalExpense = calculateTotalExpense();
double totalAmount = totalIncome - totalExpense;
return totalAmount;
}
void _openAddExpenseOverlay() {
showModalBottomSheet(
context: context,
builder: (ctx) => NewExpense(onAddExpense: _addExpense),
);
}
void _addExpense(Expense expense) {
setState(() {
_registeredExpenses.add(expense);
String categoryKey = expense.category.toString();
_categoryExpenses[categoryKey] = (_categoryExpenses[categoryKey] ?? 0) + expense.amount;
});
}
void _openAddIncomeOverlay() {
showModalBottomSheet(
context: context,
builder: (ctx) => NewIncome(onAddIncome: _addIncome),
);
}
void _addIncome(Income income) {
setState(() {
_registeredIncomes.add(income);
});
}
GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
mediaQueryData = MediaQuery.of(context);
return SafeArea(
child: Scaffold(
extendBody: true,
extendBodyBehindAppBar: true,
key: _scaffoldKey,
drawer: MenubarDraweritem(),
body: Container(
width: mediaQueryData.size.width,
height: mediaQueryData.size.height,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(ImageConstant.imgHomepage),
fit: BoxFit.cover)),
child: SizedBox(
width: double.maxFinite,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
padding: getPadding(top: 29, bottom: 29),
decoration: AppDecoration.fillGray.copyWith(
borderRadius:
BorderRadiusStyle.customBorderBL40),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
CustomAppBar(
height: getVerticalSize(42),
leadingWidth: getHorizontalSize(60),
leading: AppbarImage(
svgPath: ImageConstant.imgMenu,
margin: getMargin(
left: 20, top: 8, bottom: 9),
onTap: () {
navigatetomenu(context);
}),
actions: [
AppbarImage1(
svgPath:
ImageConstant.imgSettings,
margin: getMargin(
left: 25, right: 25),
onTap: () {
navigatetosettings(context);
})
]),
SizedBox(height: getVerticalSize(15)),
Align(
alignment: Alignment.center,
child: SizedBox(
height: getVerticalSize(77),
width: getHorizontalSize(300),
child: Stack(
alignment: Alignment.bottomLeft,
children: [
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: getPadding(top: 10),
child: Text("â¹${calculateTotalAmount().toStringAsFixed(2)}",
style: CustomTextStyles
.displayMediumJost))),
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: getPadding(left: 1),
child: Text("Total balance",
style: theme
.textTheme
.headlineSmall)))
]))),
CustomElevatedButton(
height: getVerticalSize(49),
onTap: _openAddExpenseOverlay,
text: "Click to add Expense",
margin: getMargin(
left: 40, top: 16, right: 73),
leftIcon: Container(
margin: getMargin(right: 29),
child: CustomImageView(
svgPath:
ImageConstant.imgPlus)),
buttonStyle:
CustomButtonStyles.outlineBlack,
buttonTextStyle: CustomTextStyles
.titleLargeJostOnPrimaryContainer),
CustomElevatedButton(
height: getVerticalSize(49),
text: "Click to add Income",
onTap: _openAddIncomeOverlay,
margin: getMargin(
left: 40,
top: 40,
right: 73,
bottom: 4),
leftIcon: Container(
margin: getMargin(right: 21),
child: CustomImageView(
svgPath:
ImageConstant.imgPlus)),
buttonStyle:
CustomButtonStyles.outlineBlack,
buttonTextStyle: CustomTextStyles
.titleLargeJostOnPrimaryContainer)
])),
Padding(
padding: getPadding(top: 11, bottom: 11),
child: Text("Latest Transactions",
style: CustomTextStyles.headlineSmallSemiBold)),
Padding(
padding: getPadding(top: 1, bottom: 1),
child: Text("Expenses",
style: CustomTextStyles.titleSmallInter)),
BlocBuilder<ExpenseBloc, List<Expense>>(
builder: (context, expenses) {
Widget mainContent = const Center(
child: Text('No expenses found. Start adding Some!'),
);
if (expenses.isNotEmpty) {
mainContent = ExpensesList(
expenses: expenses,
onRemoveExpense: (expense) {
context
.read<ExpenseBloc>()
.add(RemoveExpenseEvent(expense));
},
);
}
return Expanded(
child: mainContent,
);
},
),
Padding(
padding: getPadding(top: 1, bottom: 1),
child: Text("Incomes",
style: CustomTextStyles.titleSmallInter)),
BlocBuilder<IncomeBloc, List<Income>>(
builder: (context, incomes) {
Widget mainContent = const Center(
child: Text('No incomes found. Start adding Some!'),
);
if (incomes.isNotEmpty) {
mainContent = IncomesList(
incomes: incomes,
onRemoveIncome: (income) {
context
.read<IncomeBloc>()
.add(RemoveIncomeEvent(income));
},
);
}
return Expanded(
child: mainContent,
);
},
),
])))));
}
/// Opens the drawer of the current scaffold using the [_scaffoldKey] instance
/// variable.
navigatetomenu(BuildContext context) {
_scaffoldKey.currentState?.openDrawer();
}
navigatetosettings(BuildContext context) {
Navigator.popAndPushNamed(context, AppRoutes.settingsScreen);
}
}
class HomepageScreen extends StatefulWidget {
const HomepageScreen({Key? key})
: super(
key: key,
);
@override
State<HomepageScreen> createState() {
return _ExpensesState();
}
}
所以我想在这个主页屏幕上显示支出项目的内容,它确实这样做了。但当我关闭应用程序并再次打开它时,所有数据都不见了。我使用过共享引用,但它似乎仍然不起作用。