Dart无法识别同文件中声明的_movies变量问题求助
解决Dart报错:Undefined name '_movies'
问题原因
_movies是在MovieListWidget(StatefulWidget类)中声明的私有变量(以下划线_开头),根据Dart的访问规则,私有成员仅能在其定义的类内部访问,_MovieListWidgetState是独立类,无法直接读取父Widget的私有变量。- 附带问题:
ListView.builder的itemCount参数你传入了列表对象_movies,但该参数要求传入整数类型的列表长度,正确写法应为_movies.length。
修复方案
推荐两种常用修复方式:
方式1:将变量改为公开,通过widget访问
把MovieListWidget中的_movies去掉下划线改为公开变量,在State类里通过widget.movies访问,同时可以利用movie对象动态填充UI内容(替代原代码中的硬编码文本):
import 'package:flutter/material.dart'; import '../../resources/resources.dart'; class Movie { final String imageName; final String title; final String time; final String description; Movie({ required this.imageName, required this.title, required this.time, required this.description, }); } class MovieListWidget extends StatefulWidget { // 去掉下划线,改为公开变量 final movies = [ Movie( imageName: AppImages.moviePlacholder, title: 'TOP GUN', time: 'April 7, 2021', description: 'Fhjshfkhfdkhskjhkjsdhfkjsdhfjhsdfkjhsdkjfhskjdhfkjsdhfjsdhfkjhsdfjhsdkjfhskhdfksdhfkjdshfkjhsdkjfhskjdfhskjdhfkjshdfkjhsdkjfhskjdfhksjhfjdhgfkjshgkjdhjghfjksdhkjgfdhgjkhdgkjhdskghsfjghsdfhgairhe') ]; MovieListWidget({super.key}); @override State<MovieListWidget> createState() => _MovieListWidgetState(); } class _MovieListWidgetState extends State<MovieListWidget> { @override Widget build(BuildContext context) { return ListView.builder( // 修正为获取列表长度 itemCount: widget.movies.length, itemExtent: 163, itemBuilder: (BuildContext context, int index) { final movie = widget.movies[index]; return Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), child: Stack( children: [ Container( decoration: BoxDecoration( color: Colors.white, borderRadius: const BorderRadius.all(Radius.circular(10)), border: Border.all(color: Colors.black.withOpacity(0.2)), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 8, offset: const Offset(2, 2)), ]), clipBehavior: Clip.hardEdge, child: Row( children: [ // 使用movie对象的imageName Image(image: AssetImage(movie.imageName)), Expanded( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 20), Text( movie.title, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(fontWeight: FontWeight.bold), ), const SizedBox(height: 5), Text( movie.time, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(color: Colors.grey), ), const SizedBox(height: 20), Text( movie.description, maxLines: 2, overflow: TextOverflow.ellipsis, ), ], ), ), ) ], ), ), Material( color: Colors.transparent, child: InkWell( borderRadius: BorderRadius.circular(10), onTap: () { debugPrint('URURURURU'); }, ), ) ], ), ); }); } }
方式2:将变量移至State类内部
如果电影列表是MovieListWidget的内部固定数据,直接把_movies移到_MovieListWidgetState类中,这样可以直接访问私有变量:
import 'package:flutter/material.dart'; import '../../resources/resources.dart'; class Movie { final String imageName; final String title; final String time; final String description; Movie({ required this.imageName, required this.title, required this.time, required this.description, }); } class MovieListWidget extends StatefulWidget { MovieListWidget({super.key}); @override State<MovieListWidget> createState() => _MovieListWidgetState(); } class _MovieListWidgetState extends State<MovieListWidget> { // 将_movies移到State类内部 final _movies = [ Movie( imageName: AppImages.moviePlacholder, title: 'TOP GUN', time: 'April 7, 2021', description: 'Fhjshfkhfdkhskjhkjsdhfkjsdhfjhsdfkjhsdkjfhskjdhfkjsdhfjsdhfkjhsdfjhsdkjfhskhdfksdhfkjdshfkjhsdkjfhskjdfhskjdhfkjshdfkjhsdkjfhskjdfhksjhfjdhgfkjshgkjdhjghfjksdhkjgfdhgjkhdgkjhdskghsfjghsdfhgairhe') ]; @override Widget build(BuildContext context) { return ListView.builder( // 直接访问并修正为列表长度 itemCount: _movies.length, itemExtent: 163, itemBuilder: (BuildContext context, int index) { final movie = _movies[index]; // 后续UI代码同上,使用movie对象填充内容 return Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), child: Stack( // ... 原UI代码 ), ); }); } }
额外说明
Dart的下划线私有规则是库级私有(同一文件内的类理论上可以访问,但不符合官方规范),官方推荐的最佳实践是:
- 父Widget的公开数据通过
widget.xxx访问 - 仅State内部使用的私有数据,直接定义在State类中
内容的提问来源于stack exchange,提问作者Lll Cilician
相关产品推荐
相关产品推荐

