Flutter多边形处理插件flutter_polygon的使用

发布于 1周前 作者 songsunli 来自 Flutter

Flutter多边形处理插件flutter_polygon的使用

flutter_polygon 是一个Flutter插件,用于创建正多边形形状(如五边形和六边形)视图。它基于 polygon_clipper 包开发。

安装

在你的项目的 pubspec.yaml 文件中添加以下依赖:

dependencies:
  flutter_polygon: ^0.2.0

然后运行 flutter pub get 来安装依赖。

使用

Clipping

使用 ClipPolygon 小部件裁剪子小部件。

import 'package:flutter_polygon/flutter_polygon.dart';

ClipPolygon(
  sides: 6, // 边的数量,默认为3
  borderRadius: 5.0, // 圆角半径,默认为0.0度
  rotate: 90.0, // 旋转角度,默认为0.0度
  boxShadows: [
    PolygonBoxShadow(color: Colors.black, elevation: 1.0),
    PolygonBoxShadow(color: Colors.grey, elevation: 5.0)
  ],
  child: Container(color: Colors.black),
);

Borders

使用 PolygonBorder 形状与你最喜欢的小部件一起使用!

import 'package:flutter_polygon/flutter_polygon.dart';

FloatingActionButton(
  shape: PolygonBorder(
    sides: 6,
    borderRadius: 5.0, // 默认为0.0度
    rotate: 30.0, // 默认为0.0度
    border: BorderSide(color: Colors.red, width: 2.0), // 默认为BorderSide.none
  ),
  onPressed: () {},
  child: Icon(Icons.star),
),

其他可以使用的部件包括:

  • TextButton, ElevatedButton, …
  • Container
  • Chip

示例Demo

下面是一个完整的示例代码,展示了如何使用 flutter_polygon 插件来创建不同类型的多边形部件。

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_polygon/flutter_polygon.dart';

void main() => runApp(ExampleApp());

const nbs = <int>[3, 4, 5, 6, 7, 8, 9, 10];
const rotates = <double>[0, 30, 60, 90, 120, 150, 180];
const colors = <Color>[
  Colors.black,
  Colors.red,
  Colors.orange,
  Colors.yellow,
  Colors.green,
  Colors.blue,
  Colors.indigo,
  Colors.purple,
];

class ExampleApp extends StatefulWidget {
  @override
  _ExampleAppState createState() => _ExampleAppState();
}

class _ExampleAppState extends State<ExampleApp> {
  int nb = 6;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        extendBody: true,
        appBar: AppBar(
          title: Text('Flutter Polygon'),
          backgroundColor: Colors.blue[900],
          systemOverlayStyle: SystemUiOverlayStyle.light,
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {},
          shape: PolygonBorder(sides: nb),
          child: Icon(Icons.star),
        ),
        bottomNavigationBar: BottomAppBar(
          shape: AutomaticNotchedShape(
            RoundedRectangleBorder(),
            PolygonBorder(sides: nb),
          ),
          color: Colors.orange,
          notchMargin: 6.0,
          child: Row(
            mainAxisSize: MainAxisSize.max,
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              IconButton(
                icon: Icon(Icons.code),
                onPressed: () {},
              ),
              IconButton(
                  icon: Icon(Icons.save),
                  onPressed: () {}
              ),
            ],
          ),
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
        body: Container(
          child: SingleChildScrollView(
            padding: const EdgeInsets.only(bottom: 96.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              mainAxisSize: MainAxisSize.max,
              children: <Widget>[
                const SizedBox(height: 8.0,),
                Text(
                  'Chips',
                  style: Theme.of(context).textTheme.headline6
                ),
                _showCase(nbs.map(_chip)),
                const SizedBox(height: 8.0,),
                Text(
                    'Buttons',
                    style: Theme.of(context).textTheme.headline6
                ),
                _showCase(nbs.map(_button)),
                const SizedBox(height: 8.0,),
                Text(
                    'Containers',
                    style: Theme.of(context).textTheme.headline6
                ),
                _showCase(nbs.map(_container)),
                _showCase(nbs.map((nb) => _container(nb, width: 2, rotate: 15.0))),
                _showCase(nbs.map((nb) => _container(nb, width: 3, rotate: 30.0))),
                const SizedBox(height: 8.0,),
                Text(
                    'Clipped Image',
                    style: Theme.of(context).textTheme.headline6
                ),
                const SizedBox(height: 8.0,),
                _image(nb),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget _showCase(Iterable<Widget> widgets) {
    return SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
      child: Row(
        children: widgets.toList(),
      ),
    );
  }

  Widget _image(int sides) {
    return ClipPolygon(
      child: Image.network("https://cdn.pixabay.com/photo/2018/01/05/00/20/test-image-3061864_960_720.png"),
      boxShadows: [
        PolygonBoxShadow(color: Colors.black, elevation: 2.0),
        PolygonBoxShadow(color: Colors.yellow, elevation: 4.0),
        PolygonBoxShadow(color: Colors.red, elevation: 6.0),
      ],
      sides: sides,
      borderRadius: 10,
    );
  }

  Widget _button(int sides, {BorderSide side = BorderSide.none}) {
    return TextButton(
      style: ButtonStyle(
        shape: MaterialStateProperty.all<PolygonBorder>(
            PolygonBorder(sides: sides, side: BorderSide())
        ),
      ),
      onPressed: () { },
      child: Text('$sides'),
    );
  }

  Widget _chip(int sides, {BorderSide side = BorderSide.none}) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 4.0),
      child: ChoiceChip(
        shape: PolygonBorder(
          sides: sides,
          side: side,
        ),
        label: Text('$sides'),
        selected: nb == sides,
        onSelected: (s) {
          setState(() {
            this.nb = sides;
          });
        },
      ),
    );
  }

  Widget _container(int sides, {double width = 1.0, double rotate = 0.0}) {
    var index = (sides-3);
    return Container(
      padding: EdgeInsets.all(18.0),
      margin: EdgeInsets.only(right: 16.0),
      decoration: ShapeDecoration(
        shape: PolygonBorder(
          sides: sides,
          rotate: rotate,
          side: BorderSide(
            color: colors[index % colors.length],
            width: width,
          ),
        ),
      ),
      child: Text('$sides'),
    );
  }
}

这个示例代码创建了一个包含多种多边形部件的应用程序,包括按钮、容器、标签和裁剪图像等,展示了 flutter_polygon 的强大功能。

贡献

如果你发现此包存在问题,请在 GitHub 上提交问题。

如果你想为此项目做贡献,欢迎提交拉取请求。

致谢

此包基于 polygon_clipper 包开发,感谢 leonardocaldas 的贡献。


更多关于Flutter多边形处理插件flutter_polygon的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter多边形处理插件flutter_polygon的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter中使用flutter_polygon插件来处理多边形的代码案例。这个插件可以用来绘制和处理多边形,非常适合地图应用、图形界面或其他需要多边形操作的场景。

首先,你需要在你的pubspec.yaml文件中添加flutter_polygon依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_polygon: ^最新版本号  # 请替换为实际最新版本号

然后运行flutter pub get来安装依赖。

接下来,我们来看一个基本的代码示例,展示如何使用flutter_polygon来绘制和处理多边形。

import 'package:flutter/material.dart';
import 'package:flutter_polygon/flutter_polygon.dart';
import 'dart:math' as math;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Polygon Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: PolygonScreen(),
    );
  }
}

class PolygonScreen extends StatefulWidget {
  @override
  _PolygonScreenState createState() => _PolygonScreenState();
}

class _PolygonScreenState extends State<PolygonScreen> {
  List<LatLng> _polygonPoints = [];
  PolygonController? _polygonController;

  @override
  void initState() {
    super.initState();
    // 初始化一些多边形的点(例如一个矩形)
    _polygonPoints = [
      LatLng(0, 0),
      LatLng(10, 0),
      LatLng(10, 10),
      LatLng(0, 10),
      LatLng(0, 0), // 闭合多边形
    ];

    // 初始化PolygonController
    _polygonController = PolygonController(
      polygonPoints: _polygonPoints,
      onPolygonPointsChanged: (points) {
        setState(() {
          _polygonPoints = points;
        });
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Polygon Demo'),
      ),
      body: GoogleMap(
        mapType: MapType.normal,
        initialCameraPosition: CameraPosition(
          target: LatLng(5, 5),
          zoom: 10.0,
        ),
        polygons: {
          PolygonId('polygon_id'): Polygon(
            polygonId: PolygonId('polygon_id'),
            points: _polygonPoints.map((e) => LatLngLiteral(latitude: e.latitude, longitude: e.longitude)).toList(),
            strokeColor: Colors.blue.withOpacity(0.8),
            strokeWidth: 3.0,
            fillColor: Colors.blue.withOpacity(0.3),
          ),
        },
        onMapCreated: (GoogleMapController googleMapController) {
          _polygonController?.googleMapController = googleMapController;
          _polygonController?.startListening();
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // 清除多边形点
          _polygonController?.clearPolygonPoints();
        },
        tooltip: 'Clear Polygon',
        child: Icon(Icons.clear),
      ),
    );
  }

  @override
  void dispose() {
    _polygonController?.stopListening();
    _polygonController = null;
    super.dispose();
  }
}

在这个示例中,我们使用了flutter_polygon插件与google_maps_flutter插件结合来在地图上绘制多边形。PolygonController用于管理多边形的点,并处理用户交互。

注意

  1. 你需要确保你的项目已经正确配置了google_maps_flutter插件。
  2. 由于flutter_polygon插件的具体API可能会随版本变化,请查阅最新的官方文档以获取最新和最准确的API信息。

这个示例演示了如何初始化多边形、绘制多边形以及处理用户交互(如清除多边形点)。你可以根据需求进一步扩展这个示例,比如添加更多的多边形、处理多边形的点击事件等。

回到顶部