如何从调用构建器的位置访问 ListViewBuilder 中的变量?
How to access a variable inside a ListViewBuilder from where the builder is called?
我正在开发一个应用程序,该应用程序的表单使用 ListViewBuilder 作为项目列表,returns 一个小部件为列表中的每个项目显示一个 TextField。有没有办法从表单小部件本身访问任何项目的 TextField 控制器以获取新值?
ListView 构建器中使用的小部件
class BrandNamesWidget extends StatelessWidget {
BrandNamesWidget({Key? key, required this.brandName, required this.index})
: super(key: key);
final String brandName;
final int index;
final TextEditingController _brandNameController =
new TextEditingController();
@override
Widget build(BuildContext context) {
_brandNameController.text = brandName;
final deviceDimensions = Provider.of<Dimension>(context);
double height = deviceDimensions.getDeviceHeight();
double width = deviceDimensions.getDeviceWidth();
return TextField(
controller: _brandNameController,
cursorColor: Colors.black,
style: TextStyle(
color: AppInfo.MAIN_COLOR,
letterSpacing: 1.5,
),
keyboardType: TextInputType.text,
decoration: InputDecoration(
constraints: BoxConstraints(maxWidth: width * 0.45),
labelText: 'Brand name: ' + index.toString(),
prefixIcon: Icon(Icons.medication),
labelStyle: TextStyle(
fontSize: height * 0.03,
color: AppInfo.MAIN_COLOR,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
),
),
);
}
}
表单小部件
.
.
Container(
child: ListView.builder(
itemCount: _brandnames.length,
itemBuilder: (BuildContext ctx, int index) {
return BrandNamesWidget(
brandName: _brandnames[index].toString(),
index: index);
}),
),
// Want to access the _brandNameController.text here in a function to update firestore
.
.
我已经在线查看解决方案,我发现的唯一类似问题来自这个 Whosebug 问题 (Is there a way to access variables in a state in Flutter/Dart?)
一种方法是在 itemBuilder 中从外部实例化一个 TextEditingController 并将其注入到 BrandNamesWidget 中,将它们的引用保存在一个集合中,这样您就可以获取它们像这样的外部内容 Gist 我为您创建。这就是您的新 class 的样子:
class BrandNamesWidget extends StatelessWidget {
final TextEditingController? controller;
final String? brandName;
final int? index;
BrandNamesWidget({ this.brandName, required this.index, this.controller });
@override
Widget build(BuildContext context) {
double height = 100;
double width = MediaQuery.of(context).size.width;
return TextField(
controller: controller!,
keyboardType: TextInputType.text,
decoration: InputDecoration(
constraints: BoxConstraints(maxWidth: width * 0.45),
labelText: 'Brand name: ' + index.toString(),
prefixIcon: const Icon(Icons.medication),
labelStyle: TextStyle(
fontSize: height * 0.03,
color: Colors.grey,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
),
),
);
}
}
这是保留 TextEditingController 引用的父小部件,容纳您的 ListView.builder:
class MyWidget extends StatelessWidget {
List<String> _brandnames = ['Toyota', 'Honda', 'BMW', 'Mercedes'];
List<TextEditingController> controllers = [];
@override
Widget build(BuildContext context) {
controllers = [];
return Column(
children: [
Expanded(
child: Container(
child: ListView.builder(
itemCount: _brandnames.length,
itemBuilder: (BuildContext ctx, int index) {
TextEditingController ctrl = TextEditingController();
controllers.add(ctrl);
return BrandNamesWidget(
brandName: _brandnames[index].toString(),
controller: ctrl,
index: index);
}),
)
),
TextButton(
onPressed: () {
for(var ctrl in controllers) {
print(ctrl.text);
}
},
child: Text('Click me to get their values')
)
]
);
}
}
如果您在显示的文本字段中输入内容,然后单击我提供的按钮,您将从一个函数中获取它们的内容,从而能够更新 Firestore 或任何您想要的内容。检查一下并告诉我。
我正在开发一个应用程序,该应用程序的表单使用 ListViewBuilder 作为项目列表,returns 一个小部件为列表中的每个项目显示一个 TextField。有没有办法从表单小部件本身访问任何项目的 TextField 控制器以获取新值?
ListView 构建器中使用的小部件
class BrandNamesWidget extends StatelessWidget {
BrandNamesWidget({Key? key, required this.brandName, required this.index})
: super(key: key);
final String brandName;
final int index;
final TextEditingController _brandNameController =
new TextEditingController();
@override
Widget build(BuildContext context) {
_brandNameController.text = brandName;
final deviceDimensions = Provider.of<Dimension>(context);
double height = deviceDimensions.getDeviceHeight();
double width = deviceDimensions.getDeviceWidth();
return TextField(
controller: _brandNameController,
cursorColor: Colors.black,
style: TextStyle(
color: AppInfo.MAIN_COLOR,
letterSpacing: 1.5,
),
keyboardType: TextInputType.text,
decoration: InputDecoration(
constraints: BoxConstraints(maxWidth: width * 0.45),
labelText: 'Brand name: ' + index.toString(),
prefixIcon: Icon(Icons.medication),
labelStyle: TextStyle(
fontSize: height * 0.03,
color: AppInfo.MAIN_COLOR,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
),
),
);
}
}
表单小部件
.
.
Container(
child: ListView.builder(
itemCount: _brandnames.length,
itemBuilder: (BuildContext ctx, int index) {
return BrandNamesWidget(
brandName: _brandnames[index].toString(),
index: index);
}),
),
// Want to access the _brandNameController.text here in a function to update firestore
.
.
我已经在线查看解决方案,我发现的唯一类似问题来自这个 Whosebug 问题 (Is there a way to access variables in a state in Flutter/Dart?)
一种方法是在 itemBuilder 中从外部实例化一个 TextEditingController 并将其注入到 BrandNamesWidget 中,将它们的引用保存在一个集合中,这样您就可以获取它们像这样的外部内容 Gist 我为您创建。这就是您的新 class 的样子:
class BrandNamesWidget extends StatelessWidget {
final TextEditingController? controller;
final String? brandName;
final int? index;
BrandNamesWidget({ this.brandName, required this.index, this.controller });
@override
Widget build(BuildContext context) {
double height = 100;
double width = MediaQuery.of(context).size.width;
return TextField(
controller: controller!,
keyboardType: TextInputType.text,
decoration: InputDecoration(
constraints: BoxConstraints(maxWidth: width * 0.45),
labelText: 'Brand name: ' + index.toString(),
prefixIcon: const Icon(Icons.medication),
labelStyle: TextStyle(
fontSize: height * 0.03,
color: Colors.grey,
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
),
),
);
}
}
这是保留 TextEditingController 引用的父小部件,容纳您的 ListView.builder:
class MyWidget extends StatelessWidget {
List<String> _brandnames = ['Toyota', 'Honda', 'BMW', 'Mercedes'];
List<TextEditingController> controllers = [];
@override
Widget build(BuildContext context) {
controllers = [];
return Column(
children: [
Expanded(
child: Container(
child: ListView.builder(
itemCount: _brandnames.length,
itemBuilder: (BuildContext ctx, int index) {
TextEditingController ctrl = TextEditingController();
controllers.add(ctrl);
return BrandNamesWidget(
brandName: _brandnames[index].toString(),
controller: ctrl,
index: index);
}),
)
),
TextButton(
onPressed: () {
for(var ctrl in controllers) {
print(ctrl.text);
}
},
child: Text('Click me to get their values')
)
]
);
}
}
如果您在显示的文本字段中输入内容,然后单击我提供的按钮,您将从一个函数中获取它们的内容,从而能够更新 Firestore 或任何您想要的内容。检查一下并告诉我。