user-interface - 如何将 Widget 注入自定义子 Widget 并使用子 Widgets 迭代索引?
问题描述
我正在构建一个颤振应用程序。我已经构建了一个带有构造函数的类。我制作了构造函数,以便可以自定义我的 ListTile,因为我将此类用于多个页面,并且每次都需要更改文本颜色,有时甚至需要添加一个 onTap 函数。
class AppList extends StatefulWidget {
@override
AppListState createState() => AppListState();
AppList({Key key, this.child}) : super(key: key);
final Widget child;
}
class AppListState extends State<AppList> {
Widget child;
List<Map<String, String>> _installedApps;
@override
void initState() {
super.initState();
}
getApps() {
setState(() {
installedApps = _installedApps;
getApp();
});
}
@override
Widget build(BuildContext context) {
if (installedApps == null)
getApps();
return ListView.builder(
itemCount: installedApps == null ? 0 : installedApps.length,
itemBuilder: (context, index) {
return child; //This is where the ListTile will go.
},
);
}
}
//Just in case you were confused, I used a plugin for some of the features
在我建立了这个类之后,我把它放在了我的示例类中。
示例类:
class Example extends StatefulWidget {
@override
ExampleState createState() => ExampleState();
}
class ExampleState extends State<Example> {
@override
Widget build(BuildContext context) {
return MaterialApp (
debugShowCheckedModeBanner: false,
home: Scaffold (
body: Container (
color: Colors.black,
child: AppList (
child: ListTile (
title: Text(installedApps[index]["app_name"]) //this is the text
),
)
)
),
);
}
}
然后,我在其中添加了一个 ListTile 和一个文本。但是当我在写文本时,我意识到我无法写出我想要的文本。这是因为示例类中没有定义“索引”。
有没有一种好方法可以将此文本放入我的示例类中?
完整代码:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'dart:io';
import 'package:flutter_appavailability/flutter_appavailability.dart';
void main() {
SystemChrome.setEnabledSystemUIOverlays([]);
runApp(Example());
}
Future<void> getApp() async {
if (Platform.isAndroid) {
installedApps = await AppAvailability.getInstalledApps();
print(await AppAvailability.checkAvailability("com.android.chrome"));
print(await AppAvailability.isAppEnabled("com.android.chrome"));
}
else if (Platform.isIOS) {
installedApps = iOSApps;
print(await AppAvailability.checkAvailability("calshow://"));
}
}
List<Map<String, String>> installedApp;
List<Map<String, String>> installedApps;
List<Map<String, String>> iOSApps = [
{
"app_name": "Calendar",
"package_name": "calshow://"
},
{
"app_name": "Facebook",
"package_name": "fb://"
},
{
"app_name": "Whatsapp",
"package_name": "whatsapp://"
}
];
class Example extends StatefulWidget {
@override
ExampleState createState() => ExampleState();
}
class ExampleState extends State<Example> {
@override
Widget build(BuildContext context) {
return MaterialApp (
debugShowCheckedModeBanner: false,
home: Scaffold (
body: Container (
color: Colors.black,
child: AppList ()
)
),
);
}
}
class AppList extends StatefulWidget {
@override
AppListState createState() => AppListState();
AppList({Key key, this.child}) : super(key: key);
final Widget child;
}
class AppListState extends State<AppList> {
Widget child;
List<Map<String, String>> _installedApps;
@override
void initState() {
super.initState();
}
getApps() {
setState(() {
installedApps = _installedApps;
getApp();
});
}
@override
Widget build(BuildContext context) {
if (installedApps == null)
getApps();
return ListView.builder(
itemCount: installedApps == null ? 0 : installedApps.length,
itemBuilder: (context, index) {
return ListTile (
title: Text(installedApps[index]["app_name"])
);
},
);
}
}
解决方案
除了将 Widget 传递给您的自定义 AppList,您还可以传递一个构建器函数,该函数返回一个 Widget 并根据需要获取参数,例如索引和所需的任何配置。类似于以下内容:
函数定义:
typedef Widget MyListTileBuilder(int index);
然后更改以下内容:
final Widget child;
到
final MyListTileBuilder childBuilder;
当然,您需要在示例类中实现您的构建器方法:
Widget MyListTileBuilderImplementation (int index) {
return ListTile (
title: Text(installedApps[index]["app_name"]) //this is the text
),
}
当您在示例类中构建 AppList 时,您会传递该方法
AppList (
childBuilder: MyListTileBuilderImplementation
)
最后在 AppList 中调用构建器,而不是添加子小部件:
itemBuilder: (context, index) {
return childBuilder(index); //This is where the ListTile will go.
},
您具有这些更改的完整代码如下所示(我不得不注释掉您未提供的参考资料):
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import 'dart:io';
//import 'package:flutter_appavailability/flutter_appavailability.dart';
typedef Widget MyListTileBuilder(int index);
void main() {
SystemChrome.setEnabledSystemUIOverlays([]);
runApp(Example());
}
Future<void> getApp() async {
if (Platform.isAndroid) {
//installedApps = await AppAvailability.getInstalledApps();
//print(await AppAvailability.checkAvailability("com.android.chrome"));
//print(await AppAvailability.isAppEnabled("com.android.chrome"));
}
else if (Platform.isIOS) {
installedApps = iOSApps;
//print(await AppAvailability.checkAvailability("calshow://"));
}
}
List<Map<String, String>> installedApp;
List<Map<String, String>> installedApps=[
{"app_name":"app1"},
{"app_name":"app2"},
{"app_name":"app3"},
];
List<Map<String, String>> iOSApps = [
{
"app_name": "Calendar",
"package_name": "calshow://"
},
{
"app_name": "Facebook",
"package_name": "fb://"
},
{
"app_name": "Whatsapp",
"package_name": "whatsapp://"
}
];
class Example extends StatefulWidget {
@override
ExampleState createState() => ExampleState();
}
class ExampleState extends State<Example> {
Widget MyListTileBuilderImplementation (int index) {
return ListTile (
title: Text(installedApps[index]["app_name"] + " index:" + index.toString()) //this is the text
);
}
@override
Widget build(BuildContext context) {
return MaterialApp (
debugShowCheckedModeBanner: false,
home: Scaffold (
body: Container (
color: Colors.white,
child: AppList (childBuilder: this.MyListTileBuilderImplementation)
)
),
);
}
}
class AppList extends StatefulWidget {
@override
AppListState createState() => AppListState();
AppList({Key key, this.childBuilder}) : super(key: key);
final MyListTileBuilder childBuilder;
}
class AppListState extends State<AppList> {
List<Map<String, String>> _installedApps;
@override
void initState() {
super.initState();
}
getApps() {
setState(() {
installedApps = _installedApps;
getApp();
});
}
@override
Widget build(BuildContext context) {
if (installedApps == null)
getApps();
return ListView.builder(
itemCount: installedApps == null ? 0 : installedApps.length,
itemBuilder: (context, index) {
return widget.childBuilder(index);
},
);
}
}
推荐阅读
- cmd - 如何从命令提示符接收 WM_COPYDATA?
- arrays - 快速将 Xml 解析为字典
- node.js - 在 nodejs 中存储 api 访问令牌的位置
- javascript - 如何使用地图为表格单元格生成唯一ID
- python - 如何扩展 django-allauth 的注册模型并添加名字和姓氏字段?
- android - Firebase 无法与 Firebase 服务器通信
- github-actions - FTP-Deploy-Action:致命:肮脏的存储库:有未提交的更改。退出
- python - Python:为什么使用 for 循环将其从列表类型打印为空白(已编辑:案例已解决)
- android - 为什么我得到这个意外的异常?
- hyperledger-fabric - UnhandledPromiseRejectionWarning:错误:找不到合同 ID 的详细信息