15_flutter_自定义控件,自定义插件

660 阅读2分钟

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_自定义插件