帮助,我正在尝试创建一个类似image of what I want here
的半圆形菜单但是我不知道如何将小部件放置在较大的白线上方...我尝试使用以下代码。请将该小部件用作main.dart中的主页小部件,然后查看结果。我已经在包pub中使用了font_awesome_flutter包作为图标:-
image of how it is currently here
import 'package:flutter/material.dart';
import 'dart:math';
import 'package:vector_math/vector_math.dart' show radians, Vector3;
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
class Homewidgettoslack extends StatefulWidget {
Homewidgettoslack({
Key key,
}) : super(key: key);
@override
_HomewidgettoslackState createState() => _HomewidgettoslackState();
}
class _HomewidgettoslackState extends State<Homewidgettoslack> with TickerProviderStateMixin {
Animation<double> rotation;
Animation<double> translation;
Animation<double> menuscale;
AnimationController menuController;
@override
void initState() {
super.initState();
menuController =
AnimationController(duration: Duration(milliseconds: 900), vsync: this);
rotation = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(
CurvedAnimation(
parent: menuController,
curve: Interval(
0.0,
0.7,
curve: Curves.decelerate,
),
),
);
translation = Tween<double>(
begin: 0.0,
end: 100.0,
).animate(
CurvedAnimation(parent: menuController, curve: Curves.elasticOut),
);
menuscale = Tween<double>(
begin: 1.5,
end: 0.0,
).animate(
CurvedAnimation(parent: menuController, curve: Curves.fastOutSlowIn),
);
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.blueGrey,
child: Scaffold(
backgroundColor: Colors.transparent,
body: Stack(
children: <Widget>[
Positioned(
left: -27,
right: -27,
top: 57,
bottom: 57,
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: CustomPaint(
painter: CurvedblacklinePainter(),
),
),
),
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: CustomPaint(
painter: CurvedblacklinePainter(),
),
),
Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: AnimatedBuilder(
animation: menuController,
builder: (context, widget) {
return Transform.rotate(
angle: radians(rotation.value),
child:
Stack(alignment: Alignment.center, children: <Widget>[
_buildButton(0,
color: Colors.red, icon: FontAwesomeIcons.thumbtack),
_buildButton(45,
color: Colors.green, icon: FontAwesomeIcons.sprayCan),
_buildButton(90,
color: Colors.orange, icon: FontAwesomeIcons.fire),
_buildButton(270,
color: Colors.pink, icon: FontAwesomeIcons.car),
_buildButton(315,
color: Colors.yellow, icon: FontAwesomeIcons.bolt),
Transform.scale(
scale: menuscale.value - 1,
child: FloatingActionButton(
child: Icon(FontAwesomeIcons.timesCircle),
onPressed: _close,
backgroundColor: Colors.red),
),
Transform.scale(
scale: menuscale.value,
child: FloatingActionButton(
child: Icon(
FontAwesomeIcons.solidDotCircle,
color: Colors.red,
),
onPressed: _open),
)
]),
);
},
),
),
],
),
),
);
}
_buildButton(double angle, {Color color, IconData icon}) {
final double rad = radians(angle);
return Transform(
transform: Matrix4.identity()
..translate(
(translation.value) * cos(rad), (translation.value) * sin(rad)),
child: FloatingActionButton(
child: Icon(icon),
backgroundColor: color,
onPressed: _close,
elevation: 0));
}
_open() {
print('OPEN CLICKED');
menuController.forward();
}
_close() {
print('CLOSE CLICKED');
menuController.reverse();
}
}
class CurvedblacklinePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
Paint paint = new Paint()
..color = Colors.white
..strokeWidth = 1.8
..style = PaintingStyle.stroke;
Path path = Path();
path.moveTo(0, 0);
var secondEndPoint = Offset(0, size.height);
path.arcToPoint(secondEndPoint,
radius: Radius.circular((size.width / 2)),
clockwise: true,
largeArc: false);
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
答案 0 :(得分:1)
我改进了您的代码,并按如下所示进行了修复,
请用您的代码替换我的代码
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:vector_math/vector_math.dart' show radians, Vector3;
class Homewidgettoslack extends StatefulWidget {
Homewidgettoslack({
Key key,
}) : super(key: key);
@override
_HomewidgettoslackState createState() => _HomewidgettoslackState();
}
class _HomewidgettoslackState extends State<Homewidgettoslack>
with TickerProviderStateMixin {
Animation<double> rotation;
Animation<double> translationY;
Animation<double> translationX;
Animation<double> menuscale;
AnimationController menuController;
double _menuIconSize;
@override
void initState() {
super.initState();
menuController =
AnimationController(duration: Duration(milliseconds: 900), vsync: this);
rotation = Tween<double>(
begin: 0.0,
end: 1.0,
).animate(
CurvedAnimation(
parent: menuController,
curve: Interval(
0.0,
0.7,
curve: Curves.decelerate,
),
),
);
menuscale = Tween<double>(
begin: 1.5,
end: 0.0,
).animate(
CurvedAnimation(parent: menuController, curve: Curves.fastOutSlowIn),
);
}
@override
Widget build(BuildContext context) {
ScreenUtil.init(width: 360, height: 640, allowFontScaling: false);
_menuIconSize = ScreenUtil().setWidth(60);
double _bigCurveHeight = ScreenUtil().setHeight(520);
double _bigCurveWidth = ScreenUtil().setWidth(250);
translationY = Tween<double>(
begin: 0.0,
end: ((_bigCurveHeight / 2) - (_menuIconSize / 2)),
).animate(
CurvedAnimation(parent: menuController, curve: Curves.elasticOut),
);
translationX = Tween<double>(
begin: 0.0,
end: (_bigCurveWidth - (_menuIconSize / 2)),
).animate(
CurvedAnimation(parent: menuController, curve: Curves.elasticOut),
);
return Container(
color: Colors.blueGrey,
child: Scaffold(
backgroundColor: Colors.transparent,
body: Align(
alignment: Alignment.centerLeft,
child: Stack(
alignment: Alignment.centerLeft,
children: <Widget>[
Container(
height: _bigCurveHeight,
width: _bigCurveWidth,
child: CustomPaint(
painter: CurvedblacklinePainter(strokeWidth: 2),
),
),
Container(
height: ScreenUtil().setHeight(350),
width: ScreenUtil().setWidth(130),
child: CustomPaint(
painter: CurvedblacklinePainter(
strokeWidth: ScreenUtil().setWidth(60)),
),
),
Container(
child: AnimatedBuilder(
animation: menuController,
builder: (context, widget) {
return Transform.rotate(
angle: radians(rotation.value),
child:
Stack(alignment: Alignment.center, children: <Widget>[
_buildButton(0,
color: Colors.red,
icon: FontAwesomeIcons.thumbtack),
_buildButton(45,
color: Colors.green,
icon: FontAwesomeIcons.sprayCan),
_buildButton(90,
color: Colors.orange, icon: FontAwesomeIcons.fire),
_buildButton(270,
color: Colors.pink, icon: FontAwesomeIcons.car),
_buildButton(315,
color: Colors.yellow, icon: FontAwesomeIcons.bolt),
Transform.scale(
scale: menuscale.value - 1,
child: FloatingActionButton(
child: Icon(FontAwesomeIcons.timesCircle),
onPressed: _close,
backgroundColor: Colors.red),
),
Transform.scale(
scale: menuscale.value,
child: FloatingActionButton(
child: Icon(
FontAwesomeIcons.solidDotCircle,
color: Colors.red,
),
onPressed: _open),
)
]),
);
},
),
),
],
),
),
),
);
}
_buildButton(double angle, {Color color, IconData icon}) {
final double rad = radians(angle);
return Transform(
transform: Matrix4.identity()
..translate(
(translationX.value) * cos(rad), (translationY.value) * sin(rad)),
child: FloatingActionButton(
child: Icon(icon),
backgroundColor: color,
onPressed: _close,
elevation: 0));
}
_open() {
print('OPEN CLICKED');
menuController.forward();
}
_close() {
print('CLOSE CLICKED');
menuController.reverse();
}
}
class CurvedblacklinePainter extends CustomPainter {
final double strokeWidth;
CurvedblacklinePainter({@required this.strokeWidth});
@override
void paint(Canvas canvas, Size size) {
Paint paint = new Paint()
..color = Colors.white
..strokeWidth = strokeWidth
..style = PaintingStyle.stroke;
canvas.drawOval(
Rect.fromCenter(
center: Offset(-size.width / 2, size.height / 2),
width: size.width * 3,
height: size.height),
paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
,然后在pubspec.yaml中添加依赖项:
dev_dependencies:
flutter_test:
sdk: flutter
font_awesome_flutter: ^8.8.1
flutter_screenutil: ^2.1.0
结果屏幕截图: