Flutter浮动视图插件flutter_portal的使用
Flutter浮动视图插件flutter_portal的使用
Flutter中的flutter_portal
插件提供了一种声明式的方法来创建和管理浮动视图,如工具提示、上下文菜单、对话框等。它改进了Flutter内置的Overlay
/OverlayEntry
机制,使其更加直观、易于对齐,并且可以更好地与Flutter的声明式UI模型结合使用。
🚀 优点
- 声明式而非命令式:像Flutter中的其他所有内容一样,覆盖层(portals)现在是声明式的。只需将浮动UI作为普通小部件放入小部件树中。
- 轻松对齐:内建支持将覆盖层相对于UI组件对齐。
- 直观的
Context
:覆盖层条目构建时使用其直观的父级作为context
。
此外,还有以下优点:
- 易于恢复属性:由于显示覆盖层就像调用
setState
一样简单,因此RestorableProperty
可以很好地工作。 - 正确的
Theme
/provider
:覆盖层条目可以访问与显示覆盖层的小部件相同的Theme
和不同的provider
s。
👀 示例代码
PortalTarget(
// 声明式:只需提供`portalFollower`作为普通小部件
portalFollower: MyAwesomeOverlayWidget(),
// 对齐“跟随者”相对于“子项”
anchor: Aligned.center,
child: MyChildWidget(),
)
🪜 示例
查看示例文件夹了解如何使用flutter_portal
:
🧭 使用方法
- 安装插件。遵循标准安装此包的程序。最简单的方法可能是
flutter pub add flutter_portal
。 - 添加
Portal
小部件。例如,将其放置在MaterialApp
之上。每个应用程序只需要一个Portal
。 - 在需要显示覆盖层的地方使用
PortalTarget
。
📚 教程:显示上下文菜单
添加Portal
小部件
Portal(
child: MaterialApp(...)
)
创建按钮
class MenuExample extends StatefulWidget {
@override
_MenuExampleState createState() => _MenuExampleState();
}
class _MenuExampleState extends State<MenuExample> {
bool isMenuOpen = false;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: PortalTarget(
visible: isMenuOpen,
anchor: const Aligned(
follower: Alignment.topLeft,
target: Alignment.topRight,
),
portalFollower: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {
isMenuOpen = false;
});
},
child: Material(
elevation: 8,
child: IntrinsicWidth(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(title: Text('option 1')),
ListTile(title: Text('option 2')),
],
),
),
),
),
child: ElevatedButton(
onPressed: () {
setState(() {
isMenuOpen = true;
});
},
child: Text('show menu'),
),
),
),
);
}
}
完整示例
import 'package:flutter/material.dart';
import 'package:flutter_portal/flutter_portal.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Portal(
child: MaterialApp(
home: MenuExample(),
),
);
}
}
class MenuExample extends StatefulWidget {
@override
_MenuExampleState createState() => _MenuExampleState();
}
class _MenuExampleState extends State<MenuExample> {
bool isMenuOpen = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Flutter Portal Example')),
body: Center(
child: PortalTarget(
visible: isMenuOpen,
anchor: const Aligned(
follower: Alignment.topLeft,
target: Alignment.topRight,
),
portalFollower: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
setState(() {
isMenuOpen = false;
});
},
child: Material(
elevation: 8,
child: IntrinsicWidth(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(title: Text('Option 1'), onTap: () {}),
ListTile(title: Text('Option 2'), onTap: () {}),
],
),
),
),
),
child: ElevatedButton(
onPressed: () {
setState(() {
isMenuOpen = true;
});
},
child: Text('Show Menu'),
),
),
),
);
}
}
通过以上步骤,您可以轻松地在Flutter应用中实现上下文菜单或其他类型的浮动视图。希望这个教程能帮助您更好地理解和使用flutter_portal
插件。
更多关于Flutter浮动视图插件flutter_portal的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter浮动视图插件flutter_portal的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter中使用flutter_portal
插件来创建浮动视图的示例代码。flutter_portal
插件允许你在Flutter应用中创建浮动的内容,这些内容可以覆盖在其他UI元素之上。
首先,确保你的pubspec.yaml
文件中已经添加了flutter_portal
依赖:
dependencies:
flutter:
sdk: flutter
flutter_portal: ^0.15.0 # 请检查最新版本号
然后运行flutter pub get
来安装依赖。
示例代码
下面是一个简单的示例,展示如何使用flutter_portal
来创建一个浮动按钮,该按钮可以覆盖在页面的其他内容之上。
1. 创建主页面(Main Page)
import 'package:flutter/material.dart';
import 'package:flutter_portal/flutter_portal.dart';
import 'overlay_content.dart'; // 导入浮动内容
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: PortalHost(
child: Scaffold(
appBar: AppBar(
title: Text('Flutter Portal Example'),
),
body: Center(
child: Text('This is the main content.'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
tooltip: 'Open Overlay',
child: Icon(Icons.add),
),
),
portal: OverlayContent(), // 浮动内容
),
);
}
}
2. 创建浮动内容(Overlay Content)
在overlay_content.dart
文件中,定义浮动内容:
import 'package:flutter/material.dart';
import 'package:flutter_portal/flutter_portal.dart';
class OverlayContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return PortalEntry(
visible: true, // 控制浮动内容的显示与隐藏
child: Material(
elevation: 8.0, // 设置阴影
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.0),
),
padding: EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('This is the overlay content.'),
SizedBox(height: 16.0),
ElevatedButton(
onPressed: () {
// 可以在这里添加关闭浮动内容的逻辑
},
child: Text('Close'),
),
],
),
),
),
);
}
}
解释
-
PortalHost
:这是flutter_portal
提供的一个Widget,用于作为浮动内容的容器。它有一个child
属性,用于显示正常的内容,还有一个portal
属性,用于显示浮动的内容。 -
PortalEntry
:这是浮动内容的入口点,visible
属性用于控制浮动内容的显示与隐藏。child
属性是实际的浮动内容。 -
浮动内容:在
OverlayContent
类中,我们创建了一个简单的浮动内容,包括一些文本和一个关闭按钮。
运行代码
将上述代码放入你的Flutter项目中,然后运行应用。你应该会看到一个带有浮动按钮的主页面,当你点击浮动按钮时(尽管这个例子中未添加打开浮动内容的逻辑),你可以手动在PortalHost
的portal
属性中显示浮动内容。
你可以根据需要进一步扩展这个示例,比如添加打开浮动内容的逻辑,或者在浮动内容中添加更多的交互元素。