2
\$\begingroup\$

I currently have the following code to build this widget:

enter image description here

                        MonthlyAnnualSection(
                          title: 'Tax Expense',
                          onValueChanged: (value) {
                            setState(() {
                              defaults.shouldDisplayTaxesExpensesMonthly =
                                  value == 'm';
                            });
                          },
                          children: [
                            Panel(
                              key: Key(
                                  'taxes${defaults.shouldDisplayTaxesExpensesMonthly ? 'Monthly' : 'Annual'}'),
                              title: '💸 Taxes',
                              isPercentage:
                                  defaults.shouldDisplayTaxesAsPercentage,
                              onIsPercentageChanged: (val) {
                                setState(() {
                                  defaults.shouldDisplayTaxesAsPercentage = val;
                                });
                              },
                              child: Column(
                                children: [
                                  SizedBox(height: 10),
                                  if (defaults.shouldDisplayTaxesAsPercentage)
                                    PercentageTextField(
                                      value: defaults
                                              .shouldDisplayTaxesExpensesMonthly
                                          ? defaults.taxesPercent
                                          : defaults.taxesPercent * 12,
                                      placeholder:
                                          'example: ${(defaults.shouldDisplayTaxesExpensesMonthly ? defaults.taxesPercent : defaults.taxesPercent * 12).toPercentage()}',
                                      onValueChanged: (val) {
                                        setState(() {
                                          defaults.taxesPercent = defaults
                                                  .shouldDisplayTaxesExpensesMonthly
                                              ? val
                                              : val / 12;
                                        });
                                      },
                                    ),
                                  if (!defaults.shouldDisplayTaxesAsPercentage)
                                    CurrencyTextField(
                                      value: defaults
                                              .shouldDisplayTaxesExpensesMonthly
                                          ? defaults.taxes
                                          : defaults.taxes * 12,
                                      placeholder:
                                          'example: ${(defaults.shouldDisplayTaxesExpensesMonthly ? defaults.taxes : defaults.taxes * 12).toCurrency()}',
                                      onValueChanged: (val) {
                                        setState(() {
                                          defaults.taxes = defaults
                                                  .shouldDisplayTaxesExpensesMonthly
                                              ? val
                                              : val / 12;
                                        });
                                      },
                                    ),
                                  SizedBox(height: 10),
                                ],
                              ),
                            ),
                          ],
                        ),

and this is the class where that defaults is coming from:


class Defaults {
  bool shouldDisplayTaxesExpensesMonthly;
  bool shouldDisplayTaxesAsPercentage;
  double taxes;
  double taxesPercent;
  bool shouldDisplayManagementExpensesMonthly;
  bool shouldDisplayManagementAsPercentage;
  double management;
  double managementPercent;
}

The problem as you can see, is that it takes a lot of ternary methods plus if I want to make a second similar widget below it (to use it for the management expenses, instead of tax) it takes a LOT of repeating.

Ideally I would love to just have something like this:

Section(
   title: 'Tax Expense',
   subtitle: '💸 Taxes',
   value: defaults.taxes,
   percent: defaults.taxesPercent,
   shouldDisplayMonthly: defaults.shouldDisplayTaxesExpensesMonthly,
   shouldDisplayAsPercentage: defaults.shouldDisplayTaxesAsPercentage,
),
Section(
   title: 'Management Expense',
   subtitle: '💸 Management',
   value: defaults.management,
   percent: defaults.managementPercent,
   shouldDisplayMonthly: defaults.shouldDisplayManagementExpensesMonthly,
   shouldDisplayAsPercentage: defaults.shouldDisplayManagementsAsPercentage,
),

And then it would be sorted... but apparently Dart doesn't support reflection, so I'm not sure how I could do that?

Any help is appreciated

\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

Yeah, that possible you can make class function or a separate stateless widget for code reusability.

class Section extends StatelessWidget {
  const Section(
      {super.key,
      required this.title,
      required this.subtitle,
      required this.value,
      required this.percent,
      required this.shouldDisplayMonthly,
      required this.shouldDisplayAsPercentage,
      required this.onTexesOrManagementValueChange,
      required this.onPercentageValueChanged,
      required this.onMonthlyAnnuallySelectionChange,
      required this.onIsPercentageChanged});

  final String title;
  final String subtitle;
  final double value;
  final double percent;
  final bool shouldDisplayMonthly;
  final bool shouldDisplayAsPercentage;
  final void Function() onTexesOrManagementValueChange;
  final void Function() onPercentageValueChanged;
  final void Function() onMonthlyAnnuallySelectionChange;
  final void Function(dynamic) onIsPercentageChanged;

  @override
  Widget build(BuildContext context) {
    return MonthlyAnnualSection(
      title: title,
      onValueChanged: onMonthlyAnnuallySelectionChange,
      children: [
        Panel(
          key: Key('$subtitle${shouldDisplayMonthly ? 'Monthly' : 'Annual'}'),
          title: subtitle,
          isPercentage: shouldDisplayAsPercentage,
          onIsPercentageChanged: onIsPercentageChanged,
          child: Column(
            children: [
              const SizedBox(height: 10),
              if (shouldDisplayAsPercentage)
                PercentageTextField(
                    value: shouldDisplayMonthly ? percent : percent * 12,
                    placeholder:
                        'example: ${(shouldDisplayMonthly ? percent : percent * 12).toPercentage()}',
                    onValueChanged: onPercentageValueChanged),
              if (!shouldDisplayAsPercentage)
                CurrencyTextField(
                  value: shouldDisplayMonthly ? value : value * 12,
                  placeholder:
                      'example: ${(shouldDisplayMonthly ? value : value * 12).toCurrency()}',
                  onValueChanged: onTexesOrManagementValueChange,
                ),
              const SizedBox(height: 10),
            ],
          ),
        ),
      ],
    );
  }
}

But in flutter making a StatelessWidget is good practice, and as it is going to be a StatelessWidget you need to do the operation like change values in the class where you are using it.

Like for this above code you need to call it like:

Scaffold(
      body: Section(
        title: 'Tax Expense',
        subtitle: '💸 Taxes',
        value: defaults.taxes,
        percent: defaults.taxesPercent,
        shouldDisplayMonthly: defaults.shouldDisplayTaxesExpensesMonthly,
        shouldDisplayAsPercentage: defaults.shouldDisplayTaxesAsPercentage,
        onIsPercentageChanged: (val) =>
            setState(() => defaults.shouldDisplayTaxesAsPercentage = val),
        onMonthlyAnnuallySelectionChange: (value) => setState(
            () => defaults.shouldDisplayTaxesExpensesMonthly = value == 'm'),
        onPercentageValueChanged: (val) => setState(() =>
            defaults.taxesPercent =
                defaults.shouldDisplayTaxesExpensesMonthly ? val : val / 12),
        onTexesOrManagementValueChange: (val) => setState(() => defaults.taxes =
            defaults.shouldDisplayTaxesExpensesMonthly ? val : val / 12),
      ),
    ); 
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.