简体   繁体   中英

Flutter widgets best practices: Inner Class vs Function

I am a Java developer and currently learning about Flutter/Dart. I am an adept of clean code with small functions and some widget examples just scare the s*** out of me.

I am trying to implement a Card widget with some transaction information (price, title and date). Currently the code looks like this:

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);
}

I have used two approaches:

  1. For the inner widgets I extended Containers and gave then specific styling.
  2. For the text styles I created a function returning the desired style.

Is there an approach preferable to the other? A third one? Is there a bad practice to create multiple Widgets on the same file?

Composition > inheritance

As mentioned in the comments and in the Flutter documentation , you should always compose widgets instead of inheriting from eg a Container .

In your case, this would look like this:

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,
        ),
      );
}

This is analogous for your other widgets.

Top-level functions

Declaring top-level functions is generally fine, however, in this case, you should really define a top-level property instead - preferably declare a const to take advantage of compile-time constants:

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

You should be able to apply the same to your other text styles.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM