可扩展的浮动操作按钮(使用 Stack)无法正常工作
Expandable floating action button (using Stack) not working in flutter
这是我的 dart 文件,我想在其中创建一个包裹在 Stack 小部件中的可扩展浮动按钮,并且当我尝试在其中提供 onTap/onPressed 手势时,我为可扩展 FAB 创建了一个名为 CircularButton 的自定义 IconButton GestureDetector 小部件或我的 CircularButton 自定义小部件它没有任何错误,并且在按下图标时它不会打开相应的应用程序。我尝试更改 return 类型的 customLaunch,但这也没有用。
感谢任何帮助。
谢谢,
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
void customLaunch(command) async {
if (await canLaunch(command)) {
await launch(command);
} else {
print(' could not launch $command');
}
}
AnimationController animationController;
Animation degOneTranslationAnimation,
degTwoTranslationAnimation,
degThreeTranslationAnimation;
Animation rotationAnimation;
double getRadiansFromDegree(double degree) {
double unitRadian = 57.295779513;
return degree / unitRadian;
}
@override
void initState() {
animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 600));
degOneTranslationAnimation = TweenSequence(<TweenSequenceItem>[
TweenSequenceItem<double>(
tween: Tween<double>(begin: 0.0, end: 1.2), weight: 75.0),
TweenSequenceItem<double>(
tween: Tween<double>(begin: 1.2, end: 1.0), weight: 25.0),
]).animate(animationController);
degTwoTranslationAnimation = TweenSequence(<TweenSequenceItem>[
TweenSequenceItem<double>(
tween: Tween<double>(begin: 0.0, end: 1.4), weight: 55.0),
TweenSequenceItem<double>(
tween: Tween<double>(begin: 1.4, end: 1.0), weight: 45.0)
]).animate(animationController);
degThreeTranslationAnimation = TweenSequence(<TweenSequenceItem>[
TweenSequenceItem<double>(
tween: Tween<double>(begin: 0.0, end: 1.75), weight: 35.0),
TweenSequenceItem<double>(
tween: Tween<double>(begin: 1.75, end: 1.0), weight: 65.0)
]).animate(animationController);
rotationAnimation = Tween<double>(begin: 180.0, end: 0.0).animate(
CurvedAnimation(parent: animationController, curve: Curves.easeOut));
super.initState();
animationController.addListener(() {
setState(() {});
});
}
@override
void dispose() {
animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 5,
child: Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
floatingActionButton: Stack(
children: [
Transform.translate(
offset: Offset.fromDirection(getRadiansFromDegree(270),
degOneTranslationAnimation.value * 100),
child: Transform(
transform: Matrix4.rotationZ(
getRadiansFromDegree(rotationAnimation.value))
..scale(degOneTranslationAnimation.value),
alignment: Alignment.center,
child: Container(
decoration: BoxDecoration(
color: Colors.black, shape: BoxShape.circle),
width: 50,
height: 50,
child: IconButton(
icon: Icon(Icons.repeat, color: Colors.white),
enableFeedback: true,
onPressed: () => customLaunch('https:google.com')),
),
),
),
Transform.translate(
offset: Offset.fromDirection(getRadiansFromDegree(225),
degOneTranslationAnimation.value * 100),
child: Transform(
transform: Matrix4.rotationZ(
getRadiansFromDegree(rotationAnimation.value))
..scale(degOneTranslationAnimation.value),
alignment: Alignment.center,
child: Container(
decoration: BoxDecoration(
color: Colors.black, shape: BoxShape.circle),
width: 50,
height: 50,
child: GestureDetector(
onTap: () => customLaunch('sms:546456464'),
child: IconButton(
icon: Icon(Icons.chat, color: Colors.white),
enableFeedback: true,
onPressed: () => {},
),
)),
),
),
Transform.translate(
offset: Offset.fromDirection(getRadiansFromDegree(180),
degOneTranslationAnimation.value * 100),
child: Transform(
transform: Matrix4.rotationZ(
getRadiansFromDegree(rotationAnimation.value))
..scale(degOneTranslationAnimation.value),
alignment: Alignment.center,
child: CircularButton(
onPressed: () => customLaunch('tel:+91 9478946545'),
color: Colors.black,
width: 50,
height: 50,
icon: Icon(
Icons.call,
color: Colors.white,
),
),
),
),
Transform(
transform: Matrix4.rotationZ(
getRadiansFromDegree(rotationAnimation.value)),
alignment: Alignment.center,
child: CircularButton(
color: Colors.black,
width: 60,
height: 60,
icon: Icon(
Icons.menu,
color: Colors.white,
),
onPressed: () {
if (animationController.isCompleted) {
animationController.reverse();
} else {
animationController.forward();
}
},
),
),
],
),
}
class CircularButton extends StatelessWidget {
final double width;
final double height;
final Color color;
final Icon icon;
final dynamic onPressed;
CircularButton({this.color, this.width, this.height, this.icon, this.onPressed});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
width: width,
height: height,
child: IconButton(icon: icon, enableFeedback: true, onPressed: onPressed),
);
}
}
我只想打开其他应用程序 onTap of expanded floating buttons 但它没有打开,虽然代码没有错误但仍然无法正常工作。
它不仅需要 onpressed 参数或 onTap。
我只需要将这个 IgnorePointer 添加到堆栈中,以便它检测手势并忽略该特定区域的动画
我更改的代码是
floatingActionButton: Stack(
children: <Widget>[
Positioned(
right: 30,
bottom: 30,
child: Stack(
alignment: Alignment.bottomRight,
children: <Widget>[
IgnorePointer( // this edit made it worked
child: Container(
color: Colors.transparent,
height: 150.0,
width: 150.0,
),
),
Transform.translate(
offset: Offset.fromDirection(getRadiansFromDegree(270),
degOneTranslationAnimation.value * 100),
child: Transform(
transform: Matrix4.rotationZ(
getRadiansFromDegree(rotationAnimation.value))
..scale(degOneTranslationAnimation.value),
alignment: Alignment.center,
child: CircularButton(
onClick: () => customLaunch('www.cigarettewala.com'),
color: Colors.black,
width: 50,
height: 50,
icon: Icon(
Icons.repeat,
color: Colors.white,
),
),
),
),
这是我的 dart 文件,我想在其中创建一个包裹在 Stack 小部件中的可扩展浮动按钮,并且当我尝试在其中提供 onTap/onPressed 手势时,我为可扩展 FAB 创建了一个名为 CircularButton 的自定义 IconButton GestureDetector 小部件或我的 CircularButton 自定义小部件它没有任何错误,并且在按下图标时它不会打开相应的应用程序。我尝试更改 return 类型的 customLaunch,但这也没有用。
感谢任何帮助。 谢谢,
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
void customLaunch(command) async {
if (await canLaunch(command)) {
await launch(command);
} else {
print(' could not launch $command');
}
}
AnimationController animationController;
Animation degOneTranslationAnimation,
degTwoTranslationAnimation,
degThreeTranslationAnimation;
Animation rotationAnimation;
double getRadiansFromDegree(double degree) {
double unitRadian = 57.295779513;
return degree / unitRadian;
}
@override
void initState() {
animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 600));
degOneTranslationAnimation = TweenSequence(<TweenSequenceItem>[
TweenSequenceItem<double>(
tween: Tween<double>(begin: 0.0, end: 1.2), weight: 75.0),
TweenSequenceItem<double>(
tween: Tween<double>(begin: 1.2, end: 1.0), weight: 25.0),
]).animate(animationController);
degTwoTranslationAnimation = TweenSequence(<TweenSequenceItem>[
TweenSequenceItem<double>(
tween: Tween<double>(begin: 0.0, end: 1.4), weight: 55.0),
TweenSequenceItem<double>(
tween: Tween<double>(begin: 1.4, end: 1.0), weight: 45.0)
]).animate(animationController);
degThreeTranslationAnimation = TweenSequence(<TweenSequenceItem>[
TweenSequenceItem<double>(
tween: Tween<double>(begin: 0.0, end: 1.75), weight: 35.0),
TweenSequenceItem<double>(
tween: Tween<double>(begin: 1.75, end: 1.0), weight: 65.0)
]).animate(animationController);
rotationAnimation = Tween<double>(begin: 180.0, end: 0.0).animate(
CurvedAnimation(parent: animationController, curve: Curves.easeOut));
super.initState();
animationController.addListener(() {
setState(() {});
});
}
@override
void dispose() {
animationController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 5,
child: Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat,
floatingActionButton: Stack(
children: [
Transform.translate(
offset: Offset.fromDirection(getRadiansFromDegree(270),
degOneTranslationAnimation.value * 100),
child: Transform(
transform: Matrix4.rotationZ(
getRadiansFromDegree(rotationAnimation.value))
..scale(degOneTranslationAnimation.value),
alignment: Alignment.center,
child: Container(
decoration: BoxDecoration(
color: Colors.black, shape: BoxShape.circle),
width: 50,
height: 50,
child: IconButton(
icon: Icon(Icons.repeat, color: Colors.white),
enableFeedback: true,
onPressed: () => customLaunch('https:google.com')),
),
),
),
Transform.translate(
offset: Offset.fromDirection(getRadiansFromDegree(225),
degOneTranslationAnimation.value * 100),
child: Transform(
transform: Matrix4.rotationZ(
getRadiansFromDegree(rotationAnimation.value))
..scale(degOneTranslationAnimation.value),
alignment: Alignment.center,
child: Container(
decoration: BoxDecoration(
color: Colors.black, shape: BoxShape.circle),
width: 50,
height: 50,
child: GestureDetector(
onTap: () => customLaunch('sms:546456464'),
child: IconButton(
icon: Icon(Icons.chat, color: Colors.white),
enableFeedback: true,
onPressed: () => {},
),
)),
),
),
Transform.translate(
offset: Offset.fromDirection(getRadiansFromDegree(180),
degOneTranslationAnimation.value * 100),
child: Transform(
transform: Matrix4.rotationZ(
getRadiansFromDegree(rotationAnimation.value))
..scale(degOneTranslationAnimation.value),
alignment: Alignment.center,
child: CircularButton(
onPressed: () => customLaunch('tel:+91 9478946545'),
color: Colors.black,
width: 50,
height: 50,
icon: Icon(
Icons.call,
color: Colors.white,
),
),
),
),
Transform(
transform: Matrix4.rotationZ(
getRadiansFromDegree(rotationAnimation.value)),
alignment: Alignment.center,
child: CircularButton(
color: Colors.black,
width: 60,
height: 60,
icon: Icon(
Icons.menu,
color: Colors.white,
),
onPressed: () {
if (animationController.isCompleted) {
animationController.reverse();
} else {
animationController.forward();
}
},
),
),
],
),
}
class CircularButton extends StatelessWidget {
final double width;
final double height;
final Color color;
final Icon icon;
final dynamic onPressed;
CircularButton({this.color, this.width, this.height, this.icon, this.onPressed});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
width: width,
height: height,
child: IconButton(icon: icon, enableFeedback: true, onPressed: onPressed),
);
}
}
我只想打开其他应用程序 onTap of expanded floating buttons 但它没有打开,虽然代码没有错误但仍然无法正常工作。 它不仅需要 onpressed 参数或 onTap。
我只需要将这个 IgnorePointer 添加到堆栈中,以便它检测手势并忽略该特定区域的动画 我更改的代码是
floatingActionButton: Stack(
children: <Widget>[
Positioned(
right: 30,
bottom: 30,
child: Stack(
alignment: Alignment.bottomRight,
children: <Widget>[
IgnorePointer( // this edit made it worked
child: Container(
color: Colors.transparent,
height: 150.0,
width: 150.0,
),
),
Transform.translate(
offset: Offset.fromDirection(getRadiansFromDegree(270),
degOneTranslationAnimation.value * 100),
child: Transform(
transform: Matrix4.rotationZ(
getRadiansFromDegree(rotationAnimation.value))
..scale(degOneTranslationAnimation.value),
alignment: Alignment.center,
child: CircularButton(
onClick: () => customLaunch('www.cigarettewala.com'),
color: Colors.black,
width: 50,
height: 50,
icon: Icon(
Icons.repeat,
color: Colors.white,
),
),
),
),