Flutter实现矩形取色器的封装
前言
最近看插件库上少有的取色器大都是圆形的或者奇奇怪的的亚子,所以今天做两个矩形的颜色取色器
提示:以下是本篇文章正文内容,下面案例可供参考
一、BarTypeColorPicker
条形选色板的功能实现,颜色的获取是通过位置来判断,然后赋予相应的颜色。这个封装好的组件可通过colorListener、onTapUpListener的回调方法,把颜色传出去。
代码如下(示例):
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; ///描述:条形选色板 class BarTypeColorPicker extends StatefulWidget { final Color initialColor; final ValueChanged<Color> colorListener; final ValueChanged<Color> onTapUpListener; final int colorWidth; final int colorHeight; final Color color; const BarTypeColorPicker( {Key key, this.initialColor, this.colorListener, this.onTapUpListener, this.colorWidth, this.colorHeight, this.color}) : super(key: key); @override _BarTypeColorPickerState createState() => _BarTypeColorPickerState( colorWidth.toDouble(), colorHeight.toDouble(), ); } class _BarTypeColorPickerState extends State<BarTypeColorPicker> { double _top = 0.0; double _left = 0.0; double _Thumbsize = 20; double lightness; double _colorwidth; double _colorHeight; Color _color; _BarTypeColorPickerState(double colorwidth, double colorHeight) { this._colorwidth = colorwidth; this._colorHeight = colorHeight; } @override void initState() { super.initState(); } @override Widget build(BuildContext context) { return Center( child: GestureDetector( onPanStart: (DragStartDetails detail) { var localPosition = detail.localPosition; buildSetState(localPosition, context); if (widget.colorListener != null) { widget.colorListener(_color); } }, onPanDown: (DragDownDetails detail) { var localPosition = detail.localPosition; buildSetState(localPosition, context); if (widget.colorListener != null) { widget.colorListener(_color); } }, onPanUpdate: (DragUpdateDetails detail) { var localPosition = detail.localPosition; buildSetState(localPosition, context); if (widget.colorListener != null) { widget.colorListener(_color); } }, onPanEnd: (DragEndDetails detail) { if (widget.onTapUpListener != null) { widget.onTapUpListener(_color); } }, onTapUp: (TapUpDetails detail) { if (widget.onTapUpListener != null) { widget.onTapUpListener(_color); } }, child: ColorRect( colorHeight: _colorHeight, colorwidth: _colorwidth, top: _top, Thumbsize: _Thumbsize, left: _left, color: _color), ), ); } void buildSetState(Offset localPosition, BuildContext context) { return setState(() { _left = localPosition.dx; _top = localPosition.dy; if (_left < 0) { _left = 0; } else if (0 <= _left && _left <= _colorwidth) { _left = _left; } else if (_left > _colorwidth) { _left = (_colorwidth); } if ((_colorwidth / 7) * 0 < _left && _left < (_colorwidth / 7) * 1) { _color = Color(0xFFFF0000); } else if ((_colorwidth / 7) * 1 < _left && _left < (_colorwidth / 7) * 2) { _color = Color(0xFFFFFF00); } else if ((_colorwidth / 7) * 2 < _left && _left < (_colorwidth / 7) * 3) { _color = Color(0xFF00FF00); } else if ((_colorwidth / 7) * 3 < _left && _left < (_colorwidth / 7) * 4) { _color = Color(0xFF00FFFF); } else if ((_colorwidth / 7) * 4 < _left && _left < (_colorwidth / 7) * 5) { _color = Color(0xFF0000FF); } else if ((_colorwidth / 7) * 5 < _left && _left < (_colorwidth / 7) * 6) { _color = Color(0xFFFF00FF); } else if ((_colorwidth / 7) * 6 < _left && _left < (_colorwidth / 7) * 7) { _color = Color(0xFFFFFFFF); } if (_top <= 0) { _top = 0; } else if (0 <= _top && _top <= _colorHeight) { } else if (_top > _colorHeight) { _top = _colorHeight; } }); } } class ColorRect extends StatelessWidget { ColorRect({ Key key, @required double colorHeight, @required double colorwidth, @required double top, @required double Thumbsize, @required double left, @required Color color, }) : _colorHeight = colorHeight, _colorwidth = colorwidth, _top = top, _Thumbsize = Thumbsize, _left = left, _color = color, super(key: key); final double _colorHeight; final double _colorwidth; final double _top; final double _Thumbsize; final double _left; final Color _color; List<Color> colorList = [ Color(0xFFFF0000), Color(0xFFFFFF00), Color(0xFF00FF00), Color(0xFF00FFFF), Color(0xFF0000FF), Color(0xFFFF00FF), Color(0xFFFFFFFF), ]; @override Widget build(BuildContext context) { return Container( width: _colorwidth, height: _colorHeight, child: Stack( children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: colorList .map( (e) => Container( padding: EdgeInsets.symmetric(horizontal: 2), height: _colorHeight, width: _colorwidth / 7, child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: e, ), ), ), ) .toList(), ), Container( child: Thumb( top: _top, Thumbsize: _Thumbsize, left: _left, color: _color)), ], ), ); } } class Thumb extends StatelessWidget { const Thumb({ Key key, @required double top, @required double Thumbsize, @required double left, @required Color color, }) : _top = top, _Thumbsize = Thumbsize, _left = left, _color = color, super(key: key); final double _top; final double _Thumbsize; final double _left; final Color _color; @override Widget build(BuildContext context) { return Positioned( top: _top - _Thumbsize / 2, left: _left - _Thumbsize / 2, child: GestureDetector( child: Container( child: Icon( Icons.circle, color: _color, size: _Thumbsize, ), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), boxShadow: [ BoxShadow( blurRadius: 0.1, //阴影范围 spreadRadius: 0.001, //阴影浓度 color: Colors.black, //阴影颜色 ), ], ), ))); } }
下面是使用方法。
BarTypeColorPicker( initialColor: Colors.white, colorWidth: 360, colorHeight: 150, ),
具体效果图:
一、RectangleColorPicker
矩形选色板的功能实现,颜色的获取是通过位置的坐标值转换为相应的颜色。这个封装好的组件可通过colorListener、onTapUpListener的回调方法,把颜色传出去。
代码如下(示例):
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class RectangleColorPicker extends StatefulWidget { final Color initialColor; final ValueChanged<Color> colorListener; final ValueChanged<Color> onTapUpListener; final int colorWidth; final int colorHeight; final Color color; const RectangleColorPicker( {Key key, this.initialColor, this.colorListener, this.onTapUpListener, this.colorWidth, this.colorHeight, this.color}) : super(key: key); @override _RectangleColorPickerState createState() => _RectangleColorPickerState( colorWidth.toDouble(), colorHeight.toDouble(), ); } class _RectangleColorPickerState extends State<RectangleColorPicker> { double _top = 0.0; double _left = 0.0; double _Thumbsize = 20; double _hue = 0.0; double _brightnum = 50.0; double lightness; double _colorwidth; double _colorHeight; _RectangleColorPickerState(double colorwidth, double colorHeight) { this._colorwidth = colorwidth; this._colorHeight = colorHeight; } Color get _color { return HSLColor.fromAHSL( 1, _hue, 1, lightness, ).toColor(); //返回HSL、AHSL格式的色调亮度字符串 } @override void initState() { super.initState(); HSLColor hslColor = HSLColor.fromColor(widget.initialColor); _left = (_colorwidth * hslColor.hue) / 360; _top = (_colorHeight * (hslColor.lightness - 0.5) * 200) / 100; this._hue = hslColor.hue; this.lightness = hslColor.lightness; } @override Widget build(BuildContext context) { return Center( child: GestureDetector( onPanStart: (DragStartDetails detail) { var localPosition = detail.localPosition; buildSetState(localPosition, context); if(widget.colorListener != null){ widget.colorListener(_color); } }, onPanDown: (DragDownDetails detail) { var localPosition = detail.localPosition; buildSetState(localPosition, context); if(widget.colorListener != null){ widget.colorListener(_color); } }, onPanUpdate: (DragUpdateDetails detail) { //获取当前触摸点的局部坐标 var localPosition = detail.localPosition; buildSetState(localPosition, context); if(widget.colorListener != null){ widget.colorListener(_color); } }, onPanEnd: (DragEndDetails detail) { if(widget.onTapUpListener != null){ widget.onTapUpListener(_color); } }, onTapUp: (TapUpDetails detail){ if(widget.onTapUpListener != null){ widget.onTapUpListener(_color); } }, child: ColorRect( colorHeight: _colorHeight, colorwidth: _colorwidth, top: _top, Thumbsize: _Thumbsize, left: _left, color: _color), ), ); } void buildSetState(Offset localPosition, BuildContext context) { return setState(() { _left = localPosition.dx; _top = localPosition.dy; if (_left < 0) { _left = 0; } else if (0 <= _left && _left <= _colorwidth) { _left = _left; _hue = (360 * _left) / (_colorwidth); } else if (_left > _colorwidth) { _left = (_colorwidth); _hue = 360; } if (((5 / 360 - 5 / 360) < _left && _left < (5 / 360 + 5 / 360) * _colorwidth) && (_top < 5)) { _left = 5 / 360 * _colorwidth; _top = 0; } else if ((((5 + 350 / 6) / 360 - 5 / 360) * _colorwidth < _left && _left < ((5 + 350 / 6) / 360 + 5 / 360) * _colorwidth) && (_top < 5)) { _left = (5 + (1 * 350) / 6) / 360 * _colorwidth; _top = 0; } else if ((((5 + (2 * 350) / 6) / 360 - 5 / 360) * _colorwidth < _left && _left < ((5 + (2 * 350) / 6) / 360 + 5 / 360) * _colorwidth) && (_top < 5)) { _left = (5 + (2 * 350) / 6) / 360 * _colorwidth; _top = 0; } else if ((((5 + (3 * 350) / 6) / 360 - 5 / 360) * _colorwidth < _left && _left < ((5 + (3 * 350) / 6) / 360 + 5 / 360) * _colorwidth) && (_top < 5)) { _left = (5 + (3 * 350) / 6) / 360 * _colorwidth; _top = 0; } else if ((((5 + (4 * 350) / 6) / 360 - 5 / 360) * _colorwidth < _left && _left < ((5 + (4 * 350) / 6) / 360 + 5 / 360) * _colorwidth) && (_top < 5)) { _left = (5 + (4 * 350) / 6) / 360 * _colorwidth; _top = 0; } else if ((((5 + (5 * 350) / 6) / 360 - 5 / 360) * _colorwidth < _left && _left < ((5 + (5 * 350) / 6) / 360 + 5 / 360) * _colorwidth) && (_top < 5)) { _left = (5 + (5 * 350) / 6) / 360 * _colorwidth; _top = 0; } else if ((((5 + (6 * 350) / 6) / 360 - 5 / 360) * _colorwidth < _left && _left < ((5 + (6 * 350) / 6) / 360 + 5 / 360)) && (_top < 5)) { _left = (5 + (6 * 350) / 6) / 360 * _colorwidth; _top = 0; } if (_top <= 0) { _top = 0; _brightnum = 50; lightness = _brightnum / 100; } else if (0 <= _top && _top <= _colorHeight) { _brightnum = (100 * _top) / _colorHeight / 2 + 50; lightness = _brightnum / 100; } else if (_top > _colorHeight) { _top = _colorHeight; _brightnum = 100; lightness = _brightnum / 100; } }); } } class ColorRect extends StatelessWidget { const ColorRect({ Key key, @required double colorHeight, @required double colorwidth, @required double top, @required double Thumbsize, @required double left, @required Color color, }) : _colorHeight = colorHeight, _colorwidth = colorwidth, _top = top, _Thumbsize = Thumbsize, _left = left, _color = color, super(key: key); final double _colorHeight; final double _colorwidth; final double _top; final double _Thumbsize; final double _left; final Color _color; @override Widget build(BuildContext context) { return Container( child: Stack( children: [ Container( child: ClipRRect( borderRadius: BorderRadius.circular(10), child: DecoratedBox( child: Container( height: _colorHeight, width: _colorwidth, ), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.centerLeft, end: Alignment.centerRight, stops: [ 0, 5 / 360, (5 + 350 / 6) / 360, (5 + (2 * 350) / 6) / 360, (5 + (3 * 350) / 6) / 360, (5 + (4 * 350) / 6) / 360, (5 + (5 * 350) / 6) / 360, (5 + (6 * 350) / 6) / 360, 1.0 ], colors: [ Color.fromARGB(255, 255, 0, 0), Color.fromARGB(255, 255, 0, 0), Color.fromARGB(255, 255, 255, 0), Color.fromARGB(255, 0, 255, 0), Color.fromARGB(255, 0, 255, 255), Color.fromARGB(255, 0, 0, 255), Color.fromARGB(255, 255, 0, 255), Color.fromARGB(255, 255, 0, 0), Color.fromARGB(255, 255, 0, 0), ], ), )), ), ), Container( child: ClipRRect( borderRadius: BorderRadius.circular(10), child: DecoratedBox( child: Container( height: _colorHeight, width: _colorwidth, ), decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color.fromARGB(0, 255, 255, 255), Colors.white, ], ), )), ), ), Container( child: Thumb( top: _top, Thumbsize: _Thumbsize, left: _left, color: _color)), ], ), ); } } class Thumb extends StatelessWidget { const Thumb({ Key key, @required double top, @required double Thumbsize, @required double left, @required Color color, }) : _top = top, _Thumbsize = Thumbsize, _left = left, _color = color, super(key: key); final double _top; final double _Thumbsize; final double _left; final Color _color; @override Widget build(BuildContext context) { return Positioned( top: _top - _Thumbsize / 2, left: _left - _Thumbsize / 2, child: GestureDetector( child: Container( child: Icon( Icons.circle, color: _color, size: _Thumbsize, ), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), boxShadow: [ BoxShadow( blurRadius: 0.1, //阴影范围 spreadRadius: 0.001, //阴影浓度 color: Colors.black, //阴影颜色 ), ], ), ))); } }
下面是使用方法。
RectangleColorPicker( [initialColor: Colors.white, colorWidth: 360, colorHeight: 150, onTapUpListener: (_color) { } colorListener: (_color) { } ] ),
具体效果图:
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了两种颜色选色板的使用,后面还会陆续发布一些flutter的组件使用教程。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
赞 (0)