i am a newbie in flutter, i use FadeTransistion, indexedStack and bottomNavigationBar to navigate tabs in my scaffold, but the it doesn't seem to affect my listview on 'page2', the list view become the background of 'page3' and 'page1' ( i set long duration for the fade and see it), how to make the listview disappear when i go to others tab?
Widget 'FadeIndexedStack' i reference from https://gist.github.com/diegoveloper/1cd23e79a31d0c18a67424f0cbdfd7ad, thank to the author
here is my code:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My app',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _currentIndex = 0;
List<BottomNavigationBarItem> items = [
BottomNavigationBarItem(icon: Icon(Icons.pages), label: 'page 1'),
BottomNavigationBarItem(icon: Icon(Icons.pages), label: 'page 2'),
BottomNavigationBarItem(icon: Icon(Icons.pages), label: 'page 3'),
];
@override
Widget build(BuildContext context) {
ColorScheme theme = Theme.of(context).colorScheme;
return Scaffold(
body: FadeIndexedStack(
index: _currentIndex,
children: [
page1(),
page2(),
page3(),
],
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
items: items,
backgroundColor: theme.primary,
selectedItemColor: theme.onPrimary,
showUnselectedLabels: false,
showSelectedLabels: true,
unselectedItemColor: theme.onPrimary.withOpacity(0.5),
onTap: (index) {
setState(() {
_currentIndex = index;
});
},
),
);
}
}
class page1 extends StatelessWidget {
const page1({super.key});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.amber,
child: Center(
child: Container(
width: 200,
height: 200,
color: Colors.red,
alignment: Alignment.center,
child: Text('page 1'),
),
),
);
}
}
class page2 extends StatelessWidget {
const page2({super.key});
@override
Widget build(BuildContext context) {
return ListView(
children: [
ListTile(
tileColor: Colors.blueAccent,
title: Text('page 2.1'),
shape: Border.symmetric(
horizontal: BorderSide(
color: Colors.black,
width: 1.0,
style: BorderStyle.solid,
),
),
),
ListTile(
tileColor: Colors.blueAccent,
title: Text('page 2.2'),
shape: Border.symmetric(
horizontal: BorderSide(
color: Colors.black,
width: 1.0,
style: BorderStyle.solid,
),
),
),
ListTile(
tileColor: Colors.blueAccent,
title: Text('page 2.3'),
shape: Border.symmetric(
horizontal: BorderSide(
color: Colors.black,
width: 1.0,
style: BorderStyle.solid,
),
),
),
],
);
}
}
class page3 extends StatelessWidget {
const page3({super.key});
@override
Widget build(BuildContext context) {
return Text(
'page 3',
style: TextStyle(fontSize: 30, color: Colors.red),
);
}
}
class FadeIndexedStack extends StatefulWidget {
int index;
List<Widget> children;
Duration duration;
FadeIndexedStack({
Key? key,
required this.index,
required this.children,
this.duration = const Duration(milliseconds: 3000),
});
@override
State<FadeIndexedStack> createState() => _FadeIndexedStackState();
}
class _FadeIndexedStackState extends State<FadeIndexedStack>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: widget.duration);
_controller.forward(from: 0.0);
}
@override
void didUpdateWidget(FadeIndexedStack old) {
super.didUpdateWidget(old);
if (widget.index != old.index) {
_controller.forward(from: 0.0);
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return FadeTransition(
opacity: _controller,
child: IndexedStack(
index: widget.index,
children: widget.children,
),
);
}
}
debug video: bug.gif
That's because the Stack
and IndexedStack
work in that way, all your widgets are rendered but one is on top of the other, you can uso Positioned.fill
on each of the children
of your IndexedStack
, like this:
FadeIndexedStack(
index: _currentIndex,
children: [
Positioned.fill(child: page1()),
Positioned.fill(child: page2()),
Positioned.fill(child: page3()),
],
),