gpt4 book ai didi

flutter - 创建 StatefulWidget 时访问 Flutter 上下文

转载 作者:IT王子 更新时间:2023-10-29 06:52:50 27 4
gpt4 key购买 nike

我在初始化有状态小部件时无法访问服务对象。问题来自 context 对象在 initState 中不可用。

我正在使用 InheritedWidget 在我的 main.dart 文件中注入(inject)一个服务对象,就像这样

void main() async {
final sqflite.Database database = await _openDatabase('db.sqlite3');
runApp(
Services(
database: database,
child: MyApp(),
),
);
}

Services 对象非常简单。它的成员不仅仅是 database。这个想法是小部件不需要知道是否正在访问本地数据库、本地缓存或远程服务器。

class Services extends InheritedWidget {
final Database database;

const Services({
Key key,
@required Widget child,
@required this.database,
}) : assert(child != null),
assert(database != null),
super(key: key, child: child);

Future<List<models.Animal>> readAnimals() async {
return db.readAnimals(database: this.database);
}

@override
bool updateShouldNotify(InheritedWidget oldWidget) {
return false;
}

static Services of(BuildContext context) {
return context.inheritFromWidgetOfExactType(Services) as Services;
}
}

当我想从数据库中加载所有动物时,问题出现在我的 _HomePageState 状态中。我需要访问 Services 对象。我无法访问 initState 中的 Services 对象,所以我正在使用 didChangeDependencies。从堆栈中删除主页时会出现问题。似乎 didChangeDependences 被调用并且对上下文对象的访问是非法的。所以我创建了一个 _initialized 标志,我可以在 didChangeDependencies 中使用它来确保我只在第一次加载动物。 这看起来很不优雅。有没有更好的方法?

class _HomePageState extends State<HomePage> {
bool _initialized = false;
bool _loading = false;
List<Animal> _animals;

@override
Widget build(final BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(Strings.of(this.context).appName),
),
body: _HomeBody(
loading: this._loading,
animals: this._animals,
),
);
}

@override
void didChangeDependencies() {
super.didChangeDependencies();
if (!this._initialized) {
this._initialized = true;
this._loadAnimals();
}
}

void _loadAnimals() async {
this.setState(() {
this._loading = true;
this._animals = null;
});

final List<Animal> animals = await Services.of(this.context).readAnimals();

this.setState(() {
this._loading = false;
this._animals = animals;
});
}
}

最佳答案

对于这种情况,您可以使用 WidgetsBinding 实例的 addPostFrameCallback 在构建小部件后执行一些代码。

  _onLayoutDone(_) {
this._loadAnimals();
}

@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback(_onLayoutDone);
super.initState();
}

关于flutter - 创建 StatefulWidget 时访问 Flutter 上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56729848/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com