【发布时间】:2021-07-03 23:49:11
【问题描述】:
我正在尝试构建一个包含用于在屏幕之间导航的底部导航栏的应用。
在底部导航栏的中间,我想添加一个按钮,将底部导航栏扩展成一个半圆形,并增加更多按钮。
我已经阅读了底部导航栏的文档,并且在 pub.dev 中搜索了很多我可以使用的类似的东西,但我找不到。
有谁知道它是否可以实现,如果可以,如何实现?
非常感谢
【问题讨论】:
标签: flutter dart flutter-layout flutter-dependencies
我正在尝试构建一个包含用于在屏幕之间导航的底部导航栏的应用。
在底部导航栏的中间,我想添加一个按钮,将底部导航栏扩展成一个半圆形,并增加更多按钮。
我已经阅读了底部导航栏的文档,并且在 pub.dev 中搜索了很多我可以使用的类似的东西,但我找不到。
有谁知道它是否可以实现,如果可以,如何实现?
非常感谢
【问题讨论】:
标签: flutter dart flutter-layout flutter-dependencies
您可以使用showDialog 和CustomPainter 检查这个简单的实现。基本上它涉及显示showDialog,底部填充等于BottomNavigationBar 的高度,然后在Stack 中排列项目。半圆是使用CustomPainter绘制的。
完整示例应用:
import 'dart:math' as math;
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test App'),
),
bottomNavigationBar: BottomNavigationBar(
unselectedItemColor: Colors.grey,
selectedItemColor: Colors.blue,
showUnselectedLabels: true,
selectedFontSize: 14,
unselectedFontSize: 14,
type: BottomNavigationBarType.fixed,
onTap: (index) {
if (index == 2) {
final diameter = 200.0;
final iconSize = 40;
showDialog(
context: context,
barrierDismissible: true,
barrierColor: Colors.grey.withOpacity(0.1),
builder: (context) => Material(
color: Colors.transparent,
child: Stack(
alignment: AlignmentDirectional.bottomCenter,
children: [
Container(
width: diameter + iconSize,
height: diameter / 1.5,
alignment: Alignment.bottomCenter,
margin:
EdgeInsets.only(bottom: kBottomNavigationBarHeight),
child: Stack(
children: [
Container(
alignment: Alignment.bottomCenter,
child: MyArc(diameter: diameter)),
Positioned(
left: 0,
bottom: 10,
child: _buildButton(),
),
Positioned(
left: diameter / 4,
top: 10,
child: _buildButton(),
),
Positioned(
right: diameter / 4,
top: 10,
child: _buildButton(),
),
Positioned(
right: 0,
bottom: 10,
child: _buildButton(),
)
],
),
),
],
),
),
);
}
},
items: List<BottomNavigationBarItem>.generate(
5,
(index) =>
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
),
),
);
}
_buildButton() {
return Container(
constraints: BoxConstraints.tightFor(width: 40, height: 60),
child: Column(
children: [
Text(
'Title',
style: TextStyle(fontSize: 12),
),
SizedBox(height: 3),
CircleAvatar(
backgroundColor: Colors.white,
child: Icon(Icons.home),
),
],
),
);
}
}
class MyArc extends StatelessWidget {
final double diameter;
const MyArc({Key key, this.diameter = 200}) : super(key: key);
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: MyPainter(),
size: Size(diameter, diameter),
);
}
}
// This is the Painter class
class MyPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..shader = RadialGradient(
colors: [
Colors.blue,
Colors.purpleAccent.withOpacity(0.4),
],
).createShader(Rect.fromCircle(
center: Offset(size.width / 2, size.height),
radius: 200,
));
canvas.drawArc(
Rect.fromCenter(
center: Offset(size.width / 2, size.height),
height: size.height * 1.5,
width: size.width,
),
math.pi,
math.pi,
false,
paint,
);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
【讨论】:
我认为你需要了解 Flutter Animated Radial Menu 以及如何在你的代码中实现它,你可以去with this article 并尝试以你的方式实现。
【讨论】: