为什么flutter在基于索引抓取子对象时抛出无效参数



好的,所以我目前正在使用PageBuilder,我所做的工作很有效,但我真的不喜欢滑动物理。我宁愿让他们点击底部的应用程序栏进行导航。

工作代码

class Home extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _HomeState();
}
}
class _HomeState extends State<Home> {
int selectedIndex = 0;
PageController controller = PageController();
List<GButton> tabs = new List();
final List<Widget> _children = [
Settings(),
ListFamily(),
CameraScreen(),
SplashAccount(),
Questions()
];
@override
void initState() {
super.initState();
var padding = EdgeInsets.symmetric(horizontal: 18, vertical: 5);
double gap = 10;
tabs.add(GButton(
gap: gap,
iconActiveColor: maincolor,
iconColor: Colors.grey,
textColor: maincolor,
iconSize: 24,
padding: padding,
icon: Icons.settings,
// textStyle: t.textStyle,
text: 'Settings',
));
tabs.add(GButton(
gap: gap,
iconActiveColor: maincolor,
iconColor: Colors.grey,
textColor: maincolor,
iconSize: 24,
padding: padding,
icon: Icons.wc,
// textStyle: t.textStyle,
text: 'Relations',
));
tabs.add(GButton(
gap: gap,
iconActiveColor: maincolor,
iconColor: Colors.grey,
textColor: maincolor,
iconSize: 24,
padding: padding,
icon: Icons.camera_alt,
// textStyle: t.textStyle,
text: 'Camera',
));
tabs.add(GButton(
gap: gap,
iconActiveColor: maincolor,
iconColor: Colors.grey,
textColor: maincolor,
iconSize: 24,
padding: padding,
icon: Icons.video_library,
// textStyle: t.textStyle,
text: 'Videos',
));
tabs.add(GButton(
gap: gap,
iconActiveColor: maincolor,
iconColor: Colors.grey,
textColor: maincolor,
iconSize: 24,
padding: padding,
icon: Icons.question_answer,
// textStyle: t.textStyle,
text: 'Questions',
));
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
extendBody: true,
body: PageView.builder(
onPageChanged: (page) {
setState(() {
selectedIndex = page;
});
},
controller: controller,
itemBuilder: (context, position) {
return Column(
children: <Widget>[
Expanded(child: _children[position]),
Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
bottomLeft: Radius.zero,
bottomRight: Radius.zero),
boxShadow: [
BoxShadow(
spreadRadius: -10,
blurRadius: 60,
color: Colors.black.withOpacity(.20),
offset: Offset(0, 15))
]),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child: GNav(
tabs: tabs,
selectedIndex: selectedIndex,
onTabChange: (index) {
print(index);
setState(() {
selectedIndex = index;
});
}),
),
),
],
);
},
itemCount: tabs.length, // Can be null
),
),
);
}
}

无效参数代码

class Home extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _HomeState();
}
}
class _HomeState extends State<Home> {
int selectedIndex = 0;
PageController controller = PageController();
List<GButton> tabs = new List();
final List<Widget> _children = [
Settings(),
Container(),
Container(),
Container(),
Container()
];
@override
void initState() {
super.initState();
var padding = EdgeInsets.symmetric(horizontal: 18, vertical: 5);
double gap = 10;
tabs.add(GButton(
gap: gap,
iconActiveColor: maincolor,
iconColor: Colors.grey,
textColor: maincolor,
iconSize: 24,
padding: padding,
icon: Icons.settings,
// textStyle: t.textStyle,
text: 'Settings',
));
tabs.add(GButton(
gap: gap,
iconActiveColor: maincolor,
iconColor: Colors.grey,
textColor: maincolor,
iconSize: 24,
padding: padding,
icon: Icons.wc,
// textStyle: t.textStyle,
text: 'Relations',
));
tabs.add(GButton(
gap: gap,
iconActiveColor: maincolor,
iconColor: Colors.grey,
textColor: maincolor,
iconSize: 24,
padding: padding,
icon: Icons.camera_alt,
// textStyle: t.textStyle,
text: 'Camera',
));
tabs.add(GButton(
gap: gap,
iconActiveColor: maincolor,
iconColor: Colors.grey,
textColor: maincolor,
iconSize: 24,
padding: padding,
icon: Icons.video_library,
// textStyle: t.textStyle,
text: 'Videos',
));
tabs.add(GButton(
gap: gap,
iconActiveColor: maincolor,
iconColor: Colors.grey,
textColor: maincolor,
iconSize: 24,
padding: padding,
icon: Icons.question_answer,
// textStyle: t.textStyle,
text: 'Questions',
));
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
extendBody: true,
body: Column(
children: <Widget>[
// _children[selectedIndex] will cause the Invalid Argument(s) error here.
Expanded(child: _children[selectedIndex]),
Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12),
topRight: Radius.circular(12),
bottomLeft: Radius.zero,
bottomRight: Radius.zero),
boxShadow: [
BoxShadow(
spreadRadius: -10,
blurRadius: 60,
color: Colors.black.withOpacity(.20),
offset: Offset(0, 15))
]),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child: GNav(
tabs: tabs,
selectedIndex: selectedIndex,
onTabChange: (index) {
print(index);
setState(() {
selectedIndex = index;
});
}),
),
),
],
)));
}
}

我目前只使用Flutter的材料库和这个插件:https://github.com/sooxt98/google_nav_bar

此外,我也在其他底部导航栏中尝试过,我只是不明白为什么会发生这种情况

工作代码中的孩子是我的其他页面。设置页面代码如下:

class Settings extends StatefulWidget {
@override
_SettingsPageState createState() => _SettingsPageState();
}
class _SettingsPageState extends State<Settings> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
// Logo + Container
Container(
color: thirdcolor,
child: Center(
child: SafeArea(
child: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(
"assets/mvvdesign/Solid/White/horizontal/logo.png"),
fit: BoxFit.fitWidth)),
),
),
),
),
// Container for Questions bar
Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"SETTINGS",
style: TextStyle(
color: Colors.white,
fontSize: fontsize,
fontFamily: fontfamily,
fontWeight: FontWeight.w300),
),
Container(
margin: const EdgeInsets.only(top: 10.0),
color: Colors.white,
child: Divider(
height: 5.0,
thickness: 3.0,
endIndent: 100.0,
indent: 100.0,
color: Colors.white,
),
),
],
),
),
],
),
),
Container(
margin: const EdgeInsets.only(top: 20.0),
child: Column(
children: <Widget>[
Container(
height: 60,
width: MediaQuery.of(context).size.width - 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
border: Border.all(color: Colors.white, width: 2.0)),
child: Center(
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Hey, ",
style: TextStyle(
fontSize: 24.0,
color: Colors.white,
),
),
Text(
"Alyssa Thurman",
style: TextStyle(
fontSize: 24.0,
color: Colors.green,
fontWeight: FontWeight.bold),
),
],
),
),
),
margin: const EdgeInsets.only(bottom: 10.0),
),
],
),
),
Expanded(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
width: 360.0,
height: 56.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.white),
margin: const EdgeInsets.only(top: 20.0),
child: Center(
child: Text(
"Update Account Information",
style: TextStyle(fontSize: 24.0, color: maincolor),
)),
),
Container(
width: 360.0,
height: 56.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.white),
margin: const EdgeInsets.only(top: 40.0),
child: Center(
child: Text(
"Terms and Conditions",
style: TextStyle(fontSize: 24.0, color: maincolor),
)),
),
Container(
width: 360.0,
height: 56.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.white),
margin: const EdgeInsets.only(top: 40.0),
child: Center(
child: Text(
"Privacy Policy",
style: TextStyle(fontSize: 24.0, color: maincolor),
)),
),
Container(
width: 360.0,
height: 56.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.white),
margin: const EdgeInsets.only(top: 40.0),
child: Center(
child: Text(
"Manage Membership",
style: TextStyle(fontSize: 24.0, color: maincolor),
)),
),
Container(
width: 360.0,
height: 56.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.red),
margin: const EdgeInsets.only(top: 40.0, bottom: 40.0),
child: InkWell(
onTap: () async {
await OneSignal.shared.logoutEmail();
SharedPreferences prefs =
await SharedPreferences.getInstance();
prefs.remove('accesstoken');
prefs.remove('refreshtoken');
prefs.remove('email');
Navigator.push(
context,
MaterialPageRoute(builder: (context) => First()),
);
},
child: Center(
child: Text(
"LOGOUT",
style:
TextStyle(fontSize: 24.0, color: Colors.white),
)),
),
),
],
),
),
)
],
),
),
),
resizeToAvoidBottomPadding: false,
backgroundColor: thirdcolor,
);
}
}

错误日志:https://pastebin.com/raw/Regkgcqk

EDIT:我弄清楚了为什么它不起作用(相当确定(。我有一个函数,它从持久存储中获取保存的索引值,并在初始化状态时将selectedIndex设置为该值。

但是,当保存的索引被抓取时,它会返回一个null值(因为它还没有被设置(。因此,它将这个null值传递给selectedIndex,随后也传递给生成器;导致无效参数错误,因为索引不能为null。

上面错误的代码中没有包含有问题的函数,因此这两个代码段都应该有效。它对我不起作用的原因可能是因为索引被缓存了,并且它认为每次重新加载状态时索引都是null。

替代解决方案

使用页面视图生成器并根据您的偏好设置属性。

我的偏好:PageView.builder((内部

physics: NeverScrollableScrollPhysics()

最新更新