如何在 flutter 中构建手绘边框线或框?
How to build hand-drawn border line or boxes in flutter?
我如何建立如下图所示的徒手边框线?
想实现这个形象:
但我只知道构建简单的 straight/rounded 边框,
像这样:
代码:
// CORNER ROUNDED BORDER DROP DOWN:
_buildDropDownField() {
return Container(
padding: const EdgeInsets.only(left: 8, right: 8),
alignment: Alignment.center,
height: 60,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: Colors.black),
// color:Colors.white,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
selectedTopic == null
? Text(
"Select Topic",
style: TextStyle(
color: Colors.black),
)
: Text(
selectedTopic.title,
style: TextStyle(
color:
Colors.black,
),
),
DropdownButton<TopicModel>(
underline: Container(),
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_drop_down),
items: TOPICS.map((TopicModel value) {
return new DropdownMenuItem<TopicModel>(
value: value,
child: new Text(
value.title,
style: TextStyle(color: Colors.black),
),
);
}).toList(),
onChanged: (val) {
setState(() {
selectedTopic = val;
});
},
)
],
),
);
}
//CORNER ROUNDED BORDER TEXT FIELD:
new TextFormField(
controller: _option1Controller,
decoration: new InputDecoration(
// suffixText: "2",
border: new OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
),
filled: true,
hintStyle: new TextStyle(color: Colors.grey[800]),
hintText: "Option 1",
labelText: "Option 1",
fillColor: Colors.white70),
validator: (value) {
if (value.isEmpty) {
return 'Can\'t not be empty';
}
return null;
},
),
我认为 CustomPainter
可以做到这一点。但只知道画一些形状,比如环形、圆形、直线、正方形、长方形。
自定义画家直线:
class DrawCustomShape extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
var paint = Paint();
paint.color = Colors.red;
paint.strokeWidth = 5;
canvas.drawLine(
Offset(0, size.height / 2),
Offset(size.width, size.height / 2),
paint,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
Circle With Custom painter:
class DrawCustomShape extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
var paint = Paint();
paint.color = Colors.amber;
paint.strokeWidth = 5;
paint.color = Colors.blue;
paint.style = PaintingStyle.stroke;
canvas.drawCircle(Offset(size.width/2, size.height/2), size.width/4, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
我找到了把我们的手绘图canvas转成dart代码的工具(Flutter Shape Maker),真是太棒了
示例代码:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Sample(),
);
}
}
class Sample extends StatefulWidget {
@override
_SampleState createState() => _SampleState();
}
class _SampleState extends State<Sample> {
TextEditingController controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text(
"Custom painter",
),
centerTitle: true,
),
body: Center(
child: Container(
padding:const EdgeInsets.all(
10
) ,
width: MediaQuery.of(context).size.width,
child: CustomPaint(
size: Size(
MediaQuery.of(context).size.width,
(MediaQuery.of(context).size.width * 0.1111111111111111)
.toDouble()),
painter: RPSCustomPainter(),
child: Container(
padding: const EdgeInsets.only(
left: 10,
right: 10,
),
child: TextField(
controller: controller,
decoration: InputDecoration(
hintText: "type", border: InputBorder.none),
),
),
),
),
));
}
}
class RPSCustomPainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
Paint paint_0 = new Paint()
..color = Color.fromARGB(255, 33, 150, 243)
..style = PaintingStyle.stroke
..strokeWidth = 2;
Path path_0 = Path();
path_0.moveTo(size.width*0.0022222,size.height*0.0400000);
path_0.lineTo(size.width*0.0055556,size.height*0.0400000);
path_0.lineTo(size.width*0.1455556,size.height*0.0500000);
path_0.lineTo(size.width*0.2800000,size.height*0.0700000);
path_0.lineTo(size.width*0.4211111,size.height*0.0300000);
path_0.lineTo(size.width*0.5455556,size.height*0.0500000);
path_0.lineTo(size.width*0.6611111,size.height*0.0600000);
path_0.lineTo(size.width*0.7911111,size.height*0.0600000);
path_0.lineTo(size.width*0.9077778,size.height*0.0700000);
path_0.lineTo(size.width*0.9744444,size.height*0.0500000);
path_0.lineTo(size.width*0.9933333,size.height*0.0700000);
path_0.lineTo(size.width*0.9977778,size.height*0.9300000);
path_0.lineTo(size.width*0.8611111,size.height*0.9400000);
path_0.lineTo(size.width*0.7266667,size.height*0.9500000);
path_0.lineTo(size.width*0.4844444,size.height*0.9500000);
path_0.lineTo(size.width*0.2955556,size.height*0.9600000);
path_0.lineTo(size.width*0.1344444,size.height*0.9600000);
path_0.lineTo(size.width*0.0033333,size.height*0.9400000);
path_0.lineTo(size.width*0.0077778,size.height*0.5200000);
path_0.lineTo(size.width*0.0022222,size.height*0.0600000);
canvas.drawPath(path_0, paint_0);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
输出:
给你测试dartPad。
说真的,真的很棒:)
我如何建立如下图所示的徒手边框线?
想实现这个形象:
但我只知道构建简单的 straight/rounded 边框,
像这样:
代码:
// CORNER ROUNDED BORDER DROP DOWN:
_buildDropDownField() {
return Container(
padding: const EdgeInsets.only(left: 8, right: 8),
alignment: Alignment.center,
height: 60,
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(
color: Colors.black),
// color:Colors.white,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
selectedTopic == null
? Text(
"Select Topic",
style: TextStyle(
color: Colors.black),
)
: Text(
selectedTopic.title,
style: TextStyle(
color:
Colors.black,
),
),
DropdownButton<TopicModel>(
underline: Container(),
dropdownColor: Colors.white,
icon: Icon(Icons.arrow_drop_down),
items: TOPICS.map((TopicModel value) {
return new DropdownMenuItem<TopicModel>(
value: value,
child: new Text(
value.title,
style: TextStyle(color: Colors.black),
),
);
}).toList(),
onChanged: (val) {
setState(() {
selectedTopic = val;
});
},
)
],
),
);
}
//CORNER ROUNDED BORDER TEXT FIELD:
new TextFormField(
controller: _option1Controller,
decoration: new InputDecoration(
// suffixText: "2",
border: new OutlineInputBorder(
borderRadius: const BorderRadius.all(
const Radius.circular(10.0),
),
),
filled: true,
hintStyle: new TextStyle(color: Colors.grey[800]),
hintText: "Option 1",
labelText: "Option 1",
fillColor: Colors.white70),
validator: (value) {
if (value.isEmpty) {
return 'Can\'t not be empty';
}
return null;
},
),
我认为 CustomPainter
可以做到这一点。但只知道画一些形状,比如环形、圆形、直线、正方形、长方形。
自定义画家直线:
class DrawCustomShape extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
var paint = Paint();
paint.color = Colors.red;
paint.strokeWidth = 5;
canvas.drawLine(
Offset(0, size.height / 2),
Offset(size.width, size.height / 2),
paint,
);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
Circle With Custom painter:
class DrawCustomShape extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
var paint = Paint();
paint.color = Colors.amber;
paint.strokeWidth = 5;
paint.color = Colors.blue;
paint.style = PaintingStyle.stroke;
canvas.drawCircle(Offset(size.width/2, size.height/2), size.width/4, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
我找到了把我们的手绘图canvas转成dart代码的工具(Flutter Shape Maker),真是太棒了
示例代码:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Sample(),
);
}
}
class Sample extends StatefulWidget {
@override
_SampleState createState() => _SampleState();
}
class _SampleState extends State<Sample> {
TextEditingController controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text(
"Custom painter",
),
centerTitle: true,
),
body: Center(
child: Container(
padding:const EdgeInsets.all(
10
) ,
width: MediaQuery.of(context).size.width,
child: CustomPaint(
size: Size(
MediaQuery.of(context).size.width,
(MediaQuery.of(context).size.width * 0.1111111111111111)
.toDouble()),
painter: RPSCustomPainter(),
child: Container(
padding: const EdgeInsets.only(
left: 10,
right: 10,
),
child: TextField(
controller: controller,
decoration: InputDecoration(
hintText: "type", border: InputBorder.none),
),
),
),
),
));
}
}
class RPSCustomPainter extends CustomPainter{
@override
void paint(Canvas canvas, Size size) {
Paint paint_0 = new Paint()
..color = Color.fromARGB(255, 33, 150, 243)
..style = PaintingStyle.stroke
..strokeWidth = 2;
Path path_0 = Path();
path_0.moveTo(size.width*0.0022222,size.height*0.0400000);
path_0.lineTo(size.width*0.0055556,size.height*0.0400000);
path_0.lineTo(size.width*0.1455556,size.height*0.0500000);
path_0.lineTo(size.width*0.2800000,size.height*0.0700000);
path_0.lineTo(size.width*0.4211111,size.height*0.0300000);
path_0.lineTo(size.width*0.5455556,size.height*0.0500000);
path_0.lineTo(size.width*0.6611111,size.height*0.0600000);
path_0.lineTo(size.width*0.7911111,size.height*0.0600000);
path_0.lineTo(size.width*0.9077778,size.height*0.0700000);
path_0.lineTo(size.width*0.9744444,size.height*0.0500000);
path_0.lineTo(size.width*0.9933333,size.height*0.0700000);
path_0.lineTo(size.width*0.9977778,size.height*0.9300000);
path_0.lineTo(size.width*0.8611111,size.height*0.9400000);
path_0.lineTo(size.width*0.7266667,size.height*0.9500000);
path_0.lineTo(size.width*0.4844444,size.height*0.9500000);
path_0.lineTo(size.width*0.2955556,size.height*0.9600000);
path_0.lineTo(size.width*0.1344444,size.height*0.9600000);
path_0.lineTo(size.width*0.0033333,size.height*0.9400000);
path_0.lineTo(size.width*0.0077778,size.height*0.5200000);
path_0.lineTo(size.width*0.0022222,size.height*0.0600000);
canvas.drawPath(path_0, paint_0);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
输出:
给你测试dartPad。
说真的,真的很棒:)