Flutter tạo menu Facebook đơn giản
Khi Fluttertôi đang cố tạo một Facebookmenu đơn giản , trong ảnh chụp màn hình bên dưới, chúng tôi có tiện ích con số một và khi tôi nhấp vào đó, tiện ích con nằm bên dưới tiện ích con hiện tại, sẽ được thay đổi kích thước và lớn lên và hiển thị các biểu tượng khác vào đó
mã dưới đây mà tôi đã giới thiệu tham chiếu hoạt động tốt, nhưng nó không có vùng chứa nền
trong tham chiếu liên kết Columnđược sử dụng và tôi đã thay đổi nó thành Stackvà không hoạt động chính xác
tài liệu tham khảo
import 'package:flutter/material.dart';
class FancyFab extends StatefulWidget {
final Function() onPressed;
final String tooltip;
final IconData icon;
FancyFab({this.onPressed, this.tooltip, this.icon});
@override
_FancyFabState createState() => _FancyFabState();
}
class _FancyFabState extends State<FancyFab>
with SingleTickerProviderStateMixin {
bool isOpened = false;
AnimationController _animationController;
Animation<Color> _buttonColor;
Animation<double> _animateIcon;
Animation<double> _translateButton;
Curve _curve = Curves.easeOut;
double _fabHeight = 56.0;
@override
initState() {
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 500))
..addListener(() {
setState(() {});
});
_animateIcon =
Tween<double>(begin: 0.0, end: 1.0).animate(_animationController);
_buttonColor = ColorTween(
begin: Colors.blue,
end: Colors.red,
).animate(CurvedAnimation(
parent: _animationController,
curve: Interval(
0.00,
1.00,
curve: Curves.linear,
),
));
_translateButton = Tween<double>(
begin: _fabHeight,
end: -14.0,
).animate(CurvedAnimation(
parent: _animationController,
curve: Interval(
0.0,
0.75,
curve: _curve,
),
));
super.initState();
}
@override
dispose() {
_animationController.dispose();
super.dispose();
}
animate() {
if (!isOpened) {
_animationController.forward();
} else {
_animationController.reverse();
}
isOpened = !isOpened;
}
Widget add() {
return Container(
child: FloatingActionButton(
onPressed: null,
tooltip: 'Add',
child: Icon(Icons.add),
),
);
}
Widget image() {
return Container(
child: FloatingActionButton(
onPressed: null,
tooltip: 'Image',
child: Icon(Icons.image),
),
);
}
Widget inbox() {
return Container(
child: FloatingActionButton(
onPressed: null,
tooltip: 'Inbox',
child: Icon(Icons.inbox),
),
);
}
Widget toggle() {
return Container(
child: FloatingActionButton(
backgroundColor: _buttonColor.value,
onPressed: animate,
tooltip: 'Toggle',
child: AnimatedIcon(
icon: AnimatedIcons.menu_close,
progress: _animateIcon,
),
),
);
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Transform(
transform: Matrix4.translationValues(
0.0,
_translateButton.value * 3.0,
0.0,
),
child: add(),
),
Transform(
transform: Matrix4.translationValues(
0.0,
_translateButton.value * 2.0,
0.0,
),
child: image(),
),
Transform(
transform: Matrix4.translationValues(
0.0,
_translateButton.value,
0.0,
),
child: inbox(),
),
toggle(),
],
);
}
}
Tôi muốn sử dụng tiện ích này vào Flutterlistview, tiện ích đó sẽ xuất hiện ở nơi tôi nhấp vào, ví dụ bạn cho rằng tôi có tôi IconButtonvào ListViewcác mục, khi tôi nhấp vào đó, tiện ích này sẽ xuất hiện ở vị trí được nhấp và ButtonphảiFloatingActionButton
Trả lời
Tôi đã thực hiện điều này bằng cách sử dụng Stackvà AnimatedContainer.
- sử dụng
PositionedtrongStack, tôi đã đặt nó ở dưới cùng. Lý do cho điều này là để căn chỉnh cả haiContainervàFABcùng một vị trí khi hoạt ảnh của nó. - bằng cách sử dụng
AnimatedContainer, tôi đã tạo một hoạt ảnh đơn giản thay đổi chiều cao của nó khi chúng ta nhấn vàoFABbằng cách sử dụng giá trị bool.
(Tôi Thêm một vùng chứa bổ sung vào cột, nó sẽ ẩn sau FAB và cũng Căn chỉnh nó một cách hoàn hảo, nhưng bạn có thể thêm SizedBox hoặc Vùng chứa mà không có màu và giữ kích thước cuối cùng là 54.0, nếu bạn không sử dụng list.generate)
Hãy thử điều này trên DartPad
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Container(
width: 250,
height: 250,
color: Colors.white,
child: YellowBird(),
)),
),
);
}
}
class YellowBird extends StatefulWidget {
const YellowBird({Key key}) : super(key: key);
@override
_YellowBirdState createState() => _YellowBirdState();
}
class _YellowBirdState extends State<YellowBird> {
bool animate = true;
@override
Widget build(BuildContext context) {
return Stack(
alignment: AlignmentDirectional.topCenter,
children: [
Positioned(
bottom: 0,
child: AnimatedContainer(
width: 54.0,
decoration: BoxDecoration(
color: Colors.redAccent,
borderRadius: BorderRadius.all(Radius.circular(360))
),
height: animate ? 56.0 : 250.0,
duration: Duration(milliseconds: 300),
child: animate
? Container()
: Column(
children: List.generate(
4,
(i) => Expanded(
child: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
),
),
),
),
),
),
Positioned(
bottom: 0,
child: FloatingActionButton(
backgroundColor: Colors.grey,
child: Icon(animate ? Icons.menu : Icons.close, size: 30),
onPressed: () {
setState(() {
animate = !animate;
});
})),
]);
}
}
cho tôi biết nếu điều này hoạt động hoặc họ có bất cứ điều gì để thay đổi từ điều này.
xin chào, hãy xem thư viện này ... https://pub.dev/packages/flutter_portal đây là cách đơn giản nhất để tạo lớp phủ trong Flutter ...
PortalEntry(
visible: isMenuVisible, //true Or False
portalAnchor: Alignment.topLeft,
childAnchor: Alignment.topRight,
portal: TheMenuWidget, // option 1 + option 2 (White)
child: MyButton, // show Menu Button (Grey)
)