如何从底部导航栏打开底部模态弹窗?

huangapple go评论56阅读模式
英文:

How to open bottomModal sheet from bottom Navigation bar?

问题

在底部导航栏中,我有五个图标,其中四个打开不同的屏幕,我想让另一个打开showModalBottomSheet,但当我实现它并运行应用时,它显示错误,错误信息如下:

在构建期间调用了setState()或markNeedsBuild()。'package:flutter/src/widgets/navigator.dart':失败的断言:行2903位置18:'!navigator._debugLocked':不为真。

我还尝试使用WidgetsBinding.instance?.addPostFrameCallback((_),但它也显示错误,错误信息如下:

'此表达式的类型为'void',因此无法使用它。'

我该怎么办?

class BottomNavigationPage extends StatefulWidget {
  const BottomNavigationPage({Key? key}) : super(key: key);

  @override
  State<BottomNavigationPage> createState() => _BottomNavigationPageState();
}

class _BottomNavigationPageState extends State<BottomNavigationPage> {
  int currentIndex = 1;

  @override
  Widget build(BuildContext context) {
    List<Widget> body = [
      showModalBottomSheet(
          context: context,
          builder: (BuildContext context) {
            return const Containers(
              height: 400,
              color: Colors.green,
            );
          }),
      const Containers(
        height: 400,
        color: Colors.red,
      ),
      const Dashboard(),
      const DepartmentPage(),
      const Dashboard(),
      const DepartmentPage(),
    ];
    return Scaffold(
      body: Center(
        child: body[currentIndex],
      ),
      bottomNavigationBar: BottomNavigationBar(
        //showUnselectedLabels: true,
        selectedItemColor: AppColor.btnColor,
        selectedIconTheme: const IconThemeData(color: AppColor.btnColor),
        unselectedItemColor: Colors.black45,
        showSelectedLabels: true,
        currentIndex: currentIndex,
        onTap: (int newindex) {
          setState(() {
            currentIndex = newindex;
          });
        },
        items: const [
          BottomNavigationBarItem(
            label: '',
            activeIcon: Icon(
              Icons.menu,
              color: AppColor.btnColor,
              size: 30,
            ),
            icon: Icon(
              Icons.menu,
              size: 30,
            ),
          ),
          BottomNavigationBarItem(
            activeIcon: Icon(
              Icons.home,
              size: 30,
            ),
            label: 'होम',
            icon: Icon(
              Icons.home,
              size: 30,
            ),
          ),
          BottomNavigationBarItem(
            activeIcon: Icon(
              Icons.people,
              size: 30,
            ),
            label: 'शाखा हरु ',
            icon: Icon(
              Icons.people,
              size: 30,
            ),
          ),
          BottomNavigationBarItem(
            label: 'सूचना हरु',
            activeIcon: Icon(
              Icons.task,
              size: 30,
            ),
            icon: Icon(
              Icons.task,
              size: 30,
            ),
          ),
          BottomNavigationBarItem(
            activeIcon: Icon(
              Icons.task,
              size: 30,
            ),
            label: 'सूचना हरु',
            icon: Icon(
              Icons.task,
              size: 30,
            ),
          ),
        ],
      ),
    );
  }
}
英文:

In my bottom navigation bar I have five icons, four of them opens 4 different screens and I want another one to open showModalBottomSheet, but when I implemented it and ran the app it shows error saying

> setState() or markNeedsBuild() called during build. and 'package:flutter/src/widgets/navigator.dart': Failed assertion: line
> 2903 pos 18: '!navigator._debugLocked': is not true.

I aslo tried using WidgetsBinding.instance?.addPostFrameCallback((_) but it also shows error saying 'This expression has a type of 'void' so its value can't be used.'
what should i do??

class BottomNavigationPage extends StatefulWidget {
const BottomNavigationPage({Key? key}) : super(key: key);
@override
State&lt;BottomNavigationPage&gt; createState() =&gt; _BottomNavigationPageState();
}
class _BottomNavigationPageState extends State&lt;BottomNavigationPage&gt; {
int currentIndex = 1;
@override
Widget build(BuildContext context) {
List body = [
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return const Containers(
height: 400,
color: Colors.green,
);
}),
const Containers(
height: 400,
color: Colors.red,
),
const Dashboard(),
const DepartmentPage(),
const Dashboard(),
const DepartmentPage(),
];
return Scaffold(
body: Center(
child: body[currentIndex],
),
bottomNavigationBar: BottomNavigationBar(
//showUnselectedLabels: true,
selectedItemColor: AppColor.btnColor,
selectedIconTheme: const IconThemeData(color: AppColor.btnColor),
unselectedItemColor: Colors.black45,
showSelectedLabels: true,
currentIndex: currentIndex,
onTap: (int newindex) {
setState(() {
currentIndex = newindex;
});
},
items: const [
BottomNavigationBarItem(
label: &#39;&#39;,
activeIcon: Icon(
Icons.menu,
color: AppColor.btnColor,
size: 30,
),
icon: Icon(
Icons.menu,
size: 30,
),
),
BottomNavigationBarItem(
activeIcon: Icon(
Icons.home,
size: 30,
),
label: &#39;होम&#39;,
icon: Icon(
Icons.home,
size: 30,
),
),
BottomNavigationBarItem(
activeIcon: Icon(
Icons.people,
size: 30,
),
label: &#39;शाखा हरु &#39;,
icon: Icon(
Icons.people,
size: 30,
),
),
BottomNavigationBarItem(
label: &#39;सूचना हरु&#39;,
activeIcon: Icon(
Icons.task,
size: 30,
),
icon: Icon(
Icons.task,
size: 30,
),
),
BottomNavigationBarItem(
activeIcon: Icon(
Icons.task,
size: 30,
),
label: &#39;सूचना हरु&#39;,
icon: Icon(
Icons.task,
size: 30,
),
),
],
),
);
}
}

答案1

得分: 2

你不必将 showModalBottomSheet 添加到 body 列表中。您可以在点击 BottomNavigationBarItem 时检查 newindex == 0,然后显示它。试试这个:

class BottomNavigationPage extends StatefulWidget {
  const BottomNavigationPage({Key? key}) : super(key: key);

  @override
  State<BottomNavigationPage> createState() => _BottomNavigationPageState();
}

class _BottomNavigationPageState extends State<BottomNavigationPage> {
  int currentIndex = 1;

  @override
  Widget build(BuildContext context) {
    List body = [
      const Containers(
        height: 400,
        color: Colors.red,
      ),
      const Dashboard(),
      const DepartmentPage(),
      const Dashboard(),
      const DepartmentPage(),
    ];
    return Scaffold(
      body: Center(
        child: body[currentIndex-1],
      ),
      bottomNavigationBar: BottomNavigationBar(
        //showUnselectedLabels: true,
        selectedItemColor: AppColor.btnColor,
        selectedIconTheme: const IconThemeData(color: AppColor.btnColor),
        unselectedItemColor: Colors.black45,
        showSelectedLabels: true,
        currentIndex: currentIndex,
        onTap: (int newindex) {
          if (newindex == 0) {
            showModalBottomSheet(
              context: context,
              builder: (BuildContext context) {
                return const Containers(
                  height: 400,
                  color: Colors.green,
                );
              }
            );
          } else {
            setState(() {
              currentIndex = newindex;
            });
          }
        },
        items: const [
          BottomNavigationBarItem(
            label: '',
            activeIcon: Icon(
              Icons.menu,
              color: AppColor.btnColor,
              size: 30,
            ),
            icon: Icon(
              Icons.menu,
              size: 30,
            ),
          ),
          BottomNavigationBarItem(
            activeIcon: Icon(
              Icons.home,
              size: 30,
            ),
            label: 'होम',
            icon: Icon(
              Icons.home,
              size: 30,
            ),
          ),
          BottomNavigationBarItem(
            activeIcon: Icon(
              Icons.people,
              size: 30,
            ),
            label: 'शाखा हरु ',
            icon: Icon(
              Icons.people,
              size: 30,
            ),
          ),
          BottomNavigationBarItem(
            label: 'सूचना हरु',
            activeIcon: Icon(
              Icons.task,
              size: 30,
            ),
            icon: Icon(
              Icons.task,
              size: 30,
            ),
          ),
          BottomNavigationBarItem(
            activeIcon: Icon(
              Icons.task,
              size: 30,
            ),
            label: 'सूचना हरु',
            icon: Icon(
              Icons.task,
              size: 30,
            ),
          ),
        ],
      ),
    );
  }
}
英文:

You don't have to add the showModalBottomSheet to the body list. You can check if newindex == 0 when a BottomNavigationBarItem is tapped and then show it. Try this

class BottomNavigationPage extends StatefulWidget {
const BottomNavigationPage({Key? key}) : super(key: key);
@override
State&lt;BottomNavigationPage&gt; createState() =&gt; _BottomNavigationPageState();
}
class _BottomNavigationPageState extends State&lt;BottomNavigationPage&gt; {
int currentIndex = 1;
@override
Widget build(BuildContext context) {
List body = [
const Containers(
height: 400,
color: Colors.red,
),
const Dashboard(),
const DepartmentPage(),
const Dashboard(),
const DepartmentPage(),
];
return Scaffold(
body: Center(
child: body[currentIndex-1],
),
bottomNavigationBar: BottomNavigationBar(
//showUnselectedLabels: true,
selectedItemColor: AppColor.btnColor,
selectedIconTheme: const IconThemeData(color: AppColor.btnColor),
unselectedItemColor: Colors.black45,
showSelectedLabels: true,
currentIndex: currentIndex,
onTap: (int newindex) {
if (newindex == 0) {
showModalBottomSheet(
context: context,
builder: (BuildContext context) {
return const Containers(
height: 400,
color: Colors.green,
);
}
);
} else {
setState(() {
currentIndex = newindex;
});
}
},
items: const [
BottomNavigationBarItem(
label: &#39;&#39;,
activeIcon: Icon(
Icons.menu,
color: AppColor.btnColor,
size: 30,
),
icon: Icon(
Icons.menu,
size: 30,
),
),
BottomNavigationBarItem(
activeIcon: Icon(
Icons.home,
size: 30,
),
label: &#39;होम&#39;,
icon: Icon(
Icons.home,
size: 30,
),
),
BottomNavigationBarItem(
activeIcon: Icon(
Icons.people,
size: 30,
),
label: &#39;शाखा हरु &#39;,
icon: Icon(
Icons.people,
size: 30,
),
),
BottomNavigationBarItem(
label: &#39;सूचना हरु&#39;,
activeIcon: Icon(
Icons.task,
size: 30,
),
icon: Icon(
Icons.task,
size: 30,
),
),
BottomNavigationBarItem(
activeIcon: Icon(
Icons.task,
size: 30,
),
label: &#39;सूचना हरु&#39;,
icon: Icon(
Icons.task,
size: 30,
),
),
],
),
);
}
}

huangapple
  • 本文由 发表于 2023年2月27日 14:34:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75577377.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定