Flutter应用入口插件entry的使用
Flutter应用入口插件entry的使用
插件简介
Entry
Entry
是一个用于简化Flutter中Widget动画显示的包。它允许你轻松地让组件以动画的形式出现或消失,而不仅仅是简单地显示。
构造函数
默认构造函数
Entry({key, delay, duration, curve, visible, opacity, scale, xOffset, yOffset, angle, child})
默认情况下,这个构造函数是静止不动的。它包括所有命名构造函数可用的所有参数。
命名构造函数
Entry
提供了四个命名构造函数:
Entry.all({visible, opacity, scale, xOffset, yOffset, angle})
.all
使用除了angle
和xOffset
之外的所有动画。
Entry.opacity({opacity})
Entry.scale({scale})
Entry.offset({xOffset, yOffset})
注意:
key
,delay
,duration
,curve
,visible
和child
参数在上面省略了。
组合使用
你可以将一个Entry
包裹在另一个Entry
中,通过调整参数可以创造出无限可能的效果。
组合效果示例
网格构建器
固定交叉轴数量
使用Entry
与网格构建器结合可以创建交错效果:
- 包裹生成的子组件为
Entry
widget - 将
delay
值乘以index % crossAxisCount
这样,同一行的组件会依次出现。
交错效果示例
随机化
你可以设置delay
和/或duration
为随机数,使动画看起来更加独立。
delay: Duration(milliseconds: random.nextInt(300))
随机化效果示例
示例代码
下面是一个完整的示例代码,展示了如何使用entry
插件的不同功能:
import 'dart:math';
import 'package:entry/entry.dart';
import 'package:flutter/material.dart';
void main() => runApp(ExampleApp());
/// Custom card used for every example
class CustomCard extends StatelessWidget {
const CustomCard(this.label, {Key? key}) : super(key: key);
final String label;
@override
Widget build(BuildContext context) {
return Card(
child: Container(
color: Colors.grey[300],
width: 128,
height: 128,
child: Center(
child: Text(
label,
style: const TextStyle(fontSize: 16),
),
),
),
);
}
}
/// Example app widget
class ExampleApp extends StatefulWidget {
const ExampleApp({Key? key}) : super(key: key);
@override
State<ExampleApp> createState() => _ExampleAppState();
}
class _ExampleAppState extends State<ExampleApp> {
/// List of the tabs titles
final tabs = [
"Constructors",
"Entry combinations",
"Staggered builds",
"Randomization"
];
/// Random instance
final random = Random();
var visible = true;
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SafeArea(
child: DefaultTabController(
length: tabs.length,
child: Scaffold(
backgroundColor: Colors.white,
appBar: TabBar(
isScrollable: true,
tabs: [
for (var tab in tabs)
Padding(
padding: const EdgeInsets.all(8),
child: Text(
tab,
style: const TextStyle(color: Colors.black),
),
),
],
),
body: TabBarView(
children: [
// Constructors
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Wrap(
alignment: WrapAlignment.center,
runAlignment: WrapAlignment.center,
children: [
Entry.all(
visible: visible,
duration: const Duration(seconds: 1),
child: const CustomCard("Entry.all()"),
),
Entry.opacity(
visible: visible,
duration: const Duration(seconds: 1),
child: const CustomCard("Entry.opacity()"),
),
Entry.scale(
visible: visible,
duration: const Duration(seconds: 1),
child: const CustomCard("Entry.scale()"),
),
Entry.offset(
visible: visible,
duration: const Duration(seconds: 1),
child: const CustomCard("Entry.offset()"),
),
],
),
Center(
child: ElevatedButton(
onPressed: () => setState(() => visible = !visible),
child: Text("visible : $visible"),
)),
],
),
// Entry combinations
Center(
child: Wrap(
children: [
// Example 1
Entry(
xOffset: -1000,
scale: 20,
delay: const Duration(milliseconds: 300),
duration: const Duration(milliseconds: 700),
curve: Curves.ease,
child: Entry(
opacity: .5,
angle: 3.1415,
scale: .5,
delay: const Duration(milliseconds: 900),
duration: const Duration(milliseconds: 500),
curve: Curves.decelerate,
child: const CustomCard("Example 1"),
),
),
// Example 2
Entry(
delay: const Duration(milliseconds: 300),
duration: const Duration(milliseconds: 300),
opacity: 0,
yOffset: -1000,
curve: Curves.easeInOutCubic,
child: Entry(
delay: const Duration(milliseconds: 450),
duration: const Duration(milliseconds: 600),
curve: Curves.decelerate,
scale: 0.5,
angle: 1.5707,
child: const CustomCard("Example 2"),
),
),
// Example 3
Entry(
delay: const Duration(milliseconds: 300),
duration: const Duration(milliseconds: 700),
yOffset: 1000,
xOffset: 1000,
angle: -4.1415,
curve: Curves.fastOutSlowIn,
child: Entry(
delay: const Duration(milliseconds: 1000),
duration: const Duration(milliseconds: 250),
curve: Curves.easeOut,
opacity: 0.5,
scale: 0.5,
child: const CustomCard("Example 3"),
),
),
],
),
),
// Staggered builds
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: GridView.builder(
itemCount: 100,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
itemBuilder: (context, index) => Entry.all(
delay: Duration(milliseconds: (200 * (index % 3))),
child: CustomCard("Card n°$index"),
),
),
),
// Randomization
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: GridView.builder(
itemCount: 100,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
itemBuilder: (context, index) => Entry.all(
delay: Duration(milliseconds: random.nextInt(300)),
child: CustomCard("Card n°$index"),
),
),
),
],
),
floatingActionButton: Builder(
builder: (context) {
return FloatingActionButton(
child: const Icon(Icons.refresh),
onPressed: () async {
// Re-initializes the whole page to show the animations again
Navigator.of(context).pop();
Navigator.push(
context,
PageRouteBuilder(
pageBuilder: (_, __, ___) => const ExampleApp(),
transitionDuration: Duration.zero,
),
);
},
);
},
),
),
),
),
);
}
}
以上代码展示了如何使用entry
插件的各种功能,包括不同的构造函数、组合动画、交错布局以及随机化效果。希望这能帮助你在Flutter项目中更好地利用动画来提升用户体验。
更多关于Flutter应用入口插件entry的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter应用入口插件entry的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter应用中,entry
插件通常用于定义应用的入口点,尤其是在处理多入口场景时非常有用。虽然Flutter本身并没有一个官方名为 entry
的插件,但我们可以理解为如何在Flutter中配置和管理多个入口点。
在Flutter中,你可以通过配置 android/app/src/main/AndroidManifest.xml
和 ios/Runner/Info.plist
文件,以及使用 flutter_native_splash
等第三方库来设置应用的启动画面和入口。不过,对于多入口点的实现,通常是通过路由管理来实现的,比如使用 flutter_navigator
或 flutter_deep_linking
等库。
下面是一个使用 flutter_navigator
库来管理多入口点的示例代码:
-
添加依赖: 在你的
pubspec.yaml
文件中添加flutter_navigator
依赖:dependencies: flutter: sdk: flutter flutter_navigator: ^x.y.z # 替换为最新版本号
-
配置路由: 创建一个路由配置文件,比如
routes.dart
,来定义你的路由和入口点:import 'package:flutter/material.dart'; import 'package:flutter_navigator/flutter_navigator.dart'; import 'your_first_screen.dart'; import 'your_second_screen.dart'; Map<String, WidgetBuilder> getRoutes() { return { '/': (context) => YourFirstScreen(), '/second': (context) => YourSecondScreen(), }; } void configureRoutes(NavigatorState navigator) { FlutterNavigator.instance .setRoutes(getRoutes()) .setInitialRoute('/'); }
-
在
main.dart
中使用路由:import 'package:flutter/material.dart'; import 'routes.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { [@override](/user/override) Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Multi Entry Example', theme: ThemeData( primarySwatch: Colors.blue, ), navigatorKey: FlutterNavigator.navigatorKey, // 使用FlutterNavigator的navigatorKey onGenerateRoute: (settings) { final routeName = settings.name ?? '/'; final route = FlutterNavigator.instance.getRoute(routeName); return MaterialPageRoute(builder: route, settings: settings); }, initialRoute: '/', ); } } [@override](/user/override) void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) => configureRoutes(FlutterNavigator.navigator!)); }
注意:在上面的代码中,
WidgetsBinding.instance.addPostFrameCallback
用于在应用框架构建完成后配置路由,确保Navigator
已经初始化。 -
启动应用: 现在,你可以通过URL来启动不同的入口点。例如,在Android上,你可以通过Intent来启动特定的路由:
Intent intent = FlutterActivity .withCachedEngine("my_engine_id") .build(context) .putExtra("flutter_entrypoint", "/second"); startActivity(intent);
在iOS上,你可以通过URL Scheme来启动特定的路由:
let url = URL(string: "yourappscheme://second")! UIApplication.shared.open(url, options: [:], completionHandler: nil)
注意:上述iOS代码示例假设你已经配置了URL Scheme,并且你的Flutter应用能够处理这些URL。
通过这种方式,你可以实现Flutter应用中的多入口点管理。虽然没有一个名为 entry
的官方插件,但你可以使用路由管理库来实现类似的功能。