代码之家  ›  专栏  ›  技术社区  ›  Dinesh Kumar M

flutter中的共享依赖项无法正常工作。数据未持久化

  •  0
  • Dinesh Kumar M  · 技术社区  · 2 年前

    我在这里提供了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();
      }
    }
    

    所以我想在这个主页屏幕上显示支出项目的内容,它确实这样做了。但当我关闭应用程序并再次打开它时,所有数据都不见了。我使用过共享引用,但它似乎仍然不起作用。

    0 回复  |  直到 2 年前