cs guy
cs guy

Reputation: 939

Flutter Navigator - Swap Pages From The Page Stack

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:

Is there a way to do this in Flutter?

Upvotes: 8

Views: 1551

Answers (3)

Mehmet Yaz
Mehmet Yaz

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

enter image description here

    
///
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

yellowgray
yellowgray

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

Saeed Fekri
Saeed Fekri

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

Related Questions