Flutter-构造器混淆

erhoui1w  于 2023-06-07  发布在  Flutter
关注(0)|答案(1)|浏览(151)

在应用程序的主页上,用户单击他们想要查看的帐户,并显示该特定帐户的数据模型页面中的余额(参见屏幕截图)。我以为我知道该怎么做,但什么都不起作用。我有它的应用程序的其他部分工作,但我不能让它在这里工作。我如何才能做到这一点?下面是代码:
在OwenTab页面上,我想用数据模型页面中的实际余额替换“Text($20.00)”。

import 'package:flutter/material.dart';

class OwenTab extends StatelessWidget {
  const OwenTab({super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        const Text(
          '\$20.00',
          style: TextStyle(fontSize: 36, fontWeight: FontWeight.bold),
        ),
        const SizedBox(height: 10.0),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: const [
            Text(
              'Available to spend',
              style: TextStyle(fontSize: 15),
            ),
            Icon(Icons.keyboard_arrow_down_rounded, size: 30),
          ],
        ),
      ],
    );
  }
}

下面是导入OwenTab()的地方。

import 'package:flutter/material.dart';
import '../../pages/eloise_tab.dart';
import '../../pages/henry_tab.dart';
import '../../pages/owen_tab.dart';

class MoneyTabBar extends StatelessWidget {
  final int tabIndex;

  const MoneyTabBar({
    super.key,
    required this.tabIndex,
  });

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      initialIndex: tabIndex,
      length: 3, // 3 tabs
      child: Scaffold(
        // TabBar Background Color
        backgroundColor: Colors.white,

        body: Column(
          children: const [
            TabBar(
              padding: EdgeInsets.only(left: 80, right: 80),
              indicatorColor: Colors.red,
              indicatorSize: TabBarIndicatorSize.label,
              labelColor: Colors.black,
              unselectedLabelColor: Colors.grey,
              labelStyle: TextStyle(fontSize: 18, fontWeight: FontWeight.w500),
              tabs: [
                // "Owen" Tab
                Tab(
                  text: 'Owen',
                ),

                // "Eloise" Tab
                Tab(
                  text: 'Eloise',
                ),

                // "Henry" Tab
                Tab(
                  text: 'Henry',
                ),
              ],
            ),
            SizedBox(height: 25),
            Expanded(
              child: TabBarView(
                children: [
                  // "Owen" Tab Content
                  OwenTab(),

                  // "Eloise" Tab Content
                  EloiseTab(),

                  // "Henry" Tab Content
                  HenryTab(),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

下面是数据模型代码:

import 'package:flutter/material.dart';

import '../models/child_tile.dart';
import '../models/home_tile.dart';

class GoHenryData extends ChangeNotifier {
  ////////////////////////////////////////////////////////////  LISTS  ////////////////////////////////////////////////////////////

  final List<HomeTile> _homeTiles = [
    HomeTile(
      iconImagePath: 'lib/assets/images/price-sticker.png',
      title: 'New in GoHenry',
      subTitle: 'Your app has new features!',
      boxColor: Colors.deepPurple,
      borderRadius: BorderRadius.circular(10),
    ),
    HomeTile(
        iconImagePath: 'lib/assets/images/money.png',
        title: 'Set up mission payments',
        subTitle: 'Reward your kids for learning',
        boxColor: Colors.deepPurple,
        borderRadius: BorderRadius.circular(50)),
    HomeTile(
        iconImagePath: 'lib/assets/images/well-done.png',
        title: 'School\'s out?',
        subTitle: 'Transfer money, say well done',
        boxColor: Colors.black,
        borderRadius: BorderRadius.circular(10)),
    HomeTile(
        iconImagePath: 'lib/assets/images/chat.png',
        title: 'Claim you bonus',
        subTitle: '\$50 for every friend referral',
        boxColor: Colors.white,
        borderRadius: BorderRadius.circular(10)),
  ];

  final List<ChildTile> _childTiles = [
    ChildTile(
      avatarImagePath: const AssetImage('lib/assets/images/owen.jpg'),
      childName: 'Owen',
      balance: '\$20.00',
      totalBalance: '\$22.00',
      savingsBalance: '\$0.00',
      bottomName: 'Owen',
    ),
    ChildTile(
      avatarImagePath: const AssetImage('lib/assets/images/eloise.jpg'),
      childName: 'Eloise',
      balance: '\$22.00',
      totalBalance: '\$40.00',
      savingsBalance: '\$0.00',
      bottomName: 'Eloise',
    ),
    ChildTile(
      avatarImagePath: const AssetImage('lib/assets/images/henry.jpg'),
      childName: 'Henry',
      balance: '\$15.00',
      totalBalance: '\$20.00',
      savingsBalance: '\$0.00',
      bottomName: 'Henry',
    )
  ];
  ////////////////////////////////////////////////////////////  GETTERS  ////////////////////////////////////////////////////////////

  List<HomeTile> get homeTiles => _homeTiles;

  List<ChildTile> get childTiles => _childTiles;

  ////////////////////////////////////////////////////////////  ADDERS  ////////////////////////////////////////////////////////////

  ////////////////////////////////////////////////////////////  REMOVERS  ////////////////////////////////////////////////////////////
}

这里是HomePage(),以防万一:

import 'package:flutter/material.dart';
import 'package:gohenry_clone/components/tiles/child_tile.dart';
import 'package:gohenry_clone/pages/money_page.dart';
import 'package:gohenry_clone/pages/savings_page.dart';
import 'package:provider/provider.dart';
import '../components/tiles/home_tiles.dart';
import '../data/gohenry_data.dart';
import '../models/child_tile.dart';
import '../models/home_tile.dart';
import 'cards_page.dart';

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Consumer<GoHenryData>(
      builder: (context, value, child) => Scaffold(
        // AppBar
        appBar: AppBar(
          toolbarHeight: 255,
          elevation: 0,
          flexibleSpace: Container(
            color: Colors.red.shade400,
            child: SafeArea(
              child: Column(
                children: [
                  // Header
                  const Padding(
                    padding: EdgeInsets.only(top: 20.0),
                    child: Text(
                      'Your parent balance',
                      style: TextStyle(
                          fontWeight: FontWeight.w600,
                          fontSize: 18,
                          color: Colors.white),
                    ),
                  ),

                  // Balance
                  const Padding(
                    padding: EdgeInsets.only(top: 30.0),
                    child: Text(
                      '\$40.00',
                      style: TextStyle(
                          fontSize: 36,
                          fontWeight: FontWeight.bold,
                          color: Colors.white),
                    ),
                  ),

                  // Text
                  const Padding(
                    padding: EdgeInsets.only(top: 30.0),
                    child: Text(
                      'Next allowance in 2 days \$10.00',
                      style: TextStyle(
                          color: Colors.white,
                          fontSize: 16,
                          fontWeight: FontWeight.w500),
                    ),
                  ),

                  // "Add Money" Button
                  Padding(
                    padding: const EdgeInsets.only(top: 20.0),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        GestureDetector(
                          onTap: () => {},
                          child: Container(
                            decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(50),
                              color: Colors.white,
                            ),
                            width: 190,
                            child: const Padding(
                              padding: EdgeInsets.all(15.0),
                              child: Center(
                                child: Text('Add money',
                                    style: TextStyle(
                                        fontSize: 16,
                                        fontWeight: FontWeight.w500)),
                              ),
                            ),
                          ),
                        ),
                        const SizedBox(
                          width: 12.0,
                        ),

                        // "Transfer" Button
                        GestureDetector(
                          onTap: () => {},
                          child: Container(
                            decoration: BoxDecoration(
                              borderRadius: BorderRadius.circular(50),
                              color: Colors.white,
                            ),
                            width: 190,
                            child: const Padding(
                              padding: EdgeInsets.all(15.0),
                              child: Center(
                                child: Text('Transfer',
                                    style: TextStyle(
                                        fontSize: 16,
                                        fontWeight: FontWeight.w500)),
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ),
        ),

        // Home Banner Tiles
        body: Column(
          children: [
            Container(
              height: 100,
              child: Expanded(
                child: ListView.builder(
                  scrollDirection: Axis.horizontal,
                  itemCount: value.homeTiles.length,
                  itemBuilder: (context, index) {
                    HomeTile individualHomeTile = value.homeTiles[index];
                    return Padding(
                      padding: index == value.homeTiles.length - 1
                          ? const EdgeInsets.fromLTRB(20, 0, 20, 0)
                          : const EdgeInsets.only(left: 20.0),
                      child: HomeTiles(
                        homeTiles: individualHomeTile,
                      ),
                    );
                  },
                ),
              ),
            ),
            const SizedBox(height: 10),

            // Child's Main Tiles
            Expanded(
              child: ListView.builder(
                scrollDirection: Axis.vertical,
                itemCount: value.childTiles.length,
                itemBuilder: (context, index) {
                  ChildTile individualChildTile = value.childTiles[index];
                  return Padding(
                    padding: const EdgeInsets.only(bottom: 10),
                    child: ChildTiles(
                      childTiles: individualChildTile,
                      onTap: () {
                        Navigator.of(context).push(
                          MaterialPageRoute(
                            builder: (context) => MoneyPage(
                              tabIndex:
                                  index, // Goes to corresponding child's account tab
                            ),
                          ),
                        );
                      },
                      onPress: () {
                        Navigator.of(context).push(
                          MaterialPageRoute(
                            builder: (context) => const CardsPage(),
                          ),
                        );
                      },
                      onPressTwo: () {
                        Navigator.of(context).push(
                          MaterialPageRoute(
                            builder: (context) => const SavingsPage(),
                          ),
                        );
                      },
                    ),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

下面是MoneyPage(),以防万一:

import 'package:flutter/material.dart';
import '../components/widgets/money_tab_bar.dart';

class MoneyPage extends StatefulWidget {
  final int tabIndex;
  const MoneyPage({super.key, required this.tabIndex});

  @override
  State<MoneyPage> createState() => _CardsPageState();
}

class _CardsPageState extends State<MoneyPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        iconTheme: const IconThemeData(color: Colors.black),
        actions: const [
          Padding(
            padding: EdgeInsets.only(right: 20.0),
            child: Icon(Icons.pie_chart_outline, color: Colors.black),
          ),
        ],
        backgroundColor: Colors.white,
        elevation: 0,
        title: const Text(
          'Money',
          style: TextStyle(color: Colors.black, fontSize: 16),
        ),
      ),
      body: MoneyTabBar(tabIndex: widget.tabIndex),
    );
  }
}

以下是截图:

5ssjco0h

5ssjco0h1#

您的数据似乎在GoHenryData小部件中,这是一个ChangeNotifier。您大概已经了解到,这个小部件的目的是向它的后代提供应用程序状态。我还假设您已经正确地向应用程序提供了changenotifier,如here所示。下一步是使用Consumer小部件访问该数据。您要查找的数据将是goHenryData.childTiles[0].totalBalance
然而,为每个硬编码的子组件创建单独的小部件是一种糟糕的设计。与其创建OwenTab、EloiseTab和HenryTab,不如创建一个ChildTab,它将ChildTile作为其构造函数中的参数,并且可以为所有3个选项重用。然后,您可以根据状态中的ChildTiles列表动态创建选项卡。
假设childTiles是应用程序状态中的ChildTiles列表,则可以按如下方式生成选项卡

childTabHeaders = childTiles.map((e) => Tab(text: e.childName)));
childTabs = childTiles.map((e) => ChildTab(childTile: e));

然后可以使用这些来构建MoneyTabBar小部件,该小部件现在可以支持任何数量的子部件。此外,在编写代码时,您不需要知道任何关于子节点的编号/名称的信息,这允许您执行诸如从数据库加载数据之类的操作。这对于像这样的应用程序的任何实际使用都是必要的。

相关问题