1_自定义控件


1.1_组合控件

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo'),
    );
  }
}
class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: CombinationWidget(Colors.blue,200.0,200.0),
    );
  }
}
// 组合控件
class CombinationWidget extends StatefulWidget {
  @required
  Color color;
  @required
  double width;
  @required
  double height;
  CombinationWidget(this.color, this.width, this.height);
  @override
  State createState() {
    return _CombinationWidgetState(color, width, height);
  }
}
class _CombinationWidgetState extends State {
  Color _color;
  double _width;
  double _height;
  var _startCount = 0;
  _CombinationWidgetState(this._color, this._width, this._height);
  @override
  Widget build(BuildContext context) {
    return Center(
      child: ClipOval(
        child: Container(
          color: _color,
          width: _width,
          height: _height,
          child: Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              IconButton(
                  icon: const Icon(
                    Icons.thumb_up,
                    color: Colors.white,
                  ),
                  onPressed: () {
                    setState(() {
                      _startCount += 1;
                    });
                  }),
              Text(
                _startCount.toString(),
                style: const TextStyle(fontSize: 25, color: Colors.red),
              )
            ],
          ),
        ),
      ),
    );
  }
}

1.2_自绘控件

import 'dart:math';
import 'package:flutter/material.dart';
void main() {
  runApp(const MyApp());
}
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo'),
    );
  }
}
class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: const WheelWidget(),
    );
  }
}
// 将饼图封装成一个新的控件
class WheelWidget extends StatelessWidget {
  const WheelWidget({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      // 设置控件宽高
      size: const Size(200, 200),
      painter: WheelPaint(),
    );
  }
}
// 自绘控件
class WheelPaint extends CustomPainter {
  // 设置画笔色彩,返回不同色彩画笔
  Paint getColorPaint(Color color) {
    // 生成画笔
    Paint paint = Paint();
    // 设置画笔色彩
    paint.color = color;
    return paint;
  }
  // 制作逻辑
  @override
  void paint(Canvas canvas, Size size) {
    // 饼图的尺度
    double wheelSize = min(size.width, size.height) / 2;
    // 分红 6 份
    double nbElem = 6;
    // 1/6 圆
    double radius = (2 * pi) / nbElem;
    // 包裹饼图这个圆形的矩形框
    Rect boundingRect = Rect.fromCircle(center: Offset(wheelSize, wheelSize), radius: wheelSize);
    // 每次画 1/6 个圆弧
    canvas.drawArc(boundingRect, 0, radius, true, getColorPaint(Colors.orange));
    canvas.drawArc(boundingRect, radius, radius, true, getColorPaint(Colors.black38));
    canvas.drawArc(boundingRect, radius * 2, radius, true, getColorPaint(Colors.green));
    canvas.drawArc(boundingRect, radius * 3, radius, true, getColorPaint(Colors.red));
    canvas.drawArc(boundingRect, radius * 4, radius, true, getColorPaint(Colors.blue));
    canvas.drawArc(boundingRect, radius * 5, radius, true, getColorPaint(Colors.pink));
  }
  // 判别是否需要重绘,这里简略的做下比较即可
  @override
  bool shouldRepaint(CustomPainter oldDelegate) => oldDelegate != this;
}

2_自定义插件