Flutter小部件最佳实践:内部类 vs 函数

4

我是一名Java开发者,目前正在学习Flutter/Dart。我是一个干净代码的支持者,喜欢使用小函数,但一些Widget示例让我感到非常害怕。

我正在尝试使用Card Widget实现一些交易信息(价格、标题和日期)。目前的代码如下:

class TransactionCard extends StatelessWidget {
  final Transaction _transaction;

  TransactionCard(this._transaction);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Card(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            _PriceContainer(_transaction.amount),
            _DetailContainer(_transaction.title, _transaction.date),
          ],
        ),
      ),
    );
  }
}

// Inner Widgets

class _PriceContainer extends Container {
  _PriceContainer(double amount)
      : super(
    margin: EdgeInsets.symmetric(
      vertical: 10,
      horizontal: 15,
    ),
    decoration: BoxDecoration(
      border: Border.all(
        color: Colors.purple,
        width: 2,
      ),
    ),
    padding: EdgeInsets.all(10),
    child: Text(
      amount.toString(),
      style: _amountTextStyle(),
    ),
  );
}

class _DetailContainer extends Container {
  _DetailContainer(String title, DateTime date)
      : super(
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Text(
          title,
          style: _titleTextStyle(),
        ),
        Text(
          date.toString(),
          style: _dateTextStyle(),
        ),
      ],
    ),
  );
}

// Text styles

TextStyle _amountTextStyle() {
  return TextStyle(
    fontWeight: FontWeight.bold,
    fontSize: 20,
    color: Colors.purple,
  );
}

TextStyle _titleTextStyle() {
  return TextStyle(
    fontWeight: FontWeight.bold,
    fontSize: 18,
  );
}

TextStyle _dateTextStyle() {
  return TextStyle(color: Colors.grey);
}

我采用了两种方法:
  1. 对于内部小部件,我扩展了Containers并赋予了它们特定的样式。
  2. 对于文本样式,我创建了一个返回所需样式的函数。
有哪种方法更好?还是第三种方法?在同一文件中创建多个小部件是不良惯例吗?

两者都不好。扩展小部件是一种反模式,应改用组合。至于函数,请参见https://dev59.com/plQJ5IYBdhLWcg3wuoX7#53234826。 - Rémi Rousselet
@RémiRousselet,我同意第一个观点,但我认为你在与你的问题有关的“函数”问题上错过了重点。 - creativecreatorormaybenot
1个回答

2

组合优于继承

正如在评论和 Flutter 文档中所提到的,您应该始终组合小部件,而不是从例如 Container 继承。

在您的情况下,这将如下所示:

class _PriceContainer extends StatelessWidget {
  final double amount;

  const _PriceContainer({
    Key key,
    this.amount,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) => Container(
        margin: const EdgeInsets.symmetric(
          vertical: 10,
          horizontal: 15,
        ),
        decoration: BoxDecoration(
          border: Border.all(
            color: Colors.purple,
            width: 2,
          ),
        ),
        padding: EdgeInsets.all(10),
        child: Text(
          amount.toString(),
          style: _amountTextStyle,
        ),
      );
}

这同样适用于您的其他小部件。

顶级函数

声明顶级函数通常是可以的,但在这种情况下,最好定义一个顶级属性 - 最好声明一个const以利用编译时常量:

const _amountTextStyle = TextStyle(
  fontWeight: FontWeight.bold,
  fontSize: 20,
  color: Colors.purple,
);

你应该能够将同样的方法应用到其他文本样式中。

我该如何根据屏幕大小调整字体大小?这是一种不好的做法吗?我是否应该始终使用精确像素? - chichi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接