Flutter 可管理状态 可以跨导航路由进行通信 插件pylon的使用
Flutter 可管理状态 可以跨导航路由进行通信 插件pylon的使用
设计理念
与其它状态管理包不同,Pylon 的职责在于管理状态。这意味着我们会始终在可靠性上做取舍,而不是追求效率和速度。如果一个包不能保证 100% 的可靠运行,并且需要开发者理解系统的内部机制,那么它就不是一个好的包。Pylon 被设计为简单而可靠的工具,其优先级始终是可靠性。
Pylon 是一个 Provider
- Pylon 的工作方式与 Provider 类似,但它们的工作方式更加符合预期。
- Pylon 可以跨导航路由进行通信,通过
Pylon.push
方法实现。 - 即使 Pylon 是当前访问它的小部件的直接父级,你也可以访问它。
使用方法
Pylon 非常容易使用。你可以将值包装到 widget 树中,并且可以随时访问这些值,无需担心以后无法获取。
基本计数器
import 'package:pylon/pylon.dart';
class Counter extends StatelessWidget {
Counter({super.key});
[@override](/user/override)
Widget build(BuildContext context) => Pylon<int>(
value: 0, // 初始化值为 0
builder: (context) => Scaffold(
body: Center(
// 访问 Pylon 中的值。由于 Pylon 是构建器,你可以立即使用它
child: Text("Count: ${context.pylon<int>()}"), // 显示当前计数值
),
floatingActionButton: FloatingActionButton(
// 使用 modPylon<T>((T) => T) 来修改值,或者直接使用 setPylon(T)
onPressed: () => context.modPylon<int>((t) => t + 1), // 每次点击按钮时增加计数
child: Icon(Icons.add),
),
),
);
}
桥接 Pylons
在这个例子中,我们有一个包含多个 Dog 对象的列表,每个对象都用一个 DogTile 小部件表示。当用户点击某个 DogTile 时,他们会被导航到 DogScreen,可以在其中修改 Dog 的年龄。当返回列表视图时,被点击的列表项会自动更新为新的年龄。
// 基本的 Dog 类,包含 copyWith 方法
class Dog {
final String name;
final int age;
Dog(this.name, this.age);
static Dog copyWith(Dog dog, {String? name, int? age}) =>
Dog(name ?? dog.name, age ?? dog.age);
}
// 狗的列表
List<Dog> dogs = [
Dog("Fido", 3),
Dog("Rex", 5),
Dog("Spot", 2),
];
// 一个方便的扩展,用于访问 Pylon 的值
extension XContext on BuildContext {
Dog get dog => pylon<Dog>();
set dog(Dog value) => setPylon(value);
}
// 狗的列表视图
class DogList extends StatelessWidget {
const DogList({super.key});
[@override](/user/override)
Widget build(BuildContext context) => ListView(
// 将每个狗映射到一个 Pylon<Dog>(value: e, builder: () => DogTile())
children: dogs.withPylons((context) => DogTile()),
);
}
// 代表一个狗的列表项
class DogTile extends StatelessWidget {
const DogTile({super.key});
[@override](/user/override)
Widget build(BuildContext context) => ListTile(
title: Text(context.dog.name),
trailing: Text("${context.dog.age}y old"),
// 使用 pylon.push 导航到 DogScreen 并保持 context.dog 可用
onTap: () => Pylon.push(context, DogScreen()),
);
}
class DogScreen extends StatelessWidget {
const DogScreen({super.key});
[@override](/user/override)
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: Text(context.dog.name)),
body: Center(
child: Text("Age: ${context.dog.age}"),
),
floatingActionButton: FloatingActionButton(
// 增加狗的年龄,这将自动更新此屏幕和父级列表项
onPressed: () => context.dog = context.dog.copyWith(age: context.dog.age + 1),
child: Icon(Icons.add),
),
);
}
完整示例 Demo
以下是一个完整的示例代码,展示了如何使用 Pylon 插件来管理状态:
import 'package:flutter/material.dart';
import 'package:pylon/pylon.dart';
// 临时存储 "数据"
List<Note> notes = [];
// 临时函数用于添加笔记
void _addNote(String title, String note) => notes.add(Note(
id: notes.length,
name: title,
description: note,
));
// 笔记类表示我们的数据模型
class Note implements PylonCodec<Note> {
final int id;
final String name;
final String description;
const Note({
required this.id,
required this.name,
required this.description,
});
Map<String, dynamic> toMap() => {
'name': name,
'id': id,
'description': description,
};
factory Note.fromMap(Map<String, dynamic> map) => Note(
name: map['name'],
description: map['description'],
id: map['id'],
);
[@override](/user/override)
String pylonEncode(Note value) => value.id.toString();
[@override](/user/override)
Future<Note> pylonDecode(String value) async => notes[int.parse(value)];
}
void main() {
// 添加一些 "笔记"
for (int i = 0; i < 100; i++) {
_addNote("Hello Note ${notes.length}", "This is the content of note ${notes.length}");
}
registerPylonCodec(const Note(id: -1, name: "", description: ""));
// 注册编码器
runApp(MainS());
}
extension _XContextPylonNotes on BuildContext {
Note get note => pylon<Note>();
}
class MainS extends StatelessWidget {
Map<String, WidgetBuilder> routes = {
"/": (context) => const HomeScreen(),
"/note": (context) => const NoteScreen()
};
MainS({super.key});
[@override](/user/override)
Widget build(BuildContext context) => MaterialApp(
theme: ThemeData.dark(),
debugShowCheckedModeBanner: false,
onGenerateRoute: (RouteSettings settings) {
if (settings.name?.isNotEmpty ?? false) {
String route = Uri.parse(settings.name!).path;
if (routes.containsKey(route)) {
return MaterialPageRoute(
builder: routes[route]!, settings: settings);
}
}
},
routes: routes,
initialRoute: "/",
);
}
// 展示笔记列表的界面
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
[@override](/user/override)
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Conduit<int>(builder: (context, v) => Text("$v")),
),
body: ListView.builder(
// 为每个笔记构建一个 Pylon 包装的笔记项
itemBuilder: (context, i) => Pylon<Note>(
value: notes[i],
builder: (context) => NoteTile(),
),
itemCount: notes.length,
),
);
}
// 一个显示笔记的列表项
class NoteTile extends StatelessWidget {
const NoteTile({super.key});
[@override](/user/override)
Widget build(BuildContext context) => ListTile(
title: Text(context.note.name),
subtitle: Text(context.note.description),
onTap: () {
Pylon.push(context, NoteScreen(),
settings: RouteSettings(
name: "/note",
));
Conduit.modOr<int>((i) => (i ?? 0) + 1);
},
);
}
class NoteScreen extends StatelessWidget {
const NoteScreen({super.key});
[@override](/user/override)
Widget build(BuildContext context) => PylonPort<Note>(
tag: "note",
loading: const Scaffold(body: Center(child: CircularProgressIndicator())),
error: const Scaffold(body: Center(child: Text("Something went wrong"))),
builder: (context) => Scaffold(
appBar: AppBar(
title: Text(context.note.name),
),
body: Text(context.note.description),
floatingActionButton: FloatingActionButton(
onPressed: () {
Pylon.push(
context,
Pylon<Note>(
value: notes[(context.note.id + 1) % notes.length],
builder: (context) => NoteScreen(),
));
},
child: Icon(Icons.next_plan)),
),
);
}
更多关于Flutter 可管理状态 可以跨导航路由进行通信 插件pylon的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter 可管理状态 可以跨导航路由进行通信 插件pylon的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,使用第三方插件通常涉及添加依赖项、导入包以及调用插件提供的API。尽管pylon
插件的具体功能未知(由于描述为“undefined”),但我可以提供一个通用的模板代码示例,展示如何在Flutter项目中集成和使用一个假设的第三方插件。
步骤 1: 添加依赖项
首先,你需要在pubspec.yaml
文件中添加pylon
插件的依赖项。请注意,由于这是一个假设的插件,实际的依赖项名称和版本号可能会有所不同。你需要替换为实际的插件名称和版本号。
dependencies:
flutter:
sdk: flutter
pylon: ^x.y.z # 替换为实际的版本号
然后运行flutter pub get
来安装依赖项。
步骤 2: 导入包
在你的Dart文件中,你需要导入pylon
包。
import 'package:pylon/pylon.dart';
步骤 3: 使用插件功能
由于pylon
的具体功能未知,我将提供一个假设的示例代码,展示如何调用一个假设的插件方法。假设pylon
插件有一个名为performUnknownFunction
的方法。
import 'package:flutter/material.dart';
import 'package:pylon/pylon.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String result = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Pylon Plugin Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Result: $result',
style: TextStyle(fontSize: 20),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () async {
try {
// 调用假设的 performUnknownFunction 方法
var response = await Pylon.performUnknownFunction();
setState(() {
result = 'Response: $response';
});
} catch (e) {
setState(() {
result = 'Error: ${e.toString()}';
});
}
},
child: Text('Perform Unknown Function'),
),
],
),
),
);
}
}
在这个示例中,我们创建了一个简单的Flutter应用,其中包含一个按钮,当用户点击按钮时,会调用Pylon.performUnknownFunction()
方法(这是一个假设的方法名)。结果会显示在屏幕上。
注意事项
- 实际方法名与参数:由于
pylon
插件的具体功能未知,你需要查阅插件的官方文档以了解实际的方法名、参数以及返回值。 - 错误处理:在实际应用中,添加适当的错误处理是非常重要的,以便在插件调用失败时能够给用户一个友好的提示。
- 插件版本:确保你使用的是与你的Flutter SDK版本兼容的插件版本。
希望这个示例代码能帮助你开始使用pylon
插件,尽管其具体功能未知。一旦你有了更多关于插件的信息,你可以相应地调整代码。