Reputation: 939
My situation is a bit tedious. I am pushing 2 pages to navigator
A - B
B is pushed latest.
For some reasons. I dont want to pop B to navigate from B to A. I want to replace / swap them. The reasons are due to states. I want to keep the states of both A and B pages as there are some widgets which are extremely costly to build (Unity view widget). From B how can I use Navigator so that without destroying my pages I can swap B with A?
Here is the flow:
A opens as the default page.
B is pushed with
Navigator.of(context).pushNamed();
Page Stack is A - B
From B I want to navigate to A while still keeping the B page alive.
-After some magical operations I am missing -
Page Stack is B - A. The user sees the page A. None of the pages were destroyed. They were swapped.
Is there a way to do this in Flutter?
Upvotes: 8
Views: 1551
Reputation: 305
PageView , ListView and GridView builders are designed for high number of objects. And rebuild when scrolling
Column or Row save all their children builds.
Yo can try :
SingleChildScrollView(NeverScrollable) -> Row -> A(equal screen size) and B(same)
And than animate or jump to :
For A offset 0 and for B offset screen width.
I have try, works fine
///
class AtoBExample extends StatefulWidget {
@override
_AtoBExampleState createState() => _AtoBExampleState();
}
class _AtoBExampleState extends State<AtoBExample> {
ScrollController scrollController = ScrollController();
_toB() {
// !!! Forward or any operations animations in here
// e.g animate A's opacity 1 to 0 and wait finish
scrollController.jumpTo(MediaQuery.of(context).size.width);
// And animate B's opacity 0 to 1
}
_toA() {
// !!! Forward or any operations animations in here
// e.g animate B's opacity 1 to 0 and wait finish
scrollController.jumpTo(0);
// And animate A's opacity 0 to 1
}
@override
Widget build(BuildContext context) {
var size = MediaQuery.of(context).size;
return Scaffold(
body: SingleChildScrollView(
controller: scrollController,
scrollDirection: Axis.horizontal,
physics: const NeverScrollableScrollPhysics(),
child: Row(
children: [
// A
Builder(
builder: (c) {
print('GREEN BUILD');
return InkWell(
onTap: (){
print('TO B');
_toB();
},
child: Container(
width: size.width,
height: size.height,
color: Colors.green,
),
);
},
),
Builder(
builder: (c) {
print('RED BUILD');
return InkWell(
onTap: (){
print('TO A');
_toA();
},
child: Container(
width: size.width,
height: size.height,
color: Colors.red,
),
);
},
)
],
),
),
);
}
}
Upvotes: -1
Reputation: 4509
Maybe IndexedStack is what you are looking for. It change between widget like TV channel . The widget won't be rebuilt when changing.
As your demand, switch page with animation, AnimatedSwitcher
seems to be most closely to what your want except it does rebuild Widget. So I think IndexedStack
is a good start for what you want.
You can also refer to animated_indexed_stack.dart or AnimatedSwitcher with IndexedStack mentioned in this thread
Upvotes: 0
Reputation: 1135
You can use PageView
for simple way and set config like this:
PageController _pagerController = PageController(keepPage: true);
PageView(
physics: NeverScrollableScrollPhysics(),
controller: _pagerController,
children: [
Page_A(),
Page_B(),
],
),
And for switching between pages:
goNextPage() {
_pagerController.animateToPage(
currentPage + 1,
duration: Duration(milliseconds: 500),
curve: Curves.ease,
);
}
goPrevPage() {
_pagerController.animateToPage(
currentPage - 1,
duration: Duration(milliseconds: 500),
curve: Curves.ease,
);
}
I hope it's useful for you.
Upvotes: 3