【问题标题】:Refactoring Dart Code into a separate file将 Dart 代码重构为单独的文件
【发布时间】:2021-04-02 20:56:12
【问题描述】:

我有这段代码,我的应用程序中有侧边栏(抽屉)。我创建了一个单独的文件drawer.dart,看起来有点像这样:

import 'package:flutter/material.dart';

class DrawerClass extends StatefulWidget {
  @override
  _DrawerClassState createState() => _DrawerClassState();
}

class _DrawerClassState extends State<DrawerClass> {
  @override
  Widget build(BuildContext context) {
    return Drawer(
      child: ListView(
        padding: EdgeInsets.zero,
        children: [
          DrawerHeader(
            child: CircleAvatar(
              backgroundColor: Theme.of(context).primaryColor,
              radius: 30,
              child: Icon(
                Icons.pets,
                size: 60,
                color: Colors.white,
              ),
            ),
          ),
          ListTile(
            leading: Icon(Icons.home),
            title: Text("Home"),
            onTap: () {
              Navigator.pushReplacementNamed(context, "/home");
            },
          ),
          ListTile(
            leading: Icon(
              Icons.report,
            ),
            title: Text("Report"),
            onTap: () {
              Navigator.pushReplacementNamed(context, "/report");
            },
          ),
          ListTile(
            leading: Icon(
              Icons.settings,
            ),
            title: Text("Settings"),
            onTap: () {
              Navigator.pop(context);
            },
          ),
        ],
      ),
    );
  }
}

现在我有三个不同的文件:home.dart、report.dart、settings.dart。此重构代码在settings.dart 中使用时将完美运行,但在其他两个文件中则不行。例如,如果我在report.dart 中使用它,我必须将其 onTap 状态更改为Navigator.pop。我需要在所有其他 3 个文件中使用 drawer.dart,仅更改每个文件中的 onTap 状态。

任何帮助将不胜感激:)

【问题讨论】:

    标签: flutter dart refactoring navigation-drawer


    【解决方案1】:

    这样做的一种方法是这样的。

    enum ScreenName {
      Home,
      Report,
      Settings,
    }
    

    将此enum 用作DrawerClass 的属性(parentScreen),以便它知道它在哪个屏幕中。

    class DrawerClass extends StatefulWidget {
      final ScreenName parentScreen;
    
      const DrawerClass({@required this.parentScreen});
    
      @override
      _DrawerClassState createState() => _DrawerClassState();
    }
    
    class _DrawerClassState extends State<DrawerClass> {
      @override
      Widget build(BuildContext context) {
        return Drawer(
          child: ListView(
            padding: EdgeInsets.zero,
            children: [
              // other children,
              ListTile(
                leading: Icon(Icons.home),
                title: Text("Home"),
                onTap: () {
                  if (widget.parentScreen == ScreenName.Home)
                    Navigator.pop(context);
                  else
                    Navigator.pushReplacementNamed(context, "/home");
                },
              ),
              ListTile(
                leading: Icon(Icons.report),
                title: Text("Report"),
                onTap: () {
                  if (widget.parentScreen == ScreenName.Report)
                    Navigator.pop(context);
                  else
                    Navigator.pushReplacementNamed(context, "/report");
                },
              ),
              ListTile(
                leading: Icon(Icons.settings),
                title: Text("Settings"),
                onTap: () {
                  if (widget.parentScreen == ScreenName.Settings)
                    Navigator.pop(context);
                  else
                    Navigator.pushReplacementNamed(context, "/settings");
                },
              ),
            ],
          ),
        );
      }
    }
    

    然后像这样使用DrawerClass。例如,设置屏幕 -

    DrawerClass(parentScreen: ScreenName.Settings)
    

    【讨论】:

    • 感谢您的回答。我也想对颜色和样式做同样的事情,例如,如果父屏幕是主页 - 我想将其图标颜色更改为color: Theme.of(context).colorScheme.onPrimary,将文本样式和颜色更改为style: Theme.of(context).textTheme.bodyText1.copyWith(color: Theme.of(context).colorScheme.onPrimary,),将tileColor 更改为tileColor: Theme.of(context).primaryColor
    • 其他屏幕相同
    • @HaardikDharma,您可以使用相同的属性 (parentScreen) 来决定要设置哪个 color 或 style。
    • 你能写一个例子吗?我试着按照你说的做,但无法通过
    • 例如Icon(Icons.home, color: widget.parentScreen == ScreenName.Home ? color1 : color2)
    猜你喜欢
    • 2011-12-06
    • 2017-11-24
    • 2020-05-30
    • 1970-01-01
    • 2015-11-14
    • 2023-03-13
    • 1970-01-01
    • 2019-09-11
    • 1970-01-01
    相关资源
    最近更新 更多