如何等待异步方法导致颤振



目前我和我的团队成员正在移动应用程序中工作。这些应用程序包含五页。在所有五个页面中,我们都有一个底部抽屉来显示应用程序列表。实际上,我们使用flutter的installed_apps包来显示已安装应用程序的列表。但这里的主要问题是……为了避免代码冗余,我们将底层抽屉代码重构为一个单独的bottom_drawer_class小部件。但这里的问题是如果我们使用单独的文件,异步服务方法会返回空的应用程序列表。如果我们将bottomdrawer.class嵌入到主dart文件中,那么它可以很好地工作。我们不知道如何摆脱它。

我们的代码:如果我们不重构main.dart文件

import 'package:bottom_drawer/bottom_drawer.dart';
import 'package:flutter/material.dart';
import 'dart:typed_data';
import 'package:installed_apps/installed_apps.dart';
import 'package:installed_apps/app_info.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final double _headerHeight = 60.0;
final double _bodyHeight = 300.0;
final BottomDrawerController _controller = BottomDrawerController();
List listApps = [];
@override
void initState() {
super.initState();
_getApp();
}
void _getApp() async {
List<AppInfo> apps = await InstalledApps.getInstalledApps(true, true);
for (var app in apps) {
var item = AppModel(
title: app.name!,
package: app.getVersionInfo(),
icon: app.icon!,
);
listApps.add(item);
}
print(listApps.length);
//reloading state
setState(() {});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Bottom drawer example app'),
),
body: Stack(
children: [
_buildBottomDrawer(context),
],
),
),
);
}
Widget _buildBottomDrawer(BuildContext context) {
return BottomDrawer(
header: _buildBottomDrawerHead(context),
body: _buildBottomDrawerBody(context),
headerHeight: _headerHeight,
drawerHeight: _bodyHeight,
color: Colors.white,
controller: _controller,
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 10,
spreadRadius: 3,
offset: Offset(5, -2), // changes position of shadow
),
],
);
}
Widget _buildBottomDrawerHead(BuildContext context) {
return Container(
height: _headerHeight,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(45)),
),
child: Column(
children: const [
Padding(
padding: EdgeInsets.only(
left: 0.0,
right: 160.0,
top: 27.0,
),
child: Text(
"Most frequently used apps",
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
fontFamily: 'inter'),
),
),
Spacer(),
Divider(
height: 0.1,
thickness: 4,
color: Colors.black12,
),
],
),
);
}
Widget _buildBottomDrawerBody(BuildContext context) {
return SizedBox(
width: double.infinity,
height: _bodyHeight,
child: ListView.builder(
itemCount: listApps.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int i) => Column(
children: [
Container(
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
width: .1,
),
),
),
child: ListTile(
leading: Image.memory(listApps[i].icon),
title: Text(listApps[i].title),
subtitle: Text(listApps[i].package),
trailing: const Icon(Icons.timer),
visualDensity: const VisualDensity(vertical: -1),
),
),
],
),
),
);
}
}
class AppModel {
final String title;
final String package;
final Uint8List icon;
AppModel({required this.title, required this.package, required this.icon});
}

它将给出所需的结果列表。但是,如果我们在单独的文件中重构代码,那么列表仍然是空的。重构文件main.dart

import 'package:flutter/material.dart';
import 'bottom_drawer_class.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Bottom drawer example app'),
),
body: Stack(
children: const [
BottomDrawerGeneral(),
],
),
),
);
}
}

bottom_drawer_class.dart

import 'package:flutter/material.dart';
import 'package:bottom_drawer/bottom_drawer.dart';
import 'dart:typed_data';
import 'package:installed_apps/installed_apps.dart';
import 'package:installed_apps/app_info.dart';
class BottomDrawerGeneral extends StatefulWidget {
const BottomDrawerGeneral({Key? key}) : super(key: key);
@override
State<BottomDrawerGeneral> createState() => BottomDrawerGeneralState();
}
class BottomDrawerGeneralState extends State<BottomDrawerGeneral> {
final double _headerHeight = 60.0;
final double _bodyHeight = 300.0;
final BottomDrawerController _controller = BottomDrawerController();
List listApps = [];
void _getApp() async {
List<AppInfo> apps = await InstalledApps.getInstalledApps(true, true);
for (var app in apps) {
var item = AppModel(
title: app.name!,
package: app.getVersionInfo(),
icon: app.icon!,
);
listApps.add(item);
}
//reloading state
}
@override
void initState() {
super.initState();
_getApp();
}
@override
Widget build(BuildContext context) {
return BottomDrawer(
header: _buildBottomDrawerHead(context),
body: _buildBottomDrawerBody(context),
headerHeight: _headerHeight,
drawerHeight: _bodyHeight,
color: Colors.white,
controller: _controller,
boxShadow: const [
BoxShadow(
color: Colors.black12,
blurRadius: 10,
spreadRadius: 3,
offset: Offset(5, -2), // changes position of shadow
),
],
);
}
Widget _buildBottomDrawerHead(BuildContext context) {
return Container(
height: _headerHeight,
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(45)),
),
child: Column(
children: const [
Padding(
padding: EdgeInsets.only(
left: 0.0,
right: 160.0,
top: 27.0,
),
child: Text(
"Most frequently used apps",
style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 16,
fontFamily: 'inter'),
),
),
Spacer(),
Divider(
height: 0.1,
thickness: 4,
color: Colors.black12,
),
],
),
);
}
Widget _buildBottomDrawerBody(BuildContext context) {
print(listApps.length);
return SizedBox(
width: double.infinity,
height: _bodyHeight,
child: listApps.isNotEmpty
? ListView.builder(
itemCount: listApps.length,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int i) => Column(
children: [
Container(
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
width: .1,
),
),
),
child: ListTile(
leading: Image.memory(listApps[i].icon),
title: Text(listApps[i].title),
subtitle: Text(listApps[i].package),
trailing: const Icon(Icons.timer),
visualDensity: const VisualDensity(vertical: -1),
),
)
],
),
)
: ListView.builder(
itemCount: 10,
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemBuilder: (BuildContext context, int i) => Column(
children: [
Container(
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
width: .1,
),
),
),
child: const ListTile(
leading: Icon(Icons.app_registration),
title: Text("listApps[i].title"),
subtitle: Text("listApps[i].package"),
trailing: Icon(Icons.timer),
visualDensity: VisualDensity(vertical: -1),
),
)
],
),
));
}
}
class AppModel {
final String title;
final String package;
final Uint8List icon;
AppModel({required this.title, required this.package, required this.icon});
}

专家可以帮我解决问题:(。。如果您找到了解决方案,请用我们的重构方法解释问题。

在提取的小部件中,一个设置状态缺少

void _getApp() async {
List<AppInfo> apps = await InstalledApps.getInstalledApps(true, true);
for (var app in apps) {
var item = AppModel(
title: app.name!,
package: app.getVersionInfo(),
icon: app.icon!,
);
listApps.add(item);
}
setState((){}}; //<--- here
}

最新更新