构建小部件时如何控制null
Posted
技术标签:
【中文标题】构建小部件时如何控制null【英文标题】:How to control null when bulding widget 【发布时间】:2021-04-18 09:33:10 【问题描述】:您能告诉我如何在下一页包含 Image.file 的条件吗?我只想在 controller.image 为 not null 时构建它。
我收到一个错误: 在构建 Container(padding: EdgeInsets.all(32.0)) 时引发了以下 NoSuchMethodError: 在 null 上调用了方法“[]”。 接收方:空 尝试调用:
当我第一次重定向到这个页面时(并且 controller.image 为空):
class HomePage extends GetView<HomeController>
final myController1 = TextEditingController();
final myController2 = TextEditingController();
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text('Grobonet'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: <Widget>[
TextField(
controller: myController1,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Nazwisko'),
),
TextField(
controller: myController2,
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Miejscowosc'),
),
IconButton(
icon: Icon(
Icons.add,
size: 30,
),
onPressed: () =>
Get.toNamed(
AppRoutes.PICK_IMAGE
),
color: Colors.pink,
),
IconButton(
icon: Icon(
Icons.save_outlined,
size: 30,
),
/*onPressed: () =>
Get.toNamed(
AppRoutes.PICK_IMAGE
),*/
color: Colors.pink,
),
Container(
padding: EdgeInsets.all(32),
child: GetBuilder<HomeController>(
builder: (_)
return Image.file(controller.image);
,
),
),
]
),
),
);
控制器:
class HomeController extends GetxController
final image = Get.arguments['image'];
final file_loaded = Get.arguments['file_loaded'];
【问题讨论】:
【参考方案1】:您可以使用collection-if。只需像这样添加if (controller.image != null)
:
if (controller?.image != null)
Container(
padding: EdgeInsets.all(32),
child: GetBuilder<HomeController>(
builder: (_)
return Image.file(controller.image);
,
),
),
【讨论】:
这也可能引发错误。Null check on a null object
。如果控制器为空。
为了安全起见,我添加了条件成员访问权限。谢谢。
这仍然会引发异常:在构建 HomePage(dirty) 时引发了以下 NoSuchMethodError:在 null 上调用了方法“[]”。接收者:null 尝试调用:[]("image") 我添加了控制器代码以供参考【参考方案2】:
在控制器的 onInit() 方法中使用获取您的参数:
class HomeController extends GetxController
final File image;
final File file_loaded;
onInit()
image = Get.arguments['image'];
file_loaded = Get.arguments['file_loaded'];
这样,除了Get.arguments
实际为空之外,您不需要执行额外的空检查。
更新 你还需要像这样更新你的视图:
Container(
padding: EdgeInsets.all(32),
child: GetBuilder<HomeController>(
builder: (_)
return Image.file(_.image); // not return Image.file(controller.image);
// _ here is the instance of HomeController given by the GetBuilder
,
),
),
更新 2
正如您在 cmets 中提到的,您希望将数据从第二个页面 (OCRDetailsPage) 发送到先前打开的页面 (HomePage)。然后你不需要传递参数。您可以使用 Get.find()
在 OCRDetailsPage 中获取 HomeController 实例,然后设置变量并更新状态,如下所示:
class OCRDetailsPage extends StatelessWidget
@override
Widget build(BuildContext context)
final OCRDetailsController controller = Get.find();
return Scaffold(
appBar: AppBar(title: Text('OCR Details Page')),
body: Center(
child: FlatButton(
color: Colors.blue,
child: Icon(Icons.save_outlined),
onPressed: ()
final HomeController homeController = Get.find();
homeController.ocr_text = controller.text;
homeController.update();
Get.toNamed(
AppRoutes.HOME,
);
),
),
);
【讨论】:
我确实喜欢听从您的指导,但仍然遇到同样的错误。我不确定你是否理解一个问题,我有 2 个页面:主页和 OCR 详细信息 - 使用主页启动应用程序 - 进入 OCR 详细信息页面(显示 ocr 图像详细信息) - 在按下 OCR 详细信息上的按钮后,我想返回 ocr主页的图像详细信息所以第一次启动应用程序时出现空错误,因为 get.arguments 为空以上是关于构建小部件时如何控制null的主要内容,如果未能解决你的问题,请参考以下文章
如何构建一个在拉伸时显示更多按钮的 android 小部件?