简体   繁体   中英

Pass a class as method parameter in Dart

Suppose this class:

class SimpleRectPaint extends Object {

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

}

I'd like to abstract the class SimpleRectPaint by means of a ClassReference parameter someClass and make the method more generic. Unfortunately, this isn't valid code:

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

}

Q: How do I have to write it instead?

在此处输入图像描述

You could do that by passing a 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;
}

But, though the exercise is interesting... Why?

Instead of:

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

You can just do:

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

If, not, what is the specific needs that would require more abstraction?

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