【问题标题】:Pass a class as method parameter in Dart在 Dart 中传递一个类作为方法参数
【发布时间】:2021-05-06 02:08:57
【问题描述】:

假设这个类:

class SimpleRectPaint extends Object {

  static CustomPaint build( ParamsBundle paramBundle ) {
     return CustomPaint(
         painter: SimpleRectPainter( paramBundle: paramBundle ),
         child: Container(width: paramBundle.width, height: paramBundle.height)
     );
  }

}

我想通过ClassReference 参数someClass 抽象类SimpleRectPaint 并使该方法更通用。不幸的是,这不是有效的代码:

class SimpleRectPaint extends Object {

  static CustomPaint build( ParamsBundle paramBundle, ClassReference someClass ) {
     return CustomPaint(
         painter: someClass( paramBundle: paramBundle ),
         child: Container(width: paramBundle.width, height: paramBundle.height)
     );
  }

}

问:我要怎么写?

【问题讨论】:

  • @jamesdlin 谢谢!明天复查。太晚了。我知道,我可能会传入签名闭包( paramBundle -> someClass )。但不知怎的,我不喜欢它。嗯……
  • 我质疑以这种方式抽象它的好处。当然,任何可以调用该静态方法的地方都可以访问ParamsBundle 和使用ParamsBundle 作为其参数构造的类引用,那么你为什么不事先构造该类并传入构造的对象?让build 方法负责构建有什么好处?

标签: flutter dart


【解决方案1】:

您可以通过传递 CustomPainterCreator 来做到这一点:

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      title: 'Generic Painter',
      home: Scaffold(
        body: MyWidget(),
      ),
    ),
  );
}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: SizedBox(
        width: 200,
        height: 200,
        child: Stack(
          fit: StackFit.expand,
          children: [
            Background(),
            MyPainter(creator: RectPainter.creator, color: Color(0xFF104C91)),
            MyPainter(creator: OvalPainter.creator, color: Color(0xFF1F8AC0)),
          ],
        ),
      ),
    );
  }
}

class Background extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: Color(0xFFEFC9AF),
        border: Border.all(width: 3.0),
        borderRadius: BorderRadius.all(Radius.circular(10.0)),
      ),
    );
  }
}

typedef CustomPainterCreator(Color color);

class MyPainter extends StatelessWidget {
  final CustomPainterCreator creator;
  final Color color;

  const MyPainter({
    Key key,
    this.creator,
    this.color,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: creator(color),
    );
  }
}

class OvalPainter extends CustomPainter {
  static CustomPainterCreator creator = (color) => OvalPainter(color: color);

  final Color color;

  OvalPainter({this.color = Colors.green});

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..color = color;
    canvas.drawOval(
      Rect.fromLTWH(size.width * .4, size.height * .15, size.width * .5,
          size.height * .5),
      paint,
    );
  }

  @override
  bool shouldRepaint(OvalPainter oldDelegate) => false;
}

class RectPainter extends CustomPainter {
  static CustomPainterCreator creator = (color) => RectPainter(color: color);

  final Color color;

  RectPainter({this.color = Colors.indigo});

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()..color = color;
    canvas.drawRRect(
      RRect.fromRectAndRadius(
          Rect.fromLTWH(size.width * .15, size.height * .25, size.width * .6,
              size.height * .6),
          Radius.circular(20)),
      paint,
    );
  }

  @override
  bool shouldRepaint(RectPainter oldDelegate) => false;
}

但是,虽然这个练习很有趣……为什么?

代替:

MyPainter(creator: RectPainter.creator, color: Color(0xFF104C91)),

你可以这样做:

CustomPaint(painter: RectPainter(color: Color(0xFF104C91))),

如果不是,那么需要更多抽象的具体需求是什么?

【讨论】:

    猜你喜欢
    • 2019-09-21
    • 1970-01-01
    • 1970-01-01
    • 2017-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多