Flutter自定义聚焦菜单插件focused_menu_custom的使用
Flutter自定义聚焦菜单插件focused_menu_custom的使用
focused_menu_custom
是一个易于实现的包,用于在Flutter应用程序中添加长按聚焦菜单。该插件允许您将聚焦菜单添加到任何小部件,并根据您的应用需求自定义菜单和动画。
当前功能
- 将聚焦菜单添加到任何小部件。
- 根据应用程序需求自定义聚焦菜单和动画。
演示
使用方法
要使用此插件,只需将想要添加聚焦菜单的小部件用 FocusedMenuHolder
包裹起来即可:
Expanded(
child: GridView(
physics: BouncingScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
children: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
.map((e) => FocusedMenuHolder(
menuWidth: MediaQuery.of(context).size.width * 0.50,
blurSize: 5.0,
menuItemExtent: 45,
menuBoxDecoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.all(Radius.circular(15.0))),
duration: Duration(milliseconds: 100),
animateMenuItems: true,
blurBackgroundColor: Colors.black54,
openWithTap: true, // 点击打开而不是长按
menuOffset: 10.0, // 菜单项显示的偏移值
bottomOffsetHeight: 80.0, // 底部导航栏的偏移高度
menuItems: <FocusedMenuItem>[
FocusedMenuItem(
title: Text("Open"),
trailingIcon: Icon(Icons.open_in_new),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ScreenTwo()));
}),
FocusedMenuItem(title: Text("Share"), trailingIcon: Icon(Icons.share), onPressed: () {}),
FocusedMenuItem(title: Text("Favorite"), trailingIcon: Icon(Icons.favorite_border), onPressed: () {}),
FocusedMenuItem(
title: Text("Delete", style: TextStyle(color: Colors.redAccent)),
trailingIcon: Icon(Icons.delete, color: Colors.redAccent),
onPressed: () {}),
],
onPressed: () {},
child: Card(
child: Column(
children: <Widget>[
Image.asset("assets/images/image_$e.jpg"),
],
),
),
))
.toList(),
),
),
示例代码
以下是一个完整的示例代码,展示如何在Flutter应用中使用 focused_menu_custom
插件:
import 'package:flutter/material.dart';
import 'package:focused_menu_custom/focused_menu.dart';
import 'package:focused_menu_custom/modals.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Focused Menu Custom',
theme: ThemeData(
brightness: Brightness.light,
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
darkTheme: ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.red,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
themeMode: ThemeMode.light,
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Container(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Music Albums",
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
Expanded(child: Center()),
IconButton(icon: Icon(Icons.shopping_cart), onPressed: () {}),
CircleAvatar(
child: Image.asset("assets/images/dp_default.png"),
)
],
),
SizedBox(height: 10),
TextField(
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Look for your Interest!",
fillColor: Colors.grey.shade200,
filled: true),
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
DropdownButton(
style: TextStyle(fontSize: 15, color: Colors.black),
icon: Icon(Icons.keyboard_arrow_down),
underline: Container(
color: Colors.white,
),
items: ["Featured", "Most Rated", "Recent", "Popular"]
.map<DropdownMenuItem>(
(e) => DropdownMenuItem(child: Text(e)))
.toList(),
onChanged: (newItem) {}),
IconButton(icon: Icon(Icons.sort), onPressed: () {})
],
),
SizedBox(height: 10),
Expanded(
child: GridView(
physics: BouncingScrollPhysics(),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
children: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
.map((e) => FocusedMenuHolder(
menuWidth: MediaQuery.of(context).size.width * 0.50,
blurSize: 5.0,
menuItemExtent: 45,
menuBoxDecoration: BoxDecoration(
color: Colors.grey,
borderRadius:
BorderRadius.all(Radius.circular(15.0))),
duration: Duration(milliseconds: 100),
animateMenuItems: true,
blurBackgroundColor: Colors.black54,
bottomOffsetHeight: 100,
openWithTap: true,
menuItems: <FocusedMenuItem>[
FocusedMenuItem(
title: Text("Open"),
trailingIcon: Icon(Icons.open_in_new),
onPressed: () {
// Navigate to another screen
}),
FocusedMenuItem(
title: Text("Share"),
trailingIcon: Icon(Icons.share),
onPressed: () {}),
FocusedMenuItem(
title: Text("Favorite"),
trailingIcon: Icon(Icons.favorite_border),
onPressed: () {}),
FocusedMenuItem(
title: Text(
"Delete",
style: TextStyle(color: Colors.redAccent),
),
trailingIcon: Icon(
Icons.delete,
color: Colors.redAccent,
),
onPressed: () {}),
],
onPressed: () {},
child: Card(
child: Column(
children: <Widget>[
Image.asset("assets/images/image_$e.jpg"),
],
),
),
))
.toList(),
),
),
],
),
),
),
bottomNavigationBar: BottomNavigationBar(items: <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.add), label: "Home"),
BottomNavigationBarItem(icon: Icon(Icons.add), label: "Menu 2"),
BottomNavigationBarItem(icon: Icon(Icons.add), label: "Menu 3"),
BottomNavigationBarItem(icon: Icon(Icons.add), label: "Menu 4"),
BottomNavigationBarItem(icon: Icon(Icons.add), label: "Menu 5"),
]),
),
);
}
}
更多关于Flutter自定义聚焦菜单插件focused_menu_custom的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter自定义聚焦菜单插件focused_menu_custom的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter中使用自定义聚焦菜单插件 focused_menu_custom
的一个代码示例。这个示例展示了如何创建并显示一个自定义聚焦菜单。
首先,确保你已经在你的 pubspec.yaml
文件中添加了 focused_menu_custom
依赖项:
dependencies:
flutter:
sdk: flutter
focused_menu_custom: ^最新版本号 # 替换为实际的最新版本号
然后运行 flutter pub get
来获取依赖项。
接下来,在你的 Dart 文件中使用 FocusedMenuCustom
组件。以下是一个完整的示例:
import 'package:flutter/material.dart';
import 'package:focused_menu_custom/focused_menu_custom.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Focused Menu Custom Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Focused Menu Custom Demo'),
),
body: Center(
child: FocusedMenuCustomDemo(),
),
),
);
}
}
class FocusedMenuCustomDemo extends StatefulWidget {
@override
_FocusedMenuCustomDemoState createState() => _FocusedMenuCustomDemoState();
}
class _FocusedMenuCustomDemoState extends State<FocusedMenuCustomDemo> {
final List<String> menuItems = ['Item 1', 'Item 2', 'Item 3', 'Item 4'];
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
showMenu(
context: context,
position: RelativeRect.fromLTRB(0, 0, 0, 0),
items: menuItems.map<PopupMenuEntry<String>>((String item) {
return PopupMenuItem<String>(
value: item,
child: Text(item),
);
}).toList(),
elevation: 8.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
builder: (BuildContext context) {
return Material(
color: Colors.white,
child: FocusedMenuCustom(
menuItems: menuItems,
onMenuItemSelected: (String selectedItem) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Selected: $selectedItem'),
),
);
},
// 自定义菜单项样式
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
Navigator.pop(context, menuItems[index]);
},
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: index == menuItems.indexOf(Navigator.popResult(context))
? Colors.blue
: Colors.transparent,
width: 2.0,
),
),
),
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 12),
child: Text(
menuItems[index],
style: TextStyle(
color: index == menuItems.indexOf(Navigator.popResult(context))
? Colors.blue
: Colors.black,
),
),
),
);
},
),
);
},
);
},
child: Container(
width: 100,
height: 100,
color: Colors.blue.withOpacity(0.5),
child: Center(
child: Text(
'Tap me',
style: TextStyle(color: Colors.white),
),
),
),
);
}
}
在这个示例中,我们做了以下几件事:
- 添加了
focused_menu_custom
依赖项。 - 创建了一个包含菜单项的列表。
- 使用
GestureDetector
监听点击事件。 - 使用
showMenu
显示菜单。 - 自定义了
FocusedMenuCustom
的itemBuilder
以自定义菜单项的样式,并处理菜单项的点击事件。
请注意,Navigator.popResult(context)
并不存在于 Flutter 的标准库中,这里只是为了演示如何获取用户选择的菜单项。在实际应用中,你应该使用 Navigator.pop(context, result)
返回结果,并在调用 showMenu
的地方使用 await
关键字获取结果。由于 FocusedMenuCustom
插件可能不支持这种直接的结果返回方式,你可能需要调整逻辑以适应插件的实际行为。
希望这个示例对你有帮助!